Description
GEF+GDB version
gef➤ version
GEF: (Standalone)
Blob Hash(/home/user/.gef-a85368fc771dcbb4db2b41818781e182845015b9.py): 1a409c397646df9c0b8549d576cd7c7f8ec1ef47
SHA256(/home/user/.gef-a85368fc771dcbb4db2b41818781e182845015b9.py): f096ff3bf50df08dbbc698a919360014f86f1eea315011cdabebd72a30a5bce8
GDB: 11.2
GDB-Python: 3.9
Operating System
Linux 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 GNU/Linux
Describe the issue you encountered
Target binary:
user@LAPTOP-M65IV45R:~/binaryexploitation/level05_d$ file level05
level05: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.15, BuildID[sha1]=2cf47809a1a841f6990910071c09e6053e9f57ac, with debug_info, not stripped
Fusion VM:
fusion@fusion:~$ uname -a
Linux fusion 3.0.0-13-generic-pae #22-Ubuntu SMP Wed Nov 2 15:17:35 UTC 2011 i686 i686 i386 GNU/Linux
fusion@fusion:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 11.10
Release: 11.10
Codename: oneiric
fusion@fusion:~$ ldd --version
ldd (Ubuntu EGLIBC 2.13-20ubuntu5) 2.13
Host VM:
user@LAPTOP-M65IV45R:~/binaryexploitation/level05_d$ uname -a
Linux LAPTOP-M65IV45R 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 GNU/Linux
user@LAPTOP-M65IV45R:~/binaryexploitation/level05_d$ ldd --version
ldd (Debian GLIBC 2.31-13+deb11u5) 2.31
During examination of heap chunks the heap commands works unexpectially and doesn't recognize any allocated chunks.
Do you read the docs and look at previously closed issues/PRs for similar cases?
Yes
Architecture impacted
- X86
- X64
- ARM
- ARM64
- MIPS
- MIPS64
- PPC
- PPC64
- RISCV
Describe your issue. Without a proper reproduction step-by-step, your issue will be ignored.
Provide a step-by-step to reproduce your issue.
REMOTE ENVIRONMENT (32 BIT):
1. Setup environment.
Fusion VM:
fusion@fusion:~$ sudo gdbserver :1234 --attach 1424 [sudo] password for fusion: Attached; pid = 1424 Listening on port 1234
Host VM:
user@LAPTOP-M65IV45R:~/binaryexploitation/level05_d$ gdb
0.00ms using Python engine 3.9
gef➤ file level05
Reading symbols from level05...
gef➤ gef-remote 192.168.56.113 1234
Reading /lib/i386-linux-gnu/libc.so.6 from remote target...
[... snip ... ]
Code:
0xb777c421 <__kernel_vsyscall+13> nop
0xb777c422 <__kernel_vsyscall+14> int 0x80
→ 0xb777c424 <__kernel_vsyscall+16> pop ebp
0xb777c425 <__kernel_vsyscall+17> pop edx
0xb777c426 <__kernel_vsyscall+18> pop ecx
0xb777c427 <__kernel_vsyscall+19> ret
0xb777c428 add BYTE PTR [esi], ch
0xb777c42a jae 0xb777c494
Threads:
[#0] Id 1, stopped 0xb777c424 in __kernel_vsyscall (), reason: SIGTRAP
Trace:
[#0] 0xb777c424 → __kernel_vsyscall()
[#1] 0xb76b73ce → poll()
[#2] 0xb779fa8d → fdtask(v=0x0)
[#3] 0xb77a1396 → taskstart(y=0xb9746110, x=0x0)
[#4] 0xb76315ab → makecontext()
[#5] 0xb9746110 → data16 fs je 0xb9746175
2. Interact with code
Connect to target binary and perform two commands which uses calloc and strdup to allocate memory. Perform this a couple of times
user@LAPTOP-M65IV45R:~$ nc 192.168.56.113 20005
** welcome to level05 **
isup CHUNK1garbagedata
isup CHUNK2garbagedata
isup CHUNK3garbagedata
3. Examine heap
gef➤ vmmap
[ Legend: Code | Heap | Stack ]
Start End Offset Perm Path
0x56647000 0x56649000 0x00000000 r-- /home/user/binaryexploitation/level05_d/a.out
0x56649000 0x5664c000 0x00002000 r-x /home/user/binaryexploitation/level05_d/a.out
0x5664c000 0x5664d000 0x00005000 r-- /home/user/binaryexploitation/level05_d/a.out
0x5664d000 0x5664e000 0x00006000 rw- /home/user/binaryexploitation/level05_d/a.out
0x5664e000 0x56651000 0x00000000 rw-
0x585d0000 0x585f2000 0x00000000 rw- [heap]
(remote) gef➤ search-pattern "CHUNK1"
[+] Searching 'CHUNK1' in memory
[+] In '[heap]'(0xb9746000-0xb9767000), permission=rw-
0xb9756860 - 0xb9756871 → "CHUNK1garbagedata"
(remote) gef➤ search-pattern "CHUNK2"
[+] Searching 'CHUNK2' in memory
[+] In '[heap]'(0xb9746000-0xb9767000), permission=rw-
0xb9756888 - 0xb9756899 → "CHUNK2garbagedata"
(remote) gef➤ search-pattern "CHUNK3"
[+] Searching 'CHUNK3' in memory
[+] In '[heap]'(0xb9746000-0xb9767000), permission=rw-
0xb97565c5 - 0xb97565d6 → "CHUNK3garbagedata"
0xb97568b0 - 0xb97568c1 → "CHUNK3garbagedata"
(remote) gef➤ heap chunks
[!] Invalid arena
(remote) gef➤ heap arena
(remote) gef➤ heap chunks -a
[!] Invalid arena
(remote) gef➤ heap chunk 0xb97568b0
Chunk(addr=0xb97568b0, size=0x18, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
Chunk size: 24 (0x18)
Usable size: 20 (0x14)
Previous chunk size: 0 (0x0)
PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA
LOCAL ENVIRONMENT (32 BIT):
In this setup I've ported the source code made the nessecary code adjusements and compiled the source code on my host VM using a newer versions of LIBC.
In this setup the binary is running locally on the host VM with the specifications shown earlier.
The same GDB setup is used, however skipping remote debug and attaching directly to the running binary using its PID. The interaction with the binary is identical to that of the remote.
Target binary:
user@LAPTOP-M65IV45R:~/binaryexploitation/level05_d$ file a.out
a.out: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=84c2e6f3ea4145a586430172545fbc1d750c1af6, for GNU/Linux 3.2.0, with debug_info, not stripped
[+] Searching 'CHUNK1' in memory
[+] In '[heap]'(0x585d0000-0x585f2000), permission=rw-
0x585e0a00 - 0x585e0a11 → "CHUNK1garbagedata"
gef➤ search-pattern "CHUNK2"
[+] Searching 'CHUNK2' in memory
[+] In '[heap]'(0x585d0000-0x585f2000), permission=rw-
0x585e0a30 - 0x585e0a41 → "CHUNK2garbagedata"
gef➤ search-pattern "CHUNK3"
[+] Searching 'CHUNK3' in memory
[+] In '[heap]'(0x585d0000-0x585f2000), permission=rw-
0x585e0761 - 0x585e0772 → "CHUNK3garbagedata"
0x585e0a60 - 0x585e0a71 → "CHUNK3garbagedata"
gef➤ heap chunks
Chunk(addr=0x585d0010, size=0x0, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x585d0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................]
gef➤ heap arena
Arena(base=0xf7f26740, top=0x585e0a78, last_remainder=0x0, next=0xf7f26740)
gef➤ heap chunks -a
Arena(base=0xf7f26740, top=0x585e0a78, last_remainder=0x0, next=0xf7f26740)
Chunk(addr=0x585d0010, size=0x0, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x585d0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................]
[!] Invalid arena
gef➤ heap chunk 0x585e0a00
Chunk(addr=0x585e0a00, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
Chunk size: 32 (0x20)
Usable size: 28 (0x1c)
Previous chunk size: 0 (0x0)
PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA
gef➤ heap chunk 0x585e0a30
Chunk(addr=0x585e0a30, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
Chunk size: 32 (0x20)
Usable size: 28 (0x1c)
Previous chunk size: 0 (0x0)
PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA
gef➤ heap chunk 0x585e0a60
Chunk(addr=0x585e0a60, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
Chunk size: 32 (0x20)
Usable size: 28 (0x1c)
Previous chunk size: 0 (0x0)
PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA
gef➤ x/i 0xf7f26740
0xf7f26740: add BYTE PTR [eax],al
LOCAL ENVIRONMENT (64 BIT)
Reproduce the previous setup steps for LOCAL ENVIRONMENT 32 BIT.
Instead targeting a 64-bit compiled version.
Target binary:
user@LAPTOP-M65IV45R:~/binaryexploitation/level05_d$ file a64.out
a64.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=9efa6c2233190407fb27aefef0e577652c8a3fc1, for GNU/Linux 3.2.0, with debug_info, not stripped
The same commands are sent and the heap output works as expected.
Chunk(addr=0x564e6fda2010, size=0x290, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000564e6fda2010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................]
Chunk(addr=0x564e6fda22a0, size=0x210, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000564e6fda22a0 10 60 b1 84 3a 7f 00 00 b0 24 da 6f 4e 56 00 00 .`..:....$.oNV..]
Chunk(addr=0x564e6fda24b0, size=0x8640, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000564e6fda24b0 66 64 74 61 73 6b 00 00 00 00 00 00 00 00 00 00 fdtask..........]
Chunk(addr=0x564e6fdaaaf0, size=0x8640, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000564e6fdaaaf0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................]
Chunk(addr=0x564e6fdb3130, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000564e6fdb3130 04 00 00 00 00 00 00 00 50 31 db 6f 4e 56 00 00 ........P1.oNV..]
Chunk(addr=0x564e6fdb3150, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000564e6fdb3150 43 48 55 4e 4b 31 67 61 72 62 61 67 65 64 61 74 CHUNK1garbagedat]
Chunk(addr=0x564e6fdb3170, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000564e6fdb3170 04 00 00 00 00 00 00 00 90 31 db 6f 4e 56 00 00 .........1.oNV..]
Chunk(addr=0x564e6fdb3190, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000564e6fdb3190 43 48 55 4e 4b 32 67 61 72 62 61 67 65 64 61 74 CHUNK2garbagedat]
Chunk(addr=0x564e6fdb31b0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000564e6fdb31b0 04 00 00 00 00 00 00 00 d0 31 db 6f 4e 56 00 00 .........1.oNV..]
Chunk(addr=0x564e6fdb31d0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000564e6fdb31d0 43 48 55 4e 4b 33 67 61 72 62 61 67 65 64 61 74 CHUNK3garbagedat]
Chunk(addr=0x564e6fdb31f0, size=0xfe20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← top chunk
Minimalist test case
Use this field for a minimal code to compile and spot the issue:
// compile with gcc -fPIE -pic -o my_issue.out my_issue.c
int main(){ return 0; }
You can also provide a Dockerfile if you prefer
Additional context?
Challenge found here: http://exploit.education/fusion/level05/
Image for fusion found here: http://exploit.education/downloads/
Activity