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:
Już dwa bugi (bugi, nie vulny ;>) poprawiłem - z dodawaniem komentarzy zawierających tylko whitespace, oraz z & nie zmieniającym się na & ;>
"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
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 ;)
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
http://gynvael.coldwind.pl/6q1c61k.jpg
http://delicious.com/KKKas/gynvael
Kombinujcie dalej ;> Dodam że miejsca niekoniecznie są standardowe ;>
Jeszcze tylko 2 wam zostały do znalezienia ;>
Dobra robota póki co ;>
Coś z fotkami? ;>
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: