sobota, 12 maja 2012

QuickBlog v0.8 CMS - Multiple Web Vulnerabilities

QuickBlog jest napisany w PHP4 / PHP5 i używa bazy danych MySQL. 
Jego obsługa jest bardzo łatwa, używany jest w nim edytor WYSIWYG TinyMCE.




Dziurawe Moduły:
 
* SQL Injection: 
 
   [+] admin/gestionpost.php
   [+] include/fct_affiche.inc.php
 
* XSS:
 
 
   [+] recherche.php
   [+] commentaire/form.php
   [+] admin/samplemodifieddata.php
   [+] admin/sampleposteddata.php 
 
PoC: 
 
* SQL Injection
 
 http://127.0.0.1/quickblog/admin/gestionpost.php?page=[ SQL Injection ]
 
* XSS
 
Wkleję jeden przykład. W wyszukiwarce na głównej stronie wysyłamy postem
'search' do pliku recherche.php. $_POST['search'] nie ma tam porządnego
filtrowania, tzn. wcale go nie posiada.

<form action="http://127.0.0.1/quickblog/recherche.php" method="post">
<input type="hidden" name="search" value="<script>alert(1)</script>" />
<input type="submit" value="XSS"/>
</form> 


Fix: 
 
W pliku: admin/gestionpost.php
W lini 85 - 89:

                if(isset($_GET['page']))
                {
                    $page = $_GET['page'];
                    $page = $page - 1;
                }

zamieńmy na:

                if(isset($_GET['page']))
                {
                    $page = (int)$_GET['page'];
                    if($page<0) $page = 0; 
                }

W pliku: include/fct_affiche.inc.php
W lini 56 - 59:

                if(isset($_GET['page']))
                {
                    $page = $_GET['page'];
                    $page = $page - 1;
                }

zamieńmy na:

                if(isset($_GET['page']))
                {
                    $page = (int)$_GET['page'];
                    if($page<0) $page = 0;  
                }

W pliku: recherche.php
In lines 52 - 55:

                if (isset($_POST['search']))
                {
                    $mot = $_POST['search'];
                }

zamieńmy na:

                if (isset($_POST['search']))
                {
                    $mot = htmlspecialchars(strip_tags($_POST['search']));
                }

W pliku: commentaire/form.php
W lini 41:

               $nom=$_POST['nom'];

zamieńmy na:

               $nom= htmlspecialchars(strip_tags($_POST['nom']));

W pliku: admin/samplemodifieddata.php
In lines 47:

               $titre = $_POST['title'];

zamieńmy na:

               $titre = htmlspecialchars(strip_tags($_POST['title']));

W pliku: admin/sampleposteddata.php
In lines 38:

              $titre = $_POST['title'];

zamieńmy na:

              $titre = htmlspecialchars(strip_tags($_POST['title']));
 
 
Dlaczego w poprawce np. pliku admin/gestionpost.php jest: 

$page = (int)$_GET['page'];
if($page<0) $page = 0;   

zamiast po prostu 
 
$page = (int)$_GET['page'];  
 
?

Spójrzmy na dalszą część kodu pliku admin/gestionpost.php:
 

   $limit_par_page = 7;

   ...
   $from = $page * $limit_par_page;
   $query="SELECT * FROM " . $prefixe . "post order by `date` DESC LIMIT $from,$limit_par_page";
   $db->query($query);


Gdy dali byśmy tylko 
$page = (int)$_GET['page'];
 
Wtedy owszem, nie przeszły by żadne apostrofy, ALE
-1 już by przeszło, co w tym przypadku także powoduje błąd SQL Injection.
 
Wartość $page powinna być większa, bądź równa 0. 

Brak komentarzy:

Prześlij komentarz