Szukamy błędów SQL Injection, Session Hijacking, Auth Bypass w CMS

W tym artykule dowiesz się ode mnie w jaki sposób znalazłem kilka bardzo poważnych błędów w systemie zarządzania treścią Netious CMS. Wszystkie błędy pozwalały na zalogowanie się do systemu z uprawnieniami administratora. Znalezione błędy należą do klas: SQL Injection, Auth Bypass oraz Session Hijacking. Ten ostatni błąd zasługuje na szczególną uwagę, ponieważ jest to bardzo ciekawy przypadek podatności związanej z zarządzaniem sesjami.

Session Hijacking.

Netious sprawdza identyfikator użytkownika w bazie i jeśli równy jest on 1, logujemy się jako administrator. Przyjrzyjmy się bliżej plikowi cms/log.php, który zawiera kod odpowiedzialny za proces logowania się. Poniższy kod stanowi część pliku cms/log.php. Poniżej linie od 9-29

$result=mysql_query("SELECT AdminId FROM mycmsadmin WHERE username='$username' and password='".sha1($password)."'");
$row=mysql_fetch_row($result);
$num_rows = mysql_num_rows($result);


$id=$row[0];
if ($num_rows==1){
$SID=f_ip2dec($REMOTE_ADDR);
if (!session_id($SID))
session_start();
if (!session_is_registered('signed_in'))
session_register('signed_in');
$signed_in = "indeed";
session_register('uname');
$uname = $username;
session_register('pass');
$pass = $password;

if ($id=="1"){
Header( "Location: admin.php");
}

W linii 9 widać zapytanie, które pobiera identyfikator użytkownika. Domyślnie pierwszym użytkownikiem zapisanym w tabeli jest admin. Widzimy, że skrypt nigdzie nie inicjuje zmiennej ‘username’ ani jej nie czyści. Można tutaj wstrzyknąć kod SQL, np. za ‘username’ podstawiając cokolwiek’ or 1=1/*

Zapytanie przyjmie wtedy postać:

SELECT AdminId FROM mycmsadmin WHERE username=” or 1=1/*

or 1=1 ma na celu zwrócenie zawsze wartości prawda, natomiast /* jest znakiem komentarza dalszej części zapytania. Wynikiem zapytania, gdzie zwrócona jest prawda i pobieramy pierwszy wiersz wyniku, będzie zarazem pierwszy wiersz tabeli. Jeśli pierwszym użytkownikiem zarejestrowanym w systemie jest admin, zapytanie to pozwoli na zalogowanie się z jego uprawnieniami, co de facto ma miejsce w przypadku tego systemu CMS.

Auth Bypass

Błąd SQL Injection, powoduje również możliwość autoryzacji jako administrator, czyli mamy kolejny błąd – Auth Bypass.

Ostatnim błędem jaki opiszę, jest bardzo ciekawy błąd zarządzania sesjami. Błędny kod znajduje się w pliku cms/admin.php. Linie od 11-27:

$SUID=f_ip2dec($REMOTE_ADDR);
if (!session_id($SUID))
session_start();

$username=$_SESSION['uname'];
$password=$_SESSION['pass'];

$result=mysql_query("SELECT AdminId FROM mycmsadmin WHERE username='$username' and password='".sha1($password)."'");
$row=mysql_fetch_row($result);
$num_rows = mysql_num_rows($result);
$id=$row[0];



if ($_SESSION['signed_in']!='indeed' || $num_rows!=1 || $id!=1){
Header( "Location: index.php?action=2");
}else{  ------------>admin control panel

Jak wygląda ścieżka wykorzystania podatności

Przeanalizujmy studium przypadku zwracając uwagę na powyższe fragmenty skryptów:

  • Administrator znajdujący się w sieci lokalnej loguje się do systemu CMS, podając login i hasło administracyjne.
  • Generowany jest identyfikator sesji, bazując na adresie IP z którym ‘wychodzi’ na zewnątrz administrator.
  • Ustawiane są odpowiednie zmienne sesyjne ‘uname’ i ‘pass’ na login i hasło administratora
  • Następuje przekierowanie na admin.php
  • W tym momencie każdy użytkownik, którego zewnętrzny adres IP będzie taki sam jak IP administratora, wystarczy że odwiedzi stronę admin.php i dzięki mechanizmowi sesji, której zmienne już wcześniej ustawione zostały po zalogowaniu administratora, uzyskuje najwyższe uprawnienia.

Problem tkwi tutaj w tym, że zmienna sesyjna w pliku admin.php przyjmuje wartość numeryczną adresu IP użytkownika. Na jej podstawie następuje zapytanie do bazy a co za tym idzie autoryzacja użytkownika. Problem w tym, że wcześniej zalogowany administrator utworzył właśnie taki sam identyfikator. Z jego uprawnieniami będzie działał każdy użytkownik, który dzierżawi ten sam adres IP. Nie konieczne jest nawet logowaniesesja jeśli nie była ustanowiona w momencie logowania, to i tak zostanie zainicjalizowana po wejściu na stronę admin.php, a jak wiemy wszystkie zmienne ‘administracyjne’ są już w niej wcześniej ustawione.

5 1 vote
Ocena artykułu
Subscribe
Powiadom o
guest
0 komentarzy
Inline Feedbacks
View all comments
0
Zależy mi na Twojej opinii poniżej 😀x