JeuWeb - Crée ton jeu par navigateur
Défi sécurité. - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Défi sécurité. (/showthread.php?tid=2359)

Pages : 1 2 3 4 5


RE: Défi sécurité. - keke - 04-02-2008

Mp envoyé ^^. Je reprends tous les points qui me paraissent étrange ou contradictoire. Mais au vu de tes réponses, rien de bien troublant si tu as blindé tes SESSION et que la faille GET/lien n'est plus un problème.

kéké.


RE: Défi sécurité. - Amrac - 04-02-2008

pascaltje a écrit :petite question de configuration :
register_globals vaut On ou Off ?

A+

Pascal
register_globals = Off


Kéké a écrit :Coucou,

Citation :$tempsRestant = $donnees['timestamp'] - time();

echo '<p class="gras">- Vous allez attaquer '.getPseudo($donnees['IDDefenseur']).' dans '.convertiTemps($tempsrestant);//Message de l'attaque.
if($donnees['timestampDepart']>(time()-2*60)) //Si le joueur peut encore annuler l'attaque, alors on ajoute le lien pour pouvoir annuler.
Hum ...
$donnees['timestamp'] est différent de $donnees['timestampDepart'] ???
Je pense que c'est juste une erreur de simplification ...
$donnees['timestampDepart'] contient le timestamp au moment de l'envoie de l'attaque.
Si je lance mon attaque a 15H15, le $donnees['timestampDepart'] correspondrat a 15H15 (traduit en timestamp biensure ^^)

Citation :Sinon, il me semblerait utile de faire sortir tes cas d'erreurs de tes fonctions SQL... un bon OR DIE ('blabla'); pourrait être utile ?
Je pensais pas avoir tant de participation au début, donc j'avais virer cette partie de peur d'alourdir le code.
Mais la voici:
Code PHP :
<?php
function mysql_cquery($requete)
{
static
$nb_requetes = 0; //Sert à compter le nombre de requete
if($requete == "fin")
{
return
$nb_requetes;

}
try {
$donnees = mysql_query($requete) ;
if(
$donnees == false ) throw new Exception('plantouille'); //J'avais envie de jouer avec les exception a l'époque, me demandais pas pourquoi ^^
}
catch(
Exception $e)
{
envoieRapport(1,0,'Bug sql',mysql_error()." requete:".$requete." <br />ID SESSION:".$_SESSION['ID']." <br />Script: ".$_SERVER['SCRIPT_NAME']."<br /> Variables: ".getVars() );
die(
'Erreur SQL. Le bug est signalé.');
}
$nb_requetes++;
return
$donnees;
}
?>


Avec getVars():

Code PHP :
<?php
function getVars()
{
$Vars ='';
if(
$_POST != null)
{
$Vars.='-POST: ';
foreach(
$_POST as $index => $value)
{
$Vars.=$index.'|';
}
}
if(
$_GET != null)
{
$Vars.='-GET: ';
foreach(
$_GET as $index => $value)
{
$Vars.=$index.'|';
}
}
return
$Vars;
}
?>
Il faut donc remplacer tout les mysql_query() du premier code par mysql_cquery() (Initialement, l'ajout du c signifiait Compteur)

Kéké a écrit :Ensuite, je crois qu'il y a une erreur de compréhension. Tu dis "Je vais donc vous présenter un petit bout de code qui permet d'annuler une attaque si celle-ci a était lancé il y a moins de deux minutes." Dans le code, je crois qu'il s'agit des attaques supérieur à 2minutes .
Citation :
if($donnee['timestampDepart']>(time()-2*60))
Disons qu'il est 15H16
Comme le timestampDepart contient l'heure du départ des troupes (15H15 par exemple), on a bien 15H15>15H14, donc le départ a eu lieu il y a moins de 2 minutes.

Kéké a écrit :La notion de "Select * From ..." me parait hasardeuse ... Je pense que tu gagnerais à noter toutes les variables dont tu as besoin.
C'est vrai, mais il s'agit d'une optimisation.

Kéké a écrit :Sinon, mis à part le fait d'utiliser des liens (qui revient à l'erreur du GET dont j'ai parlé précédement, et dont il me semble que tu as dis que ce n'est pas ça, je ne vois pas ce que peux faire les joueurs :
Un joueur qui voit le lien suivant :
<a href="Armee.php?annuler=852>

Pourra modifier son URL de la manière suivante annuler=853 pour planter le combat d'un autre joueur. Mais cette idée a déjà été donnée.

J'ai hâte d'avoir des précisions, car mis à part tout ces points, je ne vois pas ce qui peut planter, et je serais intéressé de connaitre la réponse (je peux attendre 34).

Kéké.


Indice: Il est beaucoup plus difficile (Pas loin de l'impossible) de reproduire ce bug sur une station de développement, alors qu'il est nettement plus facile de le faire sur un serveur en production. Ca ajoute un coté très pervers à la faille.


RE: Défi sécurité. - uriak - 04-02-2008

Je retente le coup Smile


RE: Défi sécurité. - Amrac - 04-02-2008

Félicitations à Uriak qui a trouvé, je donne un "gros indice" pour aider les autres, et je dévoilent la réponse d'Uriak en soirée.

Voici les logs d'un joueurs chez qui j'ai pus constater la triche:

A chaque ligne correspond le chargement d'une page. Ca suit le format suivant:
La date, puis le chiffre contenu dans $_GET['lien']
07-01-08 22:24:25 -GET: 348547|
07-01-08 22:24:34 -GET: 348549|
07-01-08 22:24:37 -GET: 348548|
15-01-08 22:22:04 -GET: 377586|
15-01-08 22:22:15 -GET: 377586|
15-01-08 22:22:27 -GET: 377587|
15-01-08 22:22:28 -GET: 377586|
15-01-08 22:23:10 -GET: 377591|
15-01-08 22:23:10 -GET: 377590|
15-01-08 22:23:50 -GET: 377590|
15-01-08 22:24:01 -GET: 377590|
15-01-08 22:24:09 -GET: 377590|
15-01-08 22:24:17 -GET: 377591|
15-01-08 22:24:33 -GET: 377591|
15-01-08 22:24:54 -GET: 377592|
15-01-08 22:25:09 -GET: 377592|
15-01-08 22:25:18 -GET: 377592|
15-01-08 22:25:27 -GET: 377592|
15-01-08 22:25:58 -GET: 377675|
15-01-08 22:26:07 -GET: 377677|
15-01-08 22:26:18 -GET: 377678|
15-01-08 22:26:20 -GET: 377677|
15-01-08 22:28:50 -GET: 377677|
15-01-08 22:29:00 -GET: 377677|
15-01-08 22:29:12 -GET: 377677|
15-01-08 22:29:22 -GET: 377678|
15-01-08 22:29:23 -GET: 377677|
20-01-08 21:37:39 -GET: 391052|
20-01-08 21:37:40 -GET: 391053|
21-01-08 12:45:11 -GET: 392044|
21-01-08 12:45:12 -GET: 392045|
21-01-08 17:24:42 -GET: 392498|
21-01-08 17:24:50 -GET: 392498|
21-01-08 17:24:59 -GET: 392498|
21-01-08 17:25:06 -GET: 392498|
21-01-08 17:25:18 -GET: 392500|
21-01-08 17:25:25 -GET: 392500|
21-01-08 17:25:34 -GET: 392500|
21-01-08 17:25:42 -GET: 392500|
21-01-08 17:25:43 -GET: 392500|
21-01-08 17:27:02 -GET: 392514|
21-01-08 17:27:09 -GET: 392515|
21-01-08 17:27:10 -GET: 392514|
21-01-08 17:27:17 -GET: 392515|
21-01-08 17:27:18 -GET: 392514|
21-01-08 17:27:31 -GET: 392515|
21-01-08 17:27:37 -GET: 392515|
21-01-08 17:27:38 -GET: 392516|
21-01-08 17:27:58 -GET: 392515|
21-01-08 17:28:05 -GET: 392515|
21-01-08 17:28:14 -GET: 392515|
21-01-08 17:28:20 -GET: 392515|
21-01-08 17:28:26 -GET: 392515|
21-01-08 17:28:31 -GET: 392515|
21-01-08 17:28:37 -GET: 392515|
21-01-08 17:28:43 -GET: 392515|
21-01-08 17:28:47 -GET: 392515|
21-01-08 17:28:54 -GET: 392515|
21-01-08 17:28:55 -GET: 392516|
21-01-08 17:29:08 -GET: 392515|
21-01-08 17:29:13 -GET: 392515|
21-01-08 17:29:19 -GET: 392515|
21-01-08 17:29:23 -GET: 392516|
21-01-08 17:29:24 -GET: 392515|
21-01-08 17:29:35 -GET: 392516|
21-01-08 17:29:36 -GET: 392515|
21-01-08 17:29:51 -GET: 392516|
21-01-08 17:29:57 -GET: 392516|
21-01-08 17:29:58 -GET: 392518|
24-01-08 23:42:56 -GET: 400544|
24-01-08 23:43:03 -GET: 400544|
24-01-08 23:43:10 -GET: 400544|
24-01-08 23:43:18 -GET: 400544|
24-01-08 23:43:25 -GET: 400544|
24-01-08 23:43:32 -GET: 400544|
24-01-08 23:43:40 -GET: 400544|
24-01-08 23:43:46 -GET: 400544|
24-01-08 23:44:05 -GET: 400545|
24-01-08 23:44:06 -GET: 400544|
24-01-08 23:44:22 -GET: 400545|
24-01-08 23:44:24 -GET: 400544|
24-01-08 23:44:43 -GET: 400544|
24-01-08 23:44:50 -GET: 400545|
24-01-08 23:44:52 -GET: 400544|
25-01-08 23:20:07 -GET: 402806|
25-01-08 23:20:16 -GET: 402811|
25-01-08 23:20:27 -GET: 402811|
25-01-08 23:20:38 -GET: 402811|
25-01-08 23:20:41 -GET: 402812|
25-01-08 23:21:11 -GET: 402812|
25-01-08 23:21:12 -GET: 402811|
26-01-08 01:14:53 -GET: 403013|
26-01-08 01:14:55 -GET: 403012|
26-01-08 19:32:06 -GET: 404442|
26-01-08 19:32:15 -GET: 404444|
26-01-08 19:32:24 -GET: 404444|
26-01-08 19:32:32 -GET: 404446|
26-01-08 19:32:40 -GET: 404446|
26-01-08 19:32:47 -GET: 404446|
26-01-08 19:32:58 -GET: 404446|
26-01-08 19:33:05 -GET: 404446|
26-01-08 19:33:13 -GET: 404446|
26-01-08 19:33:22 -GET: 404446|
26-01-08 19:33:28 -GET: 404446|
26-01-08 19:33:36 -GET: 404446|
26-01-08 19:33:43 -GET: 404446|
26-01-08 19:33:51 -GET: 404446|
26-01-08 19:34:03 -GET: 404446|
26-01-08 19:34:12 -GET: 404448|
26-01-08 19:34:22 -GET: 404451|
26-01-08 19:34:26 -GET: 404452|


RE: Défi sécurité. - Amrac - 05-02-2008

voila la solution:
Citation :Bon ça m'avait paru absurde sur le coup mais ton dernier message m'impose 16 de tenter le coup :

Je parie sur une erreur de synchronisation.

Le joueur prépare sa page avec le lien en 2 exemplaire, (enfin il mets les liens...) ou alors il spamme refresh.

Il peut alors arriver que ton script entre dans l'annulation, valide le premier appel, Rajoute l'armée, puis tente de détruire l'attaque. Mais pendant ce temps, un second script est lancé pour faire la même manoeuvre et arrive aussi à cette phase. Le temps pour appeller le serveur et faire le DELETE pourrait bien être suffisamment long, pour que l'armée soit Rajoutée une seconde fois, avant que ce script ne puisse plus être parcouru à cause de la suppression en base.

résultat : attaque annulée, 2 armées pour le prix d'une.

J'ai bon ? 16
Il s'agit donc d'une "spam attaque", bien que j'appellerais bien ca "flood attaque" ^^
Avec en prime un terrible effet boule de neige. Plus il y a de joueur qui tente cette attaque (qui ne réussi que très rarement à la base), et plus le serveur s'en prend dans la gueule, et plus le serveur est ralentie a force de s'en prendre dans la gueule, plus le bug se produit ....

J'ai pensé que vous aimeriez connaitre cette vacherie a l'avance ^^

En guise de solution, je pense opter pour interdire de charger une même page à moins de 1 ou 2 secondes d'intervalle en utilisant les sessions.

Si vous avez d'autres idées pour la solution, je suis preneur car je n'en est pas encore mis en place sur mon site ^^ (Pour l'instant, la possibilité d'annuler une attaque est désactivé).


RE: Défi sécurité. - Zamentur - 05-02-2008

Ah çà me rappelle une faille de la beta de ragol-online, elle permettait de la même manière d'avancer de plusieurs cases sans avoir les point de mouvement requis.
La solution mise en place était de retirer les points avant tout autre chose. Donc là lancer le delete avant le reste. Le problème c'est que réduire les chances de réussites d'une tel attaque.

Sachant que ce genre d'erreur de construction peut se trouver n'importe ou empêcher l'ouverture de page avec des intervalles semble une bonne solution (meilleur que tout se retaper)

Sinon une autre solution serait d'utiliser une variable session "en_cour" qui serait mise à true au début de chaque script et remise à false à la fin. De cette façon on sait qu'il n'y a pas d'autre demande en même temps.


RE: Défi sécurité. - Plume - 05-02-2008

A merde, j'étais bien dans l'idée du spamming, mais j'avais pas pensé que ça aurait le temps d'exécuter l'ajout d'armée ^^

M'enfin, pas folle la guêpe.

En solution .. J'suis pas convaincu que l'utilisation des sessions avec un temps limite codé en dur soit fiable. Tu ne peux pas savoir si l'exécution d'un script va malencontreusement prendre plus de temps ou pas, tu ne sais pas non plus si il va pouvoir exécuter 'légalement' ce script mais à cause du laps de temps, il ne pourra pas. Imagine 2 attaques qu'il souhaite annuler, par exemple Smile

Mais bon, j'ai pas de solutions meilleures pour le moment.


RE: Défi sécurité. - Zamentur - 05-02-2008

ben la seconde solution avec la variable en_cour semble mieux je pense, cela dit çà empêche aussi le lancement de 2 pages en même temps...

Cela dit on peut envisager de faire patienter le script jusqu'à ce que cette variable repasse à false. Ce qui fait qu'aucune page est renvoyé pour "lapse de temps trop cour" ou "exécution simultanée interdite". Mais du coup çà mange un peu de la rapidité, puisque si 2 actions sont lancé au même moment il faudra attendre que la première se termine pour commencer la deuxième
Autre problème si une action fait appel dans son traitement à la génération d'une autre page du même serveur dans son script, ce qui est assez rare mais imaginable. Enfin il y a toujours des solutions (mise en cache, buffer, modif complète du code)


RE: Défi sécurité. - Amrac - 05-02-2008

Zamentur a écrit :Ah çà me rappelle une faille de la beta de ragol-online, elle permettait de la même manière d'avancer de plusieurs cases sans avoir les point de mouvement requis.
La solution mise en place était de retirer les points avant tout autre chose. Donc là lancer le delete avant le reste. Le problème c'est que réduire les chances de réussites d'une tel attaque.
Ca me fait penser a mon compteur de connecté.
C'est un script tout bête:
Si l'IP n'est pas dans la table, on l'ajoute, sinon on met à jour le timestamp qui correspond.
Et pourtant, environ 2 à 3 fois par semaine, j'ai une erreur sql "duplicate entry" venant du script!
C'est quelque chose qui ne cesse de m'étonner, car c'est pas une action ultra courante d'ajouter une IP au compteur, et il n'y as casi aucun code entre le select qui determine si l'IP est dans la base, et le INSERT qui l'ajoute.
Je sais pas trop comment ca se produit, déjà faut croire que certain lance 2 fois mon site d'un coup... Enfin mystère...
Quoiqu'il en soit, ca remet pas mal de principe de conception en cause :/

Zamentur a écrit :Sachant que ce genre d'erreur de construction peut se trouver n'importe ou empêcher l'ouverture de page avec des intervalles semble une bonne solution (meilleur que tout se retaper)

Sinon une autre solution serait d'utiliser une variable session "en_cour" qui serait mise à true au début de chaque script et remise à false à la fin. De cette façon on sait qu'il n'y a pas d'autre demande en même temps.
J'ai bien la solution de mettre une variable session "en_cours".
De la sorte, si on execute un script et que "en_cours"==true, on pourrait faire un sleep d'1 seconde. Logiquement, la fonction Sleep devrait libérer le processeur et lui permette d'aller bosser ailleur, ce qui ferat avancer le script en cours.
Et si le script n'est toujours pas terminé au bout de la seconde, on relance le sleep...
Une question que je me pose, c'est comment est fait le sleep en PHP? Est-ce un bête while(1) jusqu'a ce que le temps soit écoulé, ou est-ce qu'il donne bien la main à d'autres processus....


Autre problème: Est-on certain de ne pas avoir de problème d'accés concurrent avec les session comme on a avec la base de données?


RE: Défi sécurité. - Roworll - 05-02-2008

Si ta base de données est en InnoDB ou tout autre format supportant les transactions, essaye de jeter un oeil dessus.
En incluant dans la même transaction le code de vérification dans la base et la mise à jours, cela devrait pouvoir t'aider.