2008-09-25:

Security Days 6 - zadanie 2

security:easy
Trochę się u mnie sprawy uspokoiły, więc wracam do opisywania zadanek z tegorocznego SD6. Z uwagi na późną godzinę dzisiaj opisze tylko jedno, a opisy kolejnych znajdą się w następnych dniach. Dodam że polskojęzyczni czytelnicy mogą znaleźć rozwiązania na oficjalnym forum SD6, natomiast, z uwagi na to że większość zadań była skonstruowana tak, że istniało kilka rozwiązań, oraz z uwagi na fakt iż mojego bloga czytają również osoby nie związane z językiem polskim, i tak opisze zadanka z SD6 po swojemu ;>

Cel zadania drugiego był taki sam jak zadania pierwszego - trzeba się dostać do panelu admina pewnej strony www. Budowa strony była zbliżona do budowy strony z pierwszego zadania, z tą różnicą że nie było żadnego LFI, a nazwy działów były w ASCII a nie base64 (np /zad2/?page=ofirmie). Jedną z rzeczy która rzucała się w oczy (tj jeśli sie miało odpalonego Live HTTP Headers oraz Firebuga z Firecookie to się rzucała w oczy ;>) to cookie ustawiane przez stronę - id=12345 (gdzie 12345 była bodajże losowa liczba). Pomieszanie chwile przy tym ciasteczku powodowało wyświetlenie warninga wskazującego skrypt /zad2/incl/setid.inc. Katalog incl okazywał się listowalny, i znajdowało się w nim kilka plików, w tym plik admin.inc zawierający następujący skrypt:

<?php

/* TopSecurity - Unhackable technologies!  */
/* M.Niedoceniany - m.niedoceniany@ts.labs */
/* (c) by TopSecurity                 2oo8 */

include("admin/admin.php");


/* debug? */

if ( $_GET['debug'] )
{
$del = abs((abs($_GET['del'])%0x7ffffff0)) + 1;
$ins = abs((abs($_GET['inc'])%0x7ffffff0)) + 1;
}
else
{
$del = 1;
$ins = 1;
}

/* auth stuff */

if ( isset($_POST['login']) && isset($_POST['password']) )
{

echo '<tr><td>';

if ( $_GET['debug'] )
{
echo '<!-- ';
echo levenshtein($adminPass, $_POST['login'] . $_POST['password'], $ins, 1, $del);
echo '-->';
}

if ( levenshtein($adminPass, $_POST['login'] . $_POST['password'], $ins, 1, $del) == 0 )
adminArea();
else
echo 'Nieprawidłowy login i/lub hasło!';
echo '</td></tr>';
}
else
{
include("incl/loginForm.inc");
}

?>


I w tym momencie rozwiązania się rozgałęziały. Metoda zaproponowana w rozwiązaniach przez organizatorów opierała się na analizie wewnętrznej budowy funkcji levenshtein, której najważniejszy fragment wygląda następująco:

static int reference_levdist(const char *s1, int l1, const char *s2, int l2, int cost_ins, int cost_rep, int cost_del )
{
 int *p1, *p2, *tmp;
 int i1, i2, c0, c1, c2;

 if(l1==0) return l2*cost_ins;
 if(l2==0) return l1*cost_del;


Czyli jeżeli jeden z podanych stringów jest pusty, to wynikiem jest długość drugiego pomnożona przez parametr $ins bądź $del. Ponieważ celem było zwrócenie przez funkcje levenshtein zera, to chodziło o takie wymanewrowanie skryptu żeby levenshtein zwrócił to zero. Okazuje się mimo zabezpieczeń w powyższym skrypcie (mowa o abs() i modulo) nadal da się to zrobić, rozwiązując równanie 32 * (x + 1) = 0 (32 bo tyle liter hasło miało) w przestrzeni 32 bitowej dla liczb signed. Jedną z prawidłowych wartości jest 134217727. Podawało się więc tą liczbę jako koszt $ins, i już.

Oczywiście ja bezwiednie wybrałem dłuższą drogę ;p

Dłuższa droga polegała na wykorzystaniu wartości zwracanej przez funkcję levenshteina do odgadywania kolejnych liter hasła. Odległość Levenshteina, lub inaczej, odległość edytorska, to kosz operacji dodawania, wymiany, oraz usuwania literek celem zamiany jednego wyrazu w drugi. Jak widać wyżej koszt każdej z tych operacji można określić (akurat koszt wymiany literki był stały w tym zadaniu). Tak więc sprawa jest dość prosta - wystarczy podstawiać kolejne literki z alfabetu za kolejne literki hasła, i notować przy których literkach odległość się zmniejsza (ta odległość była wypisywana jeśli debug było ustawione). Pewnym utrudnieniem ze strony organizatorów było użycie kilku znaków nie będących literkami w haśle, ale tak na prawdę sprowadzało się to jedynie do użycia odpowiedniego alfabetu. Oczywiście ręcznie nie ma co tego robić - python nadaje się natomiast do takich celów wyśmienicie.

I na tym zadanie się kończyło ;>

Muszę przyznać że bardzo mi się podobało, szczególnie że były dwie drogi aby je rozwiązać. W celach statystycznych podam że zajęło mi ono 40 minut, łączeni z napisaniem skryptu szukającego hasła.

OK, na teraz tyle ;>

P.S. Dodałem pewien komunikat pod notką o copyrightach w menu ;>

Comments:

2008-09-25 23:29:46 = serkamil
{
ktoś testował podatność na błędy Twój blog ?? ;D
}
2008-09-26 01:58:17 = Gynvael Coldwind
{
Ano testował ;> I słusznie ;>
Już dwa bugi (bugi, nie vulny ;>) poprawiłem - z dodawaniem komentarzy zawierających tylko whitespace, oraz z & nie zmieniającym się na & ;>
}
2008-09-26 04:18:19 = coldpeer
{
ja tak nie na temat ;) stopka:

"dodam że w pewnych miejscach umieściłem zabawne fotki z kotkami, jest ich obecnie 7, i zachęcam do ich poszukania ;>"

przy nieistniejącym ID jedno znalazlem :P np. http://gynvael.coldwind.pl/?id=666
}
2008-09-26 05:39:54 = Notopro
{
Moje znalezione:
http://gynvael.coldwind.pl/?id=admin
http://gynvael.coldwind.pl/?lang=admin
http://gynvael.coldwind.pl/?id=73 (wyślij pusty komentarz to zobaczysz o co chodzi :))
Pozdrawiam ;)
}
2008-09-26 06:29:35 = d0minikk
{
no no, ciekawie pomyślane z tymi kotkami ;>
}
2008-09-26 06:48:26 = Gynvael Coldwind
{
Hihi OK, no to 4 już są ;> Good work ;>
Jeszcze 3 ;>

Dodam że nie we wszystkich miejscach są kotki, a w niektórych się powtarzają takie same. Nyom ;> Niektóre miejsca gdzie kotki są, są dość niestandardowe. Noo i jak zauważyliście nie wszystkie kotki są kotkami :D
}
2008-09-26 07:28:48 = bpSpb
{
Jeszcze jeden obrazek przy nieprawidłowym adresie RSS. ;>
}
2008-09-26 07:32:18 = bpSpb
{
Nie to chyba nie był feed... teraz nie moge go znalezc. :/
}
2008-09-26 13:05:01 = luq
{
Zmiana ciasteczka lang na dowolny tekst powoduje wyświetlenie tego kota :>
http://gynvael.coldwind.pl/6q1c61k.jpg
}
2008-09-27 09:45:15 = KKKas
{
Też znalazłem tylko te 5...
http://delicious.com/KKKas/gynvael
}
2008-09-30 00:23:44 = Gynvael Coldwind
{
Nieźle nieźle ;>
Kombinujcie dalej ;> Dodam że miejsca niekoniecznie są standardowe ;>
Jeszcze tylko 2 wam zostały do znalezienia ;>
Dobra robota póki co ;>

}
2008-10-03 05:16:34 = luq
{
Gyn, może jakąś małą podpowiedź dasz?
Coś z fotkami? ;>
}
2008-10-04 10:28:50 = Gynvael Coldwind
{
Nope ;> Będę wredny ;> Bez podpowiedzi ;>
No... no dobra ;> jedna mała ;> Niektóre kotki nie są z rodziny błędów WWW, są tu niejako w odwiedzinach ;>
}

Add a comment:

Nick:
URL (optional):
Math captcha: 4 ∗ 10 + 10 =