Off by one overflow

Reading time: 5 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Basic Information

Kuwa na ufikiaji wa overflow ya 1B inaruhusu mshambuliaji kubadilisha uwanja wa size kutoka kwa kipande kinachofuata. Hii inaruhusu kuingilia kati ni vipande gani vinaachiliwa, na huenda ikazalisha kipande kinachoshikilia kipande kingine halali. Utekelezaji ni sawa na double free au vipande vinavyoshirikiana.

Kuna aina 2 za udhaifu wa off by one:

  • Byte isiyo na mpangilio: Aina hii inaruhusu kuandika byte hiyo kwa thamani yoyote
  • Byte ya Null (off-by-null): Aina hii inaruhusu kuandika byte hiyo tu kwa 0x00
  • Mfano wa kawaida wa udhaifu huu unaweza kuonekana katika msimbo ufuatao ambapo tabia ya strlen na strcpy haiko sawa, ambayo inaruhusu kuweka byte ya 0x00 mwanzoni mwa kipande kinachofuata.
  • Hii inaweza kutumika kwa House of Einherjar.
  • Ikiwa unatumia Tcache, hii inaweza kutumika katika hali ya double free.
Off-by-null
c
// From https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/
int main(void)
{
char buffer[40]="";
void *chunk1;
chunk1 = malloc(24);
puts("Get Input");
gets(buffer);
if(strlen(buffer)==24)
{
strcpy(chunk1,buffer);
}
return 0;
}

Kati ya ukaguzi wengine, sasa kila wakati kipande kinapokuwa huru, ukubwa wa awali unalinganishwa na ukubwa uliowekwa katika metadata ya kipande, na kufanya shambulio hili kuwa gumu sana kuanzia toleo la 2.28.

Mfano wa msimbo:

Lengo

  • Fanya kipande kiwe ndani ya kipande kingine ili kuandika ufikiaji juu ya kipande hicho cha pili kuruhusu kuandika juu ya kile kilichomo

Mahitaji

  • Off by one overflow kubadilisha taarifa za metadata za ukubwa

Shambulio la jumla la off-by-one

  • Pata vipande vitatu A, B na C (kusema ukubwa 0x20), na kingine ili kuzuia kuunganishwa na kipande cha juu.
  • Acha C (iliyoingizwa kwenye orodha ya bure ya 0x20 Tcache).
  • Tumia kipande A kujaa juu ya B. Tumia off-by-one kubadilisha uwanja wa size wa B kutoka 0x21 hadi 0x41.
  • Sasa tuna B ikijumuisha kipande huru C
  • Acha B na pata kipande cha 0x40 (kitakuwa hapa tena)
  • Tunaweza kubadilisha kiashiria cha fd kutoka C, ambacho bado ni huru (Tcache poisoning)

Shambulio la off-by-null

  • Vipande 3 vya kumbukumbu (a, b, c) vinahifadhiwa moja baada ya nyingine. Kisha kipande cha kati kinachukuliwa. Kipande cha kwanza kina udhaifu wa off by one overflow na mshambuliaji anautumia kwa 0x00 (ikiwa byte ya awali ilikuwa 0x10 ingefanya kipande cha kati kuonyesha kwamba ni 0x10 kidogo kuliko ilivyo).
  • Kisha, vipande viwili vidogo zaidi vinapatikana katika kipande kilichochukuliwa (b), hata hivyo, kama b + b->size kamwe havisasisha kipande c kwa sababu anwani iliyoonyeshwa ni ndogo kuliko inavyopaswa.
  • Kisha, b1 na c vinachukuliwa. Kama c - c->prev_size bado inaonyesha b (b1 sasa), vyote vinaundwa katika kipande kimoja. Hata hivyo, b2 bado kiko kati ya b1 na c.
  • Hatimaye, malloc mpya inafanywa ikirejesha eneo hili la kumbukumbu ambalo kwa kweli litakuwa na b2, ikiruhusu mmiliki wa malloc mpya kudhibiti maudhui ya b2.

Picha hii inaelezea shambulio kwa ukamilifu:

https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks

Mifano Mingine & Marejeleo

  • https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks
  • Bon-nie-appetit. HTB Cyber Apocalypse CTF 2022
  • Off-by-one kwa sababu ya strlen ikizingatia uwanja wa size wa kipande kinachofuata.
  • Tcache inatumika, hivyo shambulio la jumla la off-by-one linafanya kazi kupata primitive ya kuandika isiyo na mpangilio kwa kutumia Tcache poisoning.
  • Asis CTF 2016 b00ks
  • Inawezekana kutumia off by one kuvuja anwani kutoka kwenye heap kwa sababu byte 0x00 ya mwisho wa mfuatano inayoandikwa tena na uwanja unaofuata.
  • Kuandika isiyo na mpangilio kunapatikana kwa kutumia off by one kuandika ili kufanya kiashiria kiwe kwenye mahali pengine ambapo muundo wa uwongo na viashiria vya uwongo vitajengwa. Kisha, inawezekana kufuata kiashiria cha muundo huu ili kupata kuandika isiyo na mpangilio.
  • Anwani ya libc inavuja kwa sababu ikiwa heap inapanuliwa kwa kutumia mmap, kumbukumbu iliyotolewa na mmap ina offset thabiti kutoka libc.
  • Hatimaye, kuandika isiyo na mpangilio kunatumika kuandika kwenye anwani ya __free_hook kwa kutumia gadget moja.
  • plaidctf 2015 plaiddb
  • Kuna udhaifu wa NULL off by one katika kazi ya getline inayosoma mistari ya ingizo la mtumiaji. Kazi hii inatumika kusoma "funguo" ya maudhui na si maudhui yenyewe.
  • Katika andiko hilo vipande 5 vya awali vinaundwa:
  • kipande1 (0x200)
  • kipande2 (0x50)
  • kipande5 (0x68)
  • kipande3 (0x1f8)
  • kipande4 (0xf0)
  • kipande cha ulinzi (0x400) ili kuepuka kuunganishwa na kipande cha juu
  • Kisha kipande 1, 5 na 3 vinachukuliwa, hivyo:

[ 0x200 Kipande 1 (huru) ] [ 0x50 Kipande 2 ] [ 0x68 Kipande 5 (huru) ] [ 0x1f8 Kipande 3 (huru) ] [ 0xf0 Kipande 4 ] [ 0x400 Kipande cha ulinzi ]

- Kisha kwa kutumia kipande3 (0x1f8) udhaifu wa null off-by-one unatumika kuandika prev_size kuwa `0x4e0`.
- Kumbuka jinsi ukubwa wa vipande vilivyotolewa awali 1, 2, 5 na 3 pamoja na vichwa vya vipande hivyo 4 vinavyolingana na `0x4e0`: `hex(0x1f8 + 0x10 + 0x68 + 0x10 + 0x50 + 0x10 + 0x200) = 0x4e0`
- Kisha, kipande 4 kinachukuliwa, kikizalisha kipande kinachotumia vipande vyote hadi mwanzo:
- ```python
[ 0x4e0 Kipande 1-2-5-3 (huru) ] [ 0xf0 Kipande 4 (kilichoharibiwa) ] [ 0x400 Kipande cha ulinzi ]

[ 0x200 Kipande 1 (huru) ] [ 0x50 Kipande 2 ] [ 0x68 Kipande 5 (huru) ] [ 0x1f8 Kipande 3 (huru) ] [ 0xf0 Kipande 4 ] [ 0x400 Kipande cha ulinzi ]