<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>code on irq5 test</title><link>https://irq5-7854a1fdb9f4.pages.dev/tag/code/</link><description>Recent content in code on irq5 test</description><language>en-us</language><lastBuildDate>Fri, 22 May 2020 00:00:00 +0000</lastBuildDate><atom:link href="https://irq5-7854a1fdb9f4.pages.dev/tag/code/feed/" rel="self" type="application/rss+xml"/><item><title>Batch Binary Analysis with IDA Pro 7.4 Automation</title><link>https://irq5-7854a1fdb9f4.pages.dev/2020/05/batch-binary-analysis-with-ida-pro-7.4-automation/</link><pubDate>Fri, 22 May 2020 00:00:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2020/05/batch-binary-analysis-with-ida-pro-7.4-automation/</guid><description>&lt;p>It is easy to script analysis steps with IDAPython, but now we want to automate
this analysis over, let&amp;rsquo;s say, 10,000 files.
I did a quick Google and I couldn&amp;rsquo;t find a guide on how to perform batch
binary analysis tasks by automating IDA Pro 7.x.&lt;/p>&lt;p>Unfamiliar with this, I was constantly guessing whether it was the command-line arguments,
the script, or a combination of both that was not working.
I&amp;rsquo;m sharing my experince here so you won&amp;rsquo;t have to be fumbling around like I was.&lt;/p>&lt;p>I will be using IDA Pro for Windows here, but it should be applicable to any of
their supported platforms like Mac or Linux.&lt;/p>&lt;h1 id=simple-binary-analysis>Simple Binary Analysis&lt;/h1>&lt;p>Let&amp;rsquo;s write some simple IDAPython analysis script and run it within the IDA Pro console.
This script loops through all functions in the executable and prints out its
address and name:&lt;/p>&lt;div class=highlight role=region aria-label="code block" translate=no>&lt;pre tabindex=0 class=chroma>&lt;code class=language-python data-lang=python>&lt;span class=line>&lt;span class=cl>&lt;span class=kn>import&lt;/span> &lt;span class=nn>idc&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>&lt;span class=kn>import&lt;/span> &lt;span class=nn>idautils&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>&lt;span class=nb>print&lt;/span> &lt;span class=s1>&amp;#39;count &lt;/span>&lt;span class=si>%d&lt;/span>&lt;span class=s1>&amp;#39;&lt;/span> &lt;span class=o>%&lt;/span> &lt;span class=nb>len&lt;/span>&lt;span class=p>(&lt;/span>&lt;span class=nb>list&lt;/span>&lt;span class=p>(&lt;/span>&lt;span class=n>idautils&lt;/span>&lt;span class=o>.&lt;/span>&lt;span class=n>Functions&lt;/span>&lt;span class=p>()))&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>&lt;span class=k>for&lt;/span> &lt;span class=n>ea&lt;/span> &lt;span class=ow>in&lt;/span> &lt;span class=n>idautils&lt;/span>&lt;span class=o>.&lt;/span>&lt;span class=n>Functions&lt;/span>&lt;span class=p>():&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl> &lt;span class=nb>print&lt;/span> &lt;span class=nb>hex&lt;/span>&lt;span class=p>(&lt;/span>&lt;span class=n>ea&lt;/span>&lt;span class=p>),&lt;/span> &lt;span class=n>idc&lt;/span>&lt;span class=o>.&lt;/span>&lt;span class=n>get_func_name&lt;/span>&lt;span class=p>(&lt;/span>&lt;span class=n>ea&lt;/span>&lt;span class=p>)&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The &lt;code>idautils&lt;/code> module contains higher-level functionality like getting a list of
functions, or finding code &amp; data references to addresses.
If you are familiar with IDC scripting, most of the functions by the same name
can be found within the &lt;code>idc&lt;/code> module.
This is not really meant to be an IDAPython or IDC scripting tutorial,
so you will need to look elsewhere for that.&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2020/05/batch-binary-analysis-with-ida-pro-7.4-automation/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Data Encryption on Firefox Send</title><link>https://irq5-7854a1fdb9f4.pages.dev/2019/05/data-encryption-on-firefox-send/</link><pubDate>Tue, 14 May 2019 11:59:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2019/05/data-encryption-on-firefox-send/</guid><description>&lt;p>If you haven&amp;rsquo;t heard, &lt;a href=https://send.firefox.com/ rel=noopener target=_blank class=external>Firefox Send&lt;/a> is a service
that solves the problem of sending large attachments without going through email.
It does this in a privacy-preserving manner by encrypting the file in your browser first, before upload.&lt;/p>&lt;p>The concept is simple:&lt;/p>&lt;ol>&lt;li>An encryption key is generated in your browser&lt;/li>&lt;li>Your file is encrypted with that key before being uploaded to the server.&lt;/li>&lt;li>The download URL is returned by the server,
but will only work after the browser appends the secret key to the URL &lt;em>fragment&lt;/em>.&lt;/li>&lt;/ol>&lt;p>Note that URL fragments are never sent to the server.
They are often used for page anchors, and sometimes to keep track of local state in SPA.&lt;/p>&lt;p>This has been made possible through the use of &lt;a href=https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API rel=noopener target=_blank class=external>Web Crypto API&lt;/a> exposed via JavaScript.&lt;/p>&lt;h1 id=technical-details>Technical Details&lt;/h1>&lt;p>The code that powers &lt;a href=https://github.com/mozilla/send rel=noopener target=_blank class=external>Firefox Send is actually open source&lt;/a>,
so you can run your own server, or read the code to figure out exactly how it works.
The encryption details are documented in &lt;a href=https://github.com/mozilla/send/blob/master/docs/encryption.md rel=noopener target=_blank class=external>docs/encryption.md&lt;/a>.&lt;/p>&lt;p>A master key is first generated and from it, a few keys are derived using HKDF SHA-256.
The derived key length depends on its purpose, so for AES-128 encryption, the key will be 128-bit. Oddly though, the Subtle Crypto API returns a a 512-bit key for HMAC SHA-256, which had me stumped for a while.
I wrote some code that you can &lt;a href=https://gist.githack.com/geekman/f9735602f744ebe5fa812f8ba17518c4/raw/webcrypto-hdkf.html rel=noopener target=_blank class=external>try out online&lt;/a>.&lt;/p>&lt;p>Because HKDF is based on a hash algorithm, derived keys are inherently not reversible to obtain the master key from which they were derived (unless the algorithm itself is somehow broken).&lt;/p>&lt;p>3 keys are derived from the master key:&lt;/p>&lt;ol>&lt;li>&lt;strong>Data Encryption key&lt;/strong>. Used to encrypt the actual file contents.&lt;/li>&lt;li>&lt;strong>Authentication key.&lt;/strong> Given to the service and used to authenticate future downloaders.&lt;/li>&lt;li>&lt;strong>Metadata key.&lt;/strong> Used to encrypt the upload manifest (filename and size information) for display.&lt;/li>&lt;/ol>&lt;p>&lt;picture>&lt;source srcset=/posts/2019/img/ffsend-keys.png.webp type=image/webp>&lt;img src=https://irq5-7854a1fdb9f4.pages.dev/posts/2019/img/ffsend-keys.png alt="keys derived in Firefox Send" width=1574 height=491>&lt;/picture>&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2019/05/data-encryption-on-firefox-send/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Crypto-Erasing BitLocker Drives</title><link>https://irq5-7854a1fdb9f4.pages.dev/2018/05/crypto-erasing-bitlocker-drives/</link><pubDate>Thu, 10 May 2018 12:45:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2018/05/crypto-erasing-bitlocker-drives/</guid><description>&lt;p>These days with larger and larger drive capacities, erasing stored data takes longer and longer.
Another problem is also the inability to do so when the time comes, due to bad sectors or hardware failures.
Just because the data is not accessible by you does not mean that
it is also inaccessible to someone else with the know-how.&lt;/p>&lt;p>&lt;strong>&lt;em>Cryptographic erasure&lt;/em> to the rescue!&lt;/strong>&lt;/p>&lt;p>Crypto erase simply erases the encryption key that is used to encrypt the data on your drive.
This is the &lt;a href=https://irq5-7854a1fdb9f4.pages.dev/2014/04/encrypt-all-the-drives/ rel=noopener>primary reason why&lt;/a> I encrypt my drives.&lt;/p>&lt;p>Oddly, I have not found anyone talking about BitLocker crypto erasure or doing it.
The closest I have seen is &lt;a href=https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/manage-bde-forcerecovery rel=noopener target=_blank class=external>&lt;code>manage-bde -forcerecovery&lt;/code>&lt;/a>, which removes all TPM-related key protectors.
This is briefly described in a TechNet article titled &lt;a href=https://technet.microsoft.com/en-us/library/cc512654.aspx rel=noopener target=_blank class=external>BitLocker™ Drive Encryption and Disk Sanitation&lt;/a>.&lt;/p>&lt;p>But what if we are not running Windows?
What if the disk is not a Windows boot drive that is protected by a TPM key protector?&lt;/p>&lt;p>In order to erase the (key) data, we first need to know how the data is stored on disk.
For open-source FDE implementations,
this is easy because the disk format is well-documented,
but BitLocker is not exactly open.&lt;/p>&lt;h1 id=bitlocker-disk-format>BitLocker Disk Format&lt;/h1>&lt;p>BitLocker was first introduced in Windows Vista and has gone through changes since then.
Some changes were made to the format in Windows 7, but has largely remained unchanged through Windows 8 till 10.&lt;/p>&lt;p>For LUKS, it is simple - there is a LUKS header at the start of the disk, followed by the encrypted volume data.
For BitLocker, it is slightly more involved, probably due to backward-compatible design considerations.&lt;/p>&lt;p>The header at the start of the partition is a valid boot sector (or boot block), so not all BitLocker information can be stored within.
Instead, this volume header points to the FVE metadata block where most of the data is kept.
In fact, there are 3 of these for redundancy.
This metadata block is what holds all the key material.&lt;/p>&lt;p>The metadata blocks are spaced (almost) evenly apart,
located near the start of the volume.&lt;/p>&lt;div class=highlight role=region aria-label="code block" translate=no>&lt;pre tabindex=0 class=chroma>&lt;code class=language-fallback data-lang=fallback>&lt;span class=line>&lt;span class=cl># blwipe -offset 0x2010000 bitlocker-2gb.vhd
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>metadata offset 0: 0x02100000
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>metadata offset 1: 0x100c8000
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>metadata offset 2: 0x1e08f000
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>metadata block 0 (size 65536): parsed OK
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>metadata block 1 (size 65536): parsed OK
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>metadata block 2 (size 65536): parsed OK&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The first metadata block &lt;em>usually&lt;/em> begins at &lt;code>0x02100000&lt;/code>.
This illustration depicts the locations for a 2 GB volume:&lt;/p>&lt;p>&lt;picture>&lt;img src=https://irq5-7854a1fdb9f4.pages.dev/posts/2018/img/fve-md-disk-layout.png alt="Diagram of disk layout with FVE metadata blocks marked out" width=1145 height=279>&lt;/picture>&lt;/p>&lt;p>If there are 3 of these blocks, how do we know know which ones contain valid data?&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2018/05/crypto-erasing-bitlocker-drives/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Framework for Writing Flexible Bruteforcers</title><link>https://irq5-7854a1fdb9f4.pages.dev/2017/08/framework-for-writing-flexible-bruteforcers/</link><pubDate>Wed, 30 Aug 2017 01:01:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2017/08/framework-for-writing-flexible-bruteforcers/</guid><description>&lt;p>When writing a bruteforcer, it&amp;rsquo;s easiest to think of it as mapping some kind of
output to a monotonically-increasing number.&lt;/p>&lt;p>Like for one of the solved PlaidCTF question, the answer string was composed from the eight letters &amp;ldquo;plaidctf&amp;rdquo;,
which conveniently is a power of 2, meaning each output character can be represented with 3 bits.
To write a bruteforcer for a string composed of these characters,
you might imagine generating a 3-bit number (i.e. from 0 to 7)
then mapping it to the character set for one output character,
or a 30-bit number if the output string was 10 characters.
Unsurprisingly, this was &lt;a href=https://gist.github.com/geekman/6b749c6dcb6acd6ba1d2/d69f852e30374376ce8a9cd4a65e49c72d4ef991 rel=noopener target=_blank class=external>exactly what I did&lt;/a> for my solver script.
The output string was generated from a &lt;em>BitVector&lt;/em> of &lt;code>171 * 3&lt;/code> bits.&lt;/p>&lt;p>But what if the output was composed of several different pieces that cannot be
represented uniformly as a set of bits?&lt;/p>&lt;p>One solution might be to emulate such a behaviour using an array of integers, like
how I &lt;a href=https://irq5-7854a1fdb9f4.pages.dev/2016/08/labyrenth-2016-write-up-regex/ rel=noopener>modified my solver script in version 2&lt;/a>
to handle a character set of arbitrary length.&lt;/p>&lt;p>In this post, I will walk-through writing a basic, but flexible, bruteforcer
with accompanying code snippets in &lt;a href=https://golang.org/ rel=noopener target=_blank class=external>Go&lt;/a>.&lt;/p>&lt;h1 id=keeping-state>Keeping State&lt;/h1>&lt;p>Continuing on the CTF puzzle, the &lt;em>BitVector&lt;/em> was replaced with an array of &lt;code>Int&lt;/code>s.
Each &lt;code>Int&lt;/code> will represent one character of the output string.
We can thus represent the state like so (for simplicity,
let&amp;rsquo;s limit the output string to 2 characters):&lt;/p>&lt;div class=highlight role=region aria-label="code block" translate=no>&lt;pre tabindex=0 class=chroma>&lt;code class=language-go data-lang=go>&lt;span class=line>&lt;span class=cl>&lt;span class=kd>type&lt;/span> &lt;span class=nx>state&lt;/span> &lt;span class=kd>struct&lt;/span> &lt;span class=p>{&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl> &lt;span class=nx>digit&lt;/span> &lt;span class=p>[&lt;/span>&lt;span class=mi>2&lt;/span>&lt;span class=p>]&lt;/span>&lt;span class=kt>int&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>&lt;span class=p>}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In order to increment each digit, we can write a function that increments
&lt;code>state.digit&lt;/code> until a certain number, then resets it to zero.&lt;/p>&lt;p>To make it generic, we will write a function that returns another function that
manipulates a digit position, so we don&amp;rsquo;t have to copy &amp; paste the code for
each digit position:&lt;/p>&lt;div class=highlight role=region aria-label="code block" translate=no>&lt;pre tabindex=0 class=chroma>&lt;code class=language-go data-lang=go>&lt;span class=line>&lt;span class=cl>&lt;span class=c1 translate>// returns a function that manipulates the digit at given pos
&lt;/span>&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>&lt;span class=c1 translate>&lt;/span>&lt;span class=kd>func&lt;/span> &lt;span class=nf>digitManipulator&lt;/span>&lt;span class=p>(&lt;/span>&lt;span class=nx>pos&lt;/span> &lt;span class=kt>int&lt;/span>&lt;span class=p>)&lt;/span> &lt;span class=kd>func&lt;/span>&lt;span class=p>(&lt;/span>&lt;span class=o>*&lt;/span>&lt;span class=nx>state&lt;/span>&lt;span class=p>)&lt;/span> &lt;span class=kt>bool&lt;/span> &lt;span class=p>{&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl> &lt;span class=k>return&lt;/span> &lt;span class=kd>func&lt;/span>&lt;span class=p>(&lt;/span>&lt;span class=nx>s&lt;/span> &lt;span class=o>*&lt;/span>&lt;span class=nx>state&lt;/span>&lt;span class=p>)&lt;/span> &lt;span class=kt>bool&lt;/span> &lt;span class=p>{&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl> &lt;span class=nx>s&lt;/span>&lt;span class=p>.&lt;/span>&lt;span class=nx>digit&lt;/span>&lt;span class=p>[&lt;/span>&lt;span class=nx>pos&lt;/span>&lt;span class=p>]&lt;/span>&lt;span class=o>++&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl> &lt;span class=k>if&lt;/span> &lt;span class=nx>s&lt;/span>&lt;span class=p>.&lt;/span>&lt;span class=nx>digit&lt;/span>&lt;span class=p>[&lt;/span>&lt;span class=nx>pos&lt;/span>&lt;span class=p>]&lt;/span> &lt;span class=o>==&lt;/span> &lt;span class=nx>MAX_NUMBER&lt;/span> &lt;span class=p>{&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl> &lt;span class=nx>s&lt;/span>&lt;span class=p>.&lt;/span>&lt;span class=nx>digit&lt;/span>&lt;span class=p>[&lt;/span>&lt;span class=nx>pos&lt;/span>&lt;span class=p>]&lt;/span> &lt;span class=p>=&lt;/span> &lt;span class=mi>0&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl> &lt;span class=k>return&lt;/span> &lt;span class=kc>true&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl> &lt;span class=p>}&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl> &lt;span class=k>return&lt;/span> &lt;span class=kc>false&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl> &lt;span class=p>}&lt;/span>
&lt;/span>&lt;/span>&lt;span class=line>&lt;span class=cl>&lt;span class=p>}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We will talk more about the boolean return value later.&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2017/08/framework-for-writing-flexible-bruteforcers/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Patching ZIP Files</title><link>https://irq5-7854a1fdb9f4.pages.dev/2015/07/patching-zip-files/</link><pubDate>Fri, 03 Jul 2015 15:31:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2015/07/patching-zip-files/</guid><description>&lt;p>I have recently been working with VM images and to
transport &amp; distribute them conveniently I had to zip them up.
I mainly work in a Windows environment and I use &lt;a href=http://www.7-zip.org/ rel=noopener target=_blank class=external>7-Zip&lt;/a> for packing and unpacking archives.
It&amp;rsquo;s actually quite nice (and free), if you don&amp;rsquo;t mind the spartan interface.
On my workstation, I have NTFS file encryption (EFS)
enabled on my home directory.
The way this works is that you can selectively encrypt files and folders
by setting a special attribute on these items.&lt;/p>&lt;p>&lt;picture>&lt;img src=https://irq5-7854a1fdb9f4.pages.dev/posts/2015/img/screen-ntfs-encrypt.png alt="NTFS encryption attribute" width=394 height=300 class=noinvert>&lt;/picture>&lt;/p>&lt;p>I was in a hurry to prepare a VM image for a class and I used 7-Zip to archive the entire VM folder.
The problem was, this encryption attribute was also recorded in the ZIP file and I only realized it
when I unpacked it on a machine for testing right before the class started.
On a machine that does not use NTFS, it warns the user and asks if it should continue extracting unencrypted.
On a machine &lt;em>with&lt;/em> NTFS, the destination files get encrypted and Windows starts nagging the user to back up
the EFS keys.
Compressing a 9 GB image into a 3 GB ZIP file took about 40 minutes, so there was really no time left to
decrypt the files (EFS really sucks in this regard) and re-compress it into a ZIP file without encryption.&lt;/p>&lt;p>You can check whether a file is marked for encryption by checking the Attributes column in 7-Zip.
(Note that this encryption attribute is native to NTFS and is different from ZIP file encryption.)
The attribute string is somewhat cryptic but &lt;code>E&lt;/code> means encrypted and &lt;code>A&lt;/code> is archive.
Interestingly, 7-Zip itself does not restore the encrypted attribute, but the native Windows unzipping functionality does.&lt;/p>&lt;p>&lt;picture>&lt;source srcset=/posts/2015/img/screen-zip-attr.png.webp type=image/webp>&lt;img src=https://irq5-7854a1fdb9f4.pages.dev/posts/2015/img/screen-zip-attr.png alt="ZIP attributes" width=435 height=300 class=noinvert>&lt;/picture>&lt;/p>&lt;h2 id=patch-all-the-things>Patch All The Things!&lt;/h2>&lt;p>While I did not manage to solve this annoyance in time for the class,
I had this idea to write a tool that would just patch the ZIP file.
No changes need to be made to the file data and so there is actually no need to re-compress it.&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2015/07/patching-zip-files/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Visualizing Binary Features with matplotlib</title><link>https://irq5-7854a1fdb9f4.pages.dev/2014/12/visualizing-binary-features-with-matplotlib/</link><pubDate>Fri, 26 Dec 2014 01:18:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2014/12/visualizing-binary-features-with-matplotlib/</guid><description>&lt;p>Some time ago, I started playing around with data analysis and machine learning.
One of the more popular tools for such tasks is &lt;em>IPython Notebook&lt;/em>,
a browser-based interactive REPL shell based on &lt;a href=http://ipython.org/ rel=noopener target=_blank class=external>IPython&lt;/a>.
Each session becomes a &amp;ldquo;notebook&amp;rdquo; that records the entire REPL session with both inputs and (cached) outputs, which can be saved and reviewed at a later time, or exported into another format like HTML.
This capability, combined with &lt;a href=http://matplotlib.org/ rel=noopener target=_blank class=external>matplotlib&lt;/a> for plotting and &lt;a href=http://pandas.pydata.org/ rel=noopener target=_blank class=external>pandas&lt;/a> for slicing and dicing data makes this a handy tool for analyzing and visualizing data.
To give you an idea of how useful this tool can be, take a look at some example notebooks using &lt;a href=http://nbviewer.ipython.org/ rel=noopener target=_blank class=external>the online notebook viewer&lt;/a>.&lt;/p>&lt;p>In this quick post, I&amp;rsquo;ll describe how I visualize binary features (present/not present) and clustering of such data.
I am assuming that you already have experience with all of the above-mentioned libraries.
For this example, I&amp;rsquo;ve extracted permissions (&lt;code>uses-permission&lt;/code>) and features (&lt;code>uses-feature&lt;/code>) used by a set of Android apps using &lt;a href=https://code.google.com/p/androguard/ rel=noopener target=_blank class=external>Androguard&lt;/a>. The resulting visualization looks like this:&lt;/p>&lt;p>&lt;picture>&lt;source srcset=/posts/2014/img/apps-binary-features-viz.png.webp type=image/webp>&lt;img src=https://irq5-7854a1fdb9f4.pages.dev/posts/2014/img/apps-binary-features-viz.png alt="visualization of binary features" width=630 height=386>&lt;/picture>&lt;/p>&lt;p>Each row represents one app and each column represents one feature.
More specifically, each column represent whether a permission or feature is used by the app.
Such a visualization makes it easy to see patterns, such as which permission or feature is more frequently used by apps (shown as downward streaks), or whether an app uses more or less features compared to other apps (which shows up as horizontal streaks).&lt;/p>&lt;p>While this may look relatively trivial, when the number of samples increase to thousands of apps, it becomes difficult to make sense of all the rows &amp; columns in the data table by staring at it.&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2014/12/visualizing-binary-features-with-matplotlib/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Bruteforcing LUKS Volumes Explained</title><link>https://irq5-7854a1fdb9f4.pages.dev/2014/11/bruteforcing-luks-volumes-explained/</link><pubDate>Wed, 19 Nov 2014 02:01:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2014/11/bruteforcing-luks-volumes-explained/</guid><description>&lt;p>Some weeks back, we were forced to reboot one of our server machines because it stopped responding.
When the machine came back up, we were greeted with a password prompt to decrypt the partition.
No problem, since we always used a password combination (ok, permutation) that consisted of a few words, something along the lines of &amp;ldquo;john&amp;rdquo;, &amp;ldquo;doe&amp;rdquo;, &amp;ldquo;1954&amp;rdquo;, and the server&amp;rsquo;s serial number. Except that it didn&amp;rsquo;t work, and we forgot the permutation rules AND whether we used &amp;ldquo;john&amp;rdquo; &amp;ldquo;doe&amp;rdquo; or &amp;ldquo;jack&amp;rdquo; &amp;ldquo;daniels&amp;rdquo;.&lt;/p>&lt;p>All the search results for bruteforcing LUKS are largely the same &amp;ndash; &amp;ldquo;use &lt;code>cryptsetup luksOpen --test-passphrase&lt;/code>&amp;rdquo;.
In my case, the physical server is in the server room, and I don&amp;rsquo;t want to stand in front of the rack trying to figure all this out. My question is, can I do this offline on another machine? None of those blog entries were helpful in this regard.&lt;/p>&lt;h2 id=the-luks-header>The LUKS Header&lt;/h2>&lt;p>To answer this question, I took a look at the LUKS header. This header is what provides multiple &amp;ldquo;key slots&amp;rdquo;, allowing you to specify up to 8 passwords or key files that can decrypt the volume.
&lt;a href=https://gitlab.com/cryptsetup/cryptsetup rel=noopener target=_blank class=external>cryptsetup&lt;/a> is the standard userspace tool (and library) to manipulate and mount LUKS volumes.
Since LUKS was designed based on TKS1, the &lt;a href=https://gitlab.com/cryptsetup/cryptsetup/-/wikis/TKS1 rel=noopener target=_blank class=external>TKS1 document&lt;/a> referenced by the cryptsetup project was very helpful.
After consulting the documentation &amp; code, I came up with the following diagram that describes the LUKS key verification process:&lt;/p>&lt;p>&lt;picture>&lt;source srcset=/posts/2014/img/luks-encryption-flowchart.png.webp type=image/webp>&lt;img src=https://irq5-7854a1fdb9f4.pages.dev/posts/2014/img/luks-encryption-flowchart.png alt="LUKS encryption flowchart" width=1200 height=396>&lt;/picture>&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2014/11/bruteforcing-luks-volumes-explained/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Creating Minimal Throw-away CentOS 6 VMs</title><link>https://irq5-7854a1fdb9f4.pages.dev/2014/08/creating-minimal-throw-away-centos-6-vms/</link><pubDate>Sun, 24 Aug 2014 02:23:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2014/08/creating-minimal-throw-away-centos-6-vms/</guid><description>&lt;p>Whether you are using CentOS for a build server or simply testing out a new configuration, you can quickly create a VM (virtual machine) that is under 1GB. You can do this without downloading any special tools or ISO files &amp;ndash; just the CentOS installation DVD and VirtualBox (or VMware if you prefer).&lt;/p>&lt;p>I like the text-based console, so you won&amp;rsquo;t be getting a GUI or fancy Linux desktop with this one. Given its small size, you could also archive the entire environment (or even several of them) for future use without having to waste gigabytes of free space. These environments also serve as a base which can be upgraded or added onto to provide more functionality later.&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2014/08/creating-minimal-throw-away-centos-6-vms/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Encrypt All the Drives</title><link>https://irq5-7854a1fdb9f4.pages.dev/2014/04/encrypt-all-the-drives/</link><pubDate>Tue, 08 Apr 2014 01:50:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2014/04/encrypt-all-the-drives/</guid><description>&lt;p>I have always been an advocate on storage security (all types of security, actually). I like how iOS devices keep all files encrypted, even if you do not set a passcode on the device. They do this to facilitate quick erasure of files on the device &amp;ndash; to erase all the data, they simply wipe the master key.&lt;/p>&lt;p>Erasing magnetic storage media isn&amp;rsquo;t difficult, but it is time-consuming. For solid state media such as SSDs and flash drives, the wear-leveling makes it difficult to ensure that all flash blocks have been securely overwritten. The answer to this is to encrypt everything.&lt;/p>&lt;p>&lt;picture>&lt;img src=https://irq5-7854a1fdb9f4.pages.dev/posts/2014/img/encrypt-all-the-drives.png alt="Encrypt all the drives!! (meme)" width=439 height=327 class=noinvert>&lt;/picture>&lt;/p>&lt;p>Recently I have been busy building a Linux-based NAS and I decided to put this to practice.&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2014/04/encrypt-all-the-drives/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Implementing EAP-SIM at Home</title><link>https://irq5-7854a1fdb9f4.pages.dev/2013/12/implementing-eap-sim-at-home/</link><pubDate>Mon, 23 Dec 2013 00:57:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2013/12/implementing-eap-sim-at-home/</guid><description>&lt;p>EAP-SIM is one of the authentication methods that can be used in an 802.1x or WPA Enterprise network. Specifically, it relies on the user’s SIM card to process a presented challenge. This has been used by some telcos to provide WiFi service without having to maintain a separate set of credentials. However, not all phones support EAP-SIM.&lt;/p>&lt;p>&lt;picture>&lt;source srcset=/posts/2013/img/eap-sim-7433.jpg.webp type=image/webp>&lt;img src=https://irq5-7854a1fdb9f4.pages.dev/posts/2013/img/eap-sim-7433.jpg alt="Phone displaying EAP-SIM as a WiFi authentication method" width=640 height=359>&lt;/picture>&lt;/p>&lt;p>Since I’m already using a RADIUS setup at home, the use of EAP-SIM will eliminate the need to install my CA certs onto each device. But of course, there is still a fair bit of work to do…&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2013/12/implementing-eap-sim-at-home/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Quick &amp; Dirty PHP Devel Setup on Windows</title><link>https://irq5-7854a1fdb9f4.pages.dev/2013/06/quick-dirty-php-devel-setup-on-windows/</link><pubDate>Tue, 18 Jun 2013 00:23:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2013/06/quick-dirty-php-devel-setup-on-windows/</guid><description>Here&amp;rsquo;s a quick tip if you&amp;rsquo;re developing a really simple PHP site and need a development setup on Windows with minimal fuss. Don&amp;rsquo;t bother with a full LAMP stack like XAMPP, which requires you to run a batch file that will rewrite its Apache and PHP configuration files.
PHP version 5.4.0 and above comes with a handy built-in webserver. Simply download the binaries for Windows and unzip it into a directory of your choice.&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2013/06/quick-dirty-php-devel-setup-on-windows/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Decoding BCARD Conference Badges</title><link>https://irq5-7854a1fdb9f4.pages.dev/2013/04/decoding-bcard-conference-badges/</link><pubDate>Sat, 13 Apr 2013 01:28:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2013/04/decoding-bcard-conference-badges/</guid><description>&lt;p>Last month, I had the opportunity to fly halfway around the world to attend &lt;em>RSA Conference 2013&lt;/em>. Everyone was given a lanyard and badge which contains your information entered during registration. When you visit booths, they can then scan your badge to collect your information and follow up by sending you spam.&lt;/p>&lt;p>&lt;picture>&lt;source srcset=/posts/2013/img/rsa-conf-pass.jpg.webp type=image/webp>&lt;img src=https://irq5-7854a1fdb9f4.pages.dev/posts/2013/img/rsa-conf-pass.jpg alt="RSA conference pass" width=640 height=427>&lt;/picture>&lt;/p>&lt;p>The scanner varies across different booths, but mostly it&amp;rsquo;s an Android device that ran a custom software. Since it had a large NXP logo, let&amp;rsquo;s try to read it with the &lt;a href="https://play.google.com/store/apps/details?id=com.nxp.taginfolite" rel=noopener target=_blank class=external>NFC TagInfo app&lt;/a>. Looks like the tag identifies itself as a NDEF message but the data is gibberish.&lt;/p>&lt;p>&lt;picture>&lt;img src=https://irq5-7854a1fdb9f4.pages.dev/posts/2013/img/bcard_taginfo.png alt="Data in the BCARD as decoded by TagInfo" width=720 height=1034 class="half noinvert">&lt;/picture>&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2013/04/decoding-bcard-conference-badges/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Debugging Fun with JNI</title><link>https://irq5-7854a1fdb9f4.pages.dev/2012/02/debugging-fun-with-jni/</link><pubDate>Wed, 29 Feb 2012 21:25:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2012/02/debugging-fun-with-jni/</guid><description>Our proprietary system, written in a mix of Java and C++, was crashing quite often. It only started happening after some new features were added, so naturally that became the prime suspect, but my colleague claimed it was because the process ran out of memory.
I wrote a small test case to see if an out-of-memory situation would cause this, and true enough, it did. The JVM generated a crash log file that looked like this (I&amp;rsquo;ve omitted the unimportant parts):&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2012/02/debugging-fun-with-jni/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Python bindings for iTunesMobileDevice.dll</title><link>https://irq5-7854a1fdb9f4.pages.dev/2011/09/python-bindings-for-itunesmobiledevice.dll/</link><pubDate>Mon, 12 Sep 2011 01:24:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2011/09/python-bindings-for-itunesmobiledevice.dll/</guid><description>Oddly enough I can&amp;rsquo;t seem to find a Python wrapper for iTunesMobileDevice.dll. I did manage to find a C# equivalent called Manzana though, which is quite widely used.
Anyhow, I bit the bullet and read through the ctypes documentation and wrote AMDevice.py which exposes some simple classes to handle connecting to an iPhone. I only implemented the minimal set of functions required to download and upload files to the iPhone, as I wrote this primarily for my iPhone SMS import script.&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2011/09/python-bindings-for-itunesmobiledevice.dll/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Importing SMSes into the iPhone</title><link>https://irq5-7854a1fdb9f4.pages.dev/2011/06/importing-smses-into-the-iphone/</link><pubDate>Sat, 18 Jun 2011 17:15:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2011/06/importing-smses-into-the-iphone/</guid><description>Since my iPhone 3GS died, I have been using my dad&amp;rsquo;s Samsung Jet as a temporary replacement phone. I really can&amp;rsquo;t stand the resistive touch screen - tapping backspace will at times hit the T9 button when I&amp;rsquo;m composing an SMS. Also, I miss the display of SMSes as a conversation with both sent and received messages in a single place.
I obsess over keeping chat history, so naturally I want to find a way to preserve these messages on the phone.&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2011/06/importing-smses-into-the-iphone/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Publishing Services over mDNS in C</title><link>https://irq5-7854a1fdb9f4.pages.dev/2011/04/publishing-services-over-mdns-in-c/</link><pubDate>Sun, 10 Apr 2011 23:26:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2011/04/publishing-services-over-mdns-in-c/</guid><description>For some time now I&amp;rsquo;ve been looking into mDNS-advertised services. My aim was to advertise a service using mDNS in a C program.
Typically, doing this is really easy: call the Bonjour or Avahi APIs, and the system-wide daemon will do the rest for you. The problem arises when there is no system-wide daemon such as mDNSResponder (if you&amp;rsquo;re on a Mac or Windows) or Avahi (for the other OSes). This usually happens when you&amp;rsquo;re on an embedded system, like a router that runs Linux.&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2011/04/publishing-services-over-mdns-in-c/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>MIDI to USB (Serial) Converter</title><link>https://irq5-7854a1fdb9f4.pages.dev/2011/03/midi-to-usb-serial-converter/</link><pubDate>Sat, 12 Mar 2011 19:37:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2011/03/midi-to-usb-serial-converter/</guid><description>&lt;p>MIDI is actually just serial data at 31,250bps in &lt;a href=http://en.wikipedia.org/wiki/8-N-1 rel=noopener target=_blank class=external>8N1&lt;/a> format that is transmitted over a 5-pin DIN cable. This means you can receive MIDI data from your musical instrument using a serial port, or an &lt;a href=http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm rel=noopener target=_blank class=external>FTDI cable&lt;/a>.&lt;/p>&lt;p>Receiving MIDI data over the FTDI cable doesn&amp;rsquo;t magically turn your USB serial device into a MIDI device - you need to be running a software bridge or a driver that pretends to be a virtual MIDI device emitting these messages. For this purpose, I shall use the &lt;a href=http://www.spikenzielabs.com/SpikenzieLabs/Serial_MIDI.html rel=noopener target=_blank class=external>Serial MIDI Converter&lt;/a> from SpikenzieLabs.&lt;/p>&lt;p>I&amp;rsquo;m using Mac OS X 10.6.6 and the latest Java update, so I didn&amp;rsquo;t need any extra JAR files.&lt;/p>&lt;h1 id=wiring-it-up>Wiring It Up&lt;/h1>&lt;p>The circuit is relatively simple - you need the DIN socket, an opto-isolator, 2 resistors, and optionally a diode. In my case, parts came from a scrap bin, so I used a 330 ohm resistor instead of a 220 ohm for Rb and a 1K for Rd instead of 280 ohms. For the opto-isolator, element14 had some non-RoHS CNY17-2 on sale, so I just used that.&lt;/p>&lt;p>&lt;picture>&lt;img src=https://irq5-7854a1fdb9f4.pages.dev/posts/2011/img/midi_schematic.png alt="MIDI hookup schematic" width=468 height=285>&lt;/picture>&lt;/p>&lt;p>Note that the RXD output is only meant for interfacing with a TTL circuit like an FTDI chip/cable or MAX232 transceiver, not the RS232 serial port directly.&lt;/p>&lt;p>You can find the same circuit diagram (with different values &amp; parts) in the official &lt;a href=http://www.midi.org/techspecs/electrispec.php rel=noopener target=_blank class=external>MIDI Electrical Specification Diagram&lt;/a>.&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2011/03/midi-to-usb-serial-converter/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>mdns-repeater: mDNS across subnets</title><link>https://irq5-7854a1fdb9f4.pages.dev/2011/01/mdns-repeater-mdns-across-subnets/</link><pubDate>Sun, 02 Jan 2011 03:51:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2011/01/mdns-repeater-mdns-across-subnets/</guid><description>&lt;p>&lt;strong>Update 21-Sep-2011: Added an &lt;a href=#Installation rel=noopener>Installation&lt;/a> section and updated the binaries on Bitbucket.&lt;/strong>&lt;/p>&lt;p>As you may know, I have a couple of Apple devices. Apple is fond of using Multicast DNS (mDNS) for their service discovery. The recent addition to these services being AirPrint (wireless printing service) and AirPlay (wireless audio/video streaming) from your iOS devices.&lt;/p>&lt;p>My home is setup in such a way that the wired and wireless networks are on 2 separate subnets. mDNS uses a multicast address that is &amp;ldquo;administratively scoped&amp;rdquo;, meaning the packets will not travel across subnets. I tried fiddling around with iptables rules and looked around for how I can route these packets across the subnets, but to no avail.&lt;/p>&lt;p>There is another solution - a repeater daemon that sits on the router and repeats packets between the 2 subnets. &lt;a href=http://avahi.org rel=noopener target=_blank class=external>Avahi&lt;/a> is used to provide mDNS services and it has a reflector mode that does exactly this. A more lightweight solution was &lt;a href=http://www.smittyware.com/linux/tivobridge/ rel=noopener target=_blank class=external>TiVoBridge&lt;/a>, which supposedly performs the same task but it&amp;rsquo;s much smaller. I tried to compile and set up TiVoBridge, but it required a config file and I couldn&amp;rsquo;t really get it to work the way I wanted it to. There&amp;rsquo;s an even lighter-weight solution called &lt;a href=http://svn.ninux.org/svn/ninuxdeveloping/say/trunk/ rel=noopener target=_blank class=external>SAY&lt;/a>, but it uses libpcap.&lt;/p>&lt;p>Enter &lt;a href=http://bitbucket.org/geekman/mdns-repeater/ rel=noopener target=_blank class=external>mdns-repeater&lt;/a> - a small Linux daemon that does exactly what I want it to do. I have a Linksys WRT54G which runs dd-wrt. This program was intended to be compiled for and installed on the Linksys router. As with all other programs that run on the router, it requires no configuration.&lt;/p>&lt;p>The default dd-wrt configuration has 2 interfaces - &lt;code>vlan1&lt;/code> for the WAN interface and &lt;code>br0&lt;/code> for the wireless interface (and 4-port switch). The program accepts the arguments &lt;code>vlan1&lt;/code> and &lt;code>br0&lt;/code> and begins repeating packets from &lt;code>vlan1&lt;/code> to &lt;code>br0&lt;/code> and vice-versa. I can now get my iOS devices to detect wired servers like a print server for AirPrint.&lt;/p>&lt;p>&lt;em>mdns-repeater&lt;/em> is released under GPLv2. Feel free to change it to repeat whatever protocol you want. Patches to add functionality and bug fixes are welcome. You can contact me via bitbucket.org, or if you clone the repository my email is in the commits.&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2011/01/mdns-repeater-mdns-across-subnets/#more">Continue reading…&lt;/a>&lt;/p></description></item><item><title>Raw binary protocol analysis with Wireshark</title><link>https://irq5-7854a1fdb9f4.pages.dev/2010/09/raw-binary-protocol-analysis-with-wireshark/</link><pubDate>Mon, 20 Sep 2010 21:22:00 +0000</pubDate><guid>https://irq5-7854a1fdb9f4.pages.dev/2010/09/raw-binary-protocol-analysis-with-wireshark/</guid><description>&lt;p>I&amp;rsquo;m currently trying to analyze a binary protocol between 2 devices, but their communication does not occur over the network, neither can it be sniffed easily. Since this involves communication between 2 parties, I think the most apt software for analyzing such &amp;ldquo;conversations&amp;rdquo; would be &lt;strong>Wireshark&lt;/strong>.&lt;/p>&lt;p>Wireshark allows for custom protocol dissectors. Writing such a dissector is usually done in C for speed, but I didn&amp;rsquo;t really want to setup the whole compilation environment to compile Wireshark. Fortunately, the Wireshark (Windows) binaries are compiled with Lua scripting support, which can also be used to write dissectors (although they run slower than C implementations).&lt;/p>&lt;p>&lt;a href="https://irq5-7854a1fdb9f4.pages.dev/2010/09/raw-binary-protocol-analysis-with-wireshark/#more">Continue reading…&lt;/a>&lt;/p></description></item></channel></rss>