I have a lecture where I got a program and I should analyse it about security flaws.
I found a leak where a pointer which pointed to data allocated in heap, where the data has been freed and the program still has the pointer in use.
When I then checked the contents of the leaked address in GDB, I excpected a 64bits address corresponding to some heap bin. But I found a strange address, where 3 bytes seems missing:
leaked pointers
0x59c0b003f380
0x59c0b003f2a0
gef➤ x/20gx 0x59c0b003f380
0x59c0b003f380: 0x000000059c0b003f 0x000059c0b003f2a0
0x59c0b003f390: 0x0000000000000000 0x00000000000000e1
0x59c0b003f3a0: 0x00007d4209003bf0 0x00007d4209003bf0
0x59c0b003f3b0: 0x0000000000000000 0x0000000000000000
0x59c0b003f3c0: 0x0000000000000000 0x0000000000000000
0x59c0b003f3d0: 0x0000000000000000 0x0000000000000000
0x59c0b003f3e0: 0x0000000000000000 0x0000000000000000
0x59c0b003f3f0: 0x0000000000000000 0x0000000000000000
0x59c0b003f400: 0x0000000000000000 0x0000000000000000
0x59c0b003f410: 0x0000000000000000 0x0000000000000000
gef➤ x/20gx 0x59c0b003f2a0
0x59c0b003f2a0: 0x000059c0b003fd10 0x00007d4209003b20
0x59c0b003f2b0: 0x3232323231313131 0x3232323232323232
0x59c0b003f2c0: 0x3232323232323232 0x3232323232323232
0x59c0b003f2d0: 0x0000000032323232 0x6d6f682f00000000
0x59c0b003f2e0: 0x0000726573752f65 0x0000000000000000
0x59c0b003f2f0: 0x0000000000000000 0x0000000000000000
0x59c0b003f300: 0x0000000000000000 0x752f7d42090044e0
0x59c0b003f310: 0x722f6e69622f7273 0x0000000068736162
0x59c0b003f320: 0x0000000000000000 0x000059c0b003f380
0x59c0b003f330: 0xffffffffffffffff 0x0000000000000000
gef➤ heap bins
───────────────────────────────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────
All tcachebins are empty
─────────────────────────────────────────────────────────────────────────────────────────────────── Fastbins for arena at 0x7d4209003ac0 ───────────────────────────────────────────────────────────────────────────────────────────────────
Fastbins[idx=0, size=0x20] ← Chunk(addr=0x59c0b003f380, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
Fastbins[idx=1, size=0x30] 0x00
Fastbins[idx=2, size=0x40] 0x00
Fastbins[idx=3, size=0x50] 0x00
Fastbins[idx=4, size=0x60] 0x00
Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
───────────────────────────────────────────────────────────────────────────────────────────────── Unsorted Bin for arena at 0x7d4209003ac0 ─────────────────────────────────────────────────────────────────────────────────────────────────
[+] unsorted_bins[0]: fw=0x59c0b003f290, bk=0x59c0b003fd10
→ Chunk(addr=0x59c0b003f2a0, size=0xb0, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) → Chunk(addr=0x59c0b003fd20, size=0xc00, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[+] Found 2 chunks in unsorted bin.
────────────────────────────────────────────────────────────────────────────────────────────────── Small Bins for arena at 0x7d4209003ac0 ──────────────────────────────────────────────────────────────────────────────────────────────────
[+] small_bins[13]: fw=0x59c0b003f390, bk=0x59c0b003f390
→ Chunk(addr=0x59c0b003f3a0, size=0xe0, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[+] Found 1 chunks in 1 small non-empty bins.
────────────────────────────────────────────────────────────────────────────────────────────────── Large Bins for arena at 0x7d4209003ac0 ──────────────────────────────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in 0 large non-empty bins.
As you can see the FW Pointer of 0x59c0b003f380 looks odd and seems missing the last 3 bytes.
info proc mappings
gets me this heap address:
0x59c0b003f000 0x59c0b0060000 0x21000 0x0 rw-p [heap]
It would correspond with this address when there is some weird optimization, but that’s just a wild thought of mine.
I also see it’s marked as fastbin, does this behave differently?
Can someone explain me this?
NOTE: I deactivated tCache as I suspected the issue there, but the pointer looks also weird like this with tCache enabled.
EDIT: same with tCache enabled:
gef➤ heap bins
───────────────────────────────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=0, size=0x20, count=1] ← Chunk(addr=0x585b8f74fe00, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
Tcachebins[idx=9, size=0xb0, count=1] ← Chunk(addr=0x585b8f74fd20, size=0xb0, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
Tcachebins[idx=28, size=0x1e0, count=1] ← Chunk(addr=0x585b8f74f2a0, size=0x1e0, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
─────────────────────────────────────────────────────────────────────────────────────────────────── Fastbins for arena at 0x7d7cab203ac0 ───────────────────────────────────────────────────────────────────────────────────────────────────
Fastbins[idx=0, size=0x20] 0x00
Fastbins[idx=1, size=0x30] 0x00
Fastbins[idx=2, size=0x40] 0x00
Fastbins[idx=3, size=0x50] 0x00
Fastbins[idx=4, size=0x60] 0x00
Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
───────────────────────────────────────────────────────────────────────────────────────────────── Unsorted Bin for arena at 0x7d7cab203ac0 ─────────────────────────────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in unsorted bin.
────────────────────────────────────────────────────────────────────────────────────────────────── Small Bins for arena at 0x7d7cab203ac0 ──────────────────────────────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in 0 small non-empty bins.
────────────────────────────────────────────────────────────────────────────────────────────────── Large Bins for arena at 0x7d7cab203ac0 ──────────────────────────────────────────────────────────────────────────────────────────────────
[+] large_bins[91]: fw=0x585b8f74fe10, bk=0x585b8f74fe10
→ Chunk(addr=0x585b8f74fe20, size=0xb00, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[+] Found 1 chunks in 1 large non-empty bins.
gef➤ x/10gx 0x585b8f74fe00
0x585b8f74fe00: 0x0000000585b8f74f 0xac91c0b816fbc312
0x585b8f74fe10: 0x0000000000000000 0x0000000000000b01
0x585b8f74fe20: 0x00007d7cab2040d0 0x00007d7cab2040d0
0x585b8f74fe30: 0x0000585b8f74fe10 0x0000585b8f74fe10
0x585b8f74fe40: 0x0000000000000000 0x0000000000000000
gef➤ x/10gx 0x585b8f74fd20
0x585b8f74fd20: 0x0000000585b8f74f 0xac91c0b816fbc312
0x585b8f74fd30: 0x3232323231313131 0x3232323232323232
0x585b8f74fd40: 0x3232323232323232 0x3232323232323232
0x585b8f74fd50: 0x0000000032323232 0x6d6f682f00000000
0x585b8f74fd60: 0x0000726573752f65 0x0000000000000000
Similar behavior with the tCache. I suspect they just store the “assignment” without the last 3 bytes, to which heap they belong, but this is my own wild speculation. ^^