Huom. kohteen IP-osoite vaihtuu tehtävässä, koska harjoitusta tehty eri kerroilla.
Kohteen Nmap-skannauksesta huomataan, että kohteessa on avoinna portit 22 (SSH) ja 80 (HTTP). Portissa 80 on käynnissä HTTP Node.js -palvelin.
Selaimella avattu kohteen IP-osoite. Aukesi sivu, jossa lukee että sivussa huoltokatko. Sivulla on lomakenttä johon voi syöttää sähköpostiosoitteen, jotta saa tiedon milloin sivusto on toiminnassa.
Syötetty kenttään kuvitteellinen sähköpostiosoite: jotaintekstia@jotain.com. Tuli ilmoitus, että otetaan yhteyttä sähköpostiosoitteeseen.
Nmap-syöttestä havaittiin, että sivusto on rakennettu Node.js päälle. Selaimen lisäosalla Wappalyzer:lla vahvistettu, että sivusto käyttää Express-rakennetta. Yleinen hyökkäystapa Node.js sivustoihin on SSTI (Server-side template injection).
Kokeiltu syöttää sivuston sähköpostikenttään seuraavia payloadeja (lähde: https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection), jotta tunnistetaan, onko sivusto haavoittuva:
{{7*7}}
${7*7}
<%= 7*7 %>
${{7*7}}
#{7*7}
Payloadilla {{7*7}} sivulle tuli virheilmoitus. Virhekoodista huomataan, että palvelin on käynnissä /root/Backend -hakemistossa ja Handlebars Template Engine on käytössä. Template Enginet näyttävät dynaamisesti luotua sisältöä verkkosivuilla, ja ovat alttiita haavoittuvuuksille.
Aukaistu Burb Suite ja laitettu FoxyProxy päälle. Lähetetty payloadi uudellen ja siepattu POST-requesti. Lähetetty requesti Burb Suitessa Repeater-välilehdelle painamalla näppäimistöstä ctrl+r.
Hacktricks sivun Handlebars-osiosta otettu payloadi ja URL-koodattu se Burb Suitessa (Encode as URL).
URL-koodattu payloadi kopioitu POST-requestin email-kenttään ja lähetetty payloadi painamalla “send”.
Saatiin vastauksena virhekoodi: require is not defined. Payloadin osa: {{this.push “return require(‘child_process’).exec(‘whoami’);”}} antaa todennäköisesti virhettä. Require objektia käytetään JavaScriptissä ja Node.js:ssä lataamaan koodia muista moduuleista sekä tiedostoista.
Node.js dokumentaatiosivulla on mainittu: “These objects are available in all modules. The following variables may appear to be global but are not”. Require on yksi näistä objekteista, joten tässä tapauksessa pitää käyttää jotain toista Node.js global-objektia.
Käytetään process -objektia. Burb Suitessa muokattu return-kenttään require(‘child_process’).exec(‘whoami’) tilalle: process ja lähetetty requesti.
Vinkki: Burb Suitessa pystyy purkamaan (decode) URL-koodatun tekstin painamalla näppäimistöstä ctrl+shift+u.
Response-välilehdella ei nyt saatu virhettä, ja objekti process näkyy vastauksessa.
Process objektissa on käytössä mainModule ominaisuus, jolla voidaan mahdollisesti ladata require -objekti. Payloadiin muokattu: return process.mainModule. Vastauksena ei saatu virhettä, joten mainModule ominaisuus on saatavilla.
Lisätty vielä payloadiin require ja ladattu child_process moduuli: require(‘child_process’)
Child_process moduuli on saatavilla oletuksena Node.js:ssä, ja mahdollistaa järjestelmän komentojen suorittamisen. Require objekti meni läpi ilman virheitä.
Yritetään suorittaa järjestelmässä komento whoami lisäämällä payloadiin: execSync(‘whoami’)
Saatiin vastaus: root
Payloadissa vaihdettu komennon whoami tilalle: ls /root
Onnistuneesti päästiin hakemistoon /root, josta löyty root flag.
Luettu flag.txt tiedoston sisältö kirjoittamalla payloadiin komento: cat /root/flag.txt