Puskuriylivuodot ja shellcode
Tutustukaa puskuriylivuotohaavoittuvuuksien toimintamekanismeihin ja siihen, miten niitä voidaan hyödyntää haitallisen shellcoden syöttämiseen ja suorittamiseen.
Puskuriylivuodot ja shellcode on ilmainen Assembly-kieli ja x86-tason järjestelmäohjelmointi-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Assembly-kieli ja x86-tason järjestelmäohjelmointi-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Assembly-kieli ja x86-tason järjestelmäohjelmointi-kurssilla on yhteensä 4 oppituntia.
Johdanto: puskuriylivuodot
Tervetuloa matalan tason tietoturvan tärkeän aiheen pariin: puskuriylivuodot. Ne ovat ohjelmistohaavoittuvuuksia, joiden avulla hyökkääjät voivat saada ohjelman hallintaansa.
Puskuriylivuoto tapahtuu, kun ohjelma yrittää kirjoittaa kiinteän kokoiseen muistipuskuriin enemmän dataa kuin siihen on suunniteltu mahtuvan. Ylimääräinen data ”vuotaa yli” viereisille muistialueille.
Mikä on puskuri?
Ohjelmoinnissa, erityisesti C:n tai assembly-kielen kaltaisissa kielissä, puskuri on yksinkertaisesti datan tallentamista varten varattu muistilohko. Voitte ajatella sitä säiliönä, jolla on tietty kapasiteetti.
- Puskureita käytetään usein väliaikaiseen tallennukseen, kuten käyttäjän syötteen tai verkkodatan säilyttämiseen.
- Ne voidaan määritellä merkkitaulukoiksi (merkkijonoiksi) tai muiksi tietotyypeiksi.
- Esimerkiksi
char username[32];määrittelee puskurin, johon mahtuu enintään 31 merkkiä ja nollaterminaattori.
Koodi: haavoittuva puskuri
Tarkastellaan yksinkertaista C-ohjelmaa, jossa on tarkoituksellinen puskuriylivuotohaavoittuvuus. Kiinnittäkää erityistä huomiota strcpy-funktioon.
strcpy kopioi merkkijonon lähteestä kohteeseen, mutta se ei tarkista kohdepuskurin kokoa. Tämä on yleinen ylivuotojen aiheuttaja.
/* buffer_example.c */
#include <stdio.h>
#include <string.h>
// This function is intentionally vulnerable
void vulnerable_greet(char *name_input) {
char buffer[16]; // A small buffer, 16 bytes
// This is the vulnerability! strcpy doesn't check size.
// If name_input is longer than 15 chars (+ null terminator),
// it will overflow 'buffer'.
strcpy(buffer, name_input);
printf("Hello, %s!\n", buffer);
}
int main() {
// Let's call the vulnerable function with a safe input
vulnerable_greet("CoddyKit User");
printf("Program finished normally.\n");
return 0;
}Pinokehys
Ymmärtääksemme, miten ylivuotoja voidaan hyödyntää, meidän on palattava kutsupinoon. Kun funktiota kutsutaan, luodaan uusi pinokehys.
Pinokehys sisältää yleensä:
- Funktion paikalliset muuttujat.
- Tallennetun Base Pointer -osoittimen (EBP/RBP).
- Kaikkein tärkeimpänä paluuosoitteen, joka kertoo suorittimelle, mistä suoritusta jatketaan funktion päätyttyä.
Paluuosoitteen ylikirjoittaminen
Kun pinossa tapahtuu puskuriylivuoto, ylimääräinen data ei ainoastaan turmele viereisiä paikallisia muuttujia. Jos dataa syötetään riittävästi, se voi ylikirjoittaa tallennetun EBP:n ja sen jälkeen itse paluuosoitteen.
Muuttamalla paluuosoitetta hyökkääjä voi huijata ohjelman hyppäämään mielivaltaiseen muistiosoitteeseen sen sijaan, että se palaisi oikeaan kutsujaan. Tämä on monien puskuriylivuotoihin perustuvien hyökkäysten keskeinen toimintamekanismi.
Shellcoden esittely
Minne hyökkääjä haluaa ohjelman hyppäävän? Yleensä hallitsemaansa koodiosaan, jota kutsutaan nimellä shellcode.
- Shellcode on pieni, itsenäinen konekoodinpätkä.
- Sen ensisijaisena tarkoituksena on usein suorittaa kohdejärjestelmässä ”shell” eli komentokehote.
- Se voi myös suorittaa muita haitallisia toimia, kuten luoda uusia käyttäjiä, ladata tiedostoja tai muodostaa yhteyden etäpalvelimeen.
Yksinkertaisen shellcoden rakenne
Shellcode kirjoitetaan yleensä assembly-kielellä, jotta siitä saadaan mahdollisimman kompakti ja tehokas. Se välttää nollatavuja (\x00), koska monet merkkijonofunktiot lopettavat kopioinnin ensimmäiseen nollatavuun.
Yleinen tavoite on kutsua execve-järjestelmäkutsua (Linuxissa) komennon /bin/sh käynnistämiseksi.
; Example (conceptual) Linux x86 shellcode snippet:
; mov eax, 0x0b ; Syscall number for execve
; mov ebx, addr_of_sh ; Pointer to '/bin/sh' string
; mov ecx, 0 ; Arg 2 (argv) = NULL
; mov edx, 0 ; Arg 3 (envp) = NULL
; int 0x80 ; Invoke kernel (syscall)Shellcoden syöttäminen
Miten shellcode päätyy ohjelmaan? Hyökkääjä sisällyttää sen haitalliseen syötteeseen, joka aiheuttaa puskuriylivuodon.
Kun puskuri vuotaa yli, shellcode kirjoitetaan ohjelman muistiin, yleensä pinoon ylikirjoitetun paluuosoitteen viereen.
Hyökkäyksen rakenne: NOP-liukuma
Hyökkääjät käyttävät usein NOP-liukumaa (No Operation -liukumaa) parantaakseen hyökkäyksensä luotettavuutta.
- NOP-liukuma on ”No Operation” -käskyjen (NOP) sarja (esimerkiksi
\x90x86:ssa). - Jos hyökkääjä ylikirjoittaa paluuosoitteen osoittamaan mihin tahansa NOP-liukuman kohtaan, suoritin suorittaa NOP-käskyjä, kunnes ”liukuu” varsinaiseen shellcodeen.
- Tämä kompensoi shellcoden tarkan muistiosoitteen arvioinnissa olevia pieniä epätarkkuuksia.
Suojaukset ja lievennyskeinot
Käyttöjärjestelmät ja kääntäjät ovat kehittäneet useita suojauksia puskuriylivuotoja vastaan:
- ASLR (Address Space Layout Randomization): Muistiosoitteet satunnaistetaan, jotta paluuosoitteen tai shellcoden sijainnin arvaaminen olisi vaikeampaa.
- DEP/NX-bitti (Data Execution Prevention/No-Execute): Muistialueet, kuten pino, merkitään suorituksen estäviksi, jolloin shellcodea ei voida suorittaa niissä.
- Pinokanit: Kääntäjän luomia satunnaisia arvoja, jotka sijoitetaan pinoon. Jos ne ylikirjoitetaan, ohjelma havaitsee peukaloinnin ja keskeyttää suorituksen.
- Turvalliset funktiot: Käytetään funktioita, kuten
strncpy,snprintfjafgets, tai C++-merkkijonoja, jotka tarkistavat rajat.
Testatkaa ymmärrystänne
Pinopuskurin ylivuoto antaa hyökkääjälle mahdollisuuden kirjoittaa puskurin lopun yli. Mikä on hyökkääjän ensisijainen tavoite, kun hän muotoilee syötteen huolellisesti paluuosoitteen ylikirjoittamiseksi?
Kertaus: ylivuodot ja shellcode
Tässä oppitunnissa tutustuimme puskuriylivuotojen vaaralliseen maailmaan. Opimme, että niitä tapahtuu, kun kiinteän kokoiseen puskuriin kirjoitetaan liikaa dataa, jolloin viereinen muisti korruptoituu.
Erityisen vaarallista on, jos ylivuoto ulottuu pinossa olevaan paluuosoitteeseen, jolloin hyökkääjä voi kaapata ohjelman ohjauksen. Tämä onnistuu syöttämällä shellcodea eli pientä haitallista konekoodia ja ohjaamalla suoritus siihen, usein NOP-liu'un avulla. Tutustuimme myös keskeisiin torjuntatekniikoihin, kuten ASLR:ään, DEP:hen ja pinon canary-arvoihin.
Opi Assembly tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 12
- Oppitunnit
- 48
Usein kysytyt kysymykset
Onko oppitunti ”Puskuriylivuodot ja shellcode” ilmainen?
Kyllä – oppitunnin ”Puskuriylivuodot ja shellcode” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Assembly-kieli ja x86-tason järjestelmäohjelmointi-kurssin, päivitä CoddyKit PROhon. Assembly-kieli ja x86-tason järjestelmäohjelmointi-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Puskuriylivuodot ja shellcode”?
Tutustukaa puskuriylivuotohaavoittuvuuksien toimintamekanismeihin ja siihen, miten niitä voidaan hyödyntää haitallisen shellcoden syöttämiseen ja suorittamiseen. Harjoittelet Assembly-kieli ja x86-tason järjestelmäohjelmointi-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Assembly-kieli ja x86-tason järjestelmäohjelmointi-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Assembly-kieli ja x86-tason järjestelmäohjelmointi-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.
Kuinka kauan ”Puskuriylivuodot ja shellcode”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Assembly-kieli ja x86-tason järjestelmäohjelmointi-oppitunnilla?
Kyllä. Jokainen Assembly-kieli ja x86-tason järjestelmäohjelmointi-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Välimuistin koherenssi ja suorituskyky
- Kriittisten osioiden käsin optimointi
- Puskuriylivuodot ja shellcode
- Haarautumisen ennustaminen ja spekulatiivinen suoritus