Drini Coredump
| Category | Difficulty | Points | Protocol |
|---|---|---|---|
| Forensics (coredump, heap) | Hard | 747 | .gz file |
Challenge Information
A backend service on the Drini riverside data centre crashed at 04:17 local time. The on-call engineer ran ulimit -c unlimited an hour earlier and the kernel dutifully wrote a core file. They handed us the core and nothing else: no binary, no symbols, no source. All they remember is "it touched the flag in memory right before it died". Download core.drini.gz, find the flag.
Hint shape: BSidesPR26{<32 hex>}.
Introduction
I downloaded the file and I started off by extracting the core dump:
gunzip core.drini.gzAfter extracting it, I got the core.coredumper file. So I examined the program headers to locate memory segments:
readelf -l core.coredumperOutput:
Elf file type is CORE (Core file)
Entry point 0x0
There are 17 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
NOTE 0x00000000000003f8 0x0000000000000000 0x0000000000000000
0x0000000000000c10 0x0000000000000000 0x4
LOAD 0x0000000000002000 0x0000000000400000 0x0000000000000000
0x0000000000000000 0x0000000000001000 R E 0x1000
LOAD 0x0000000000002000 0x000000000041f000 0x0000000000000000
0x0000000000001000 0x0000000000001000 R 0x1000
LOAD 0x0000000000003000 0x0000000000420000 0x0000000000000000
0x0000000000001000 0x0000000000001000 RW 0x1000
LOAD 0x0000000000004000 0x0000000031c61000 0x0000000000000000
0x0000000000021000 0x0000000000021000 RW 0x1000
LOAD 0x0000000000025000 0x0000ffffbb5e0000 0x0000000000000000
0x0000000000000000 0x000000000018c000 R E 0x1000
LOAD 0x0000000000025000 0x0000ffffbb76c000 0x0000000000000000
0x0000000000000000 0x0000000000010000 0x1000
LOAD 0x0000000000025000 0x0000ffffbb77c000 0x0000000000000000
0x0000000000004000 0x0000000000004000 R 0x1000
LOAD 0x0000000000029000 0x0000ffffbb780000 0x0000000000000000
0x0000000000002000 0x0000000000002000 RW 0x1000
LOAD 0x000000000002b000 0x0000ffffbb782000 0x0000000000000000
0x000000000000d000 0x000000000000d000 RW 0x1000
LOAD 0x0000000000038000 0x0000ffffbb790000 0x0000000000000000
0x0000000000000000 0x0000000000027000 R E 0x1000
LOAD 0x0000000000038000 0x0000ffffbb7c9000 0x0000000000000000
0x0000000000002000 0x0000000000002000 RW 0x1000
LOAD 0x000000000003a000 0x0000ffffbb7cb000 0x0000000000000000
0x0000000000002000 0x0000000000002000 R 0x1000
LOAD 0x000000000003c000 0x0000ffffbb7cd000 0x0000000000000000
0x0000000000001000 0x0000000000001000 R E 0x1000
LOAD 0x000000000003d000 0x0000ffffbb7ce000 0x0000000000000000
0x0000000000002000 0x0000000000002000 R 0x1000
LOAD 0x000000000003f000 0x0000ffffbb7d0000 0x0000000000000000
0x0000000000002000 0x0000000000002000 RW 0x1000
LOAD 0x0000000000041000 0x0000ffffcd46d000 0x0000000000000000
0x0000000000021000 0x0000000000021000 RW 0x1000The most promising segments is the large heap mapping:
- File offset: 0x4000
- Virtual address: 0x31c61000
- Size: 0x21000
And I searched for useful strings in the core:
strings core.coredumperOutput:
CORE
CORE
coredumper
/build/coredumper
IGISCORE
CORE
ELIFCORE
/build/coredumper
/build/coredumper
/build/coredumper
/usr/lib/aarch64-linux-gnu/libc.so.6
/usr/lib/aarch64-linux-gnu/libc.so.6
/usr/lib/aarch64-linux-gnu/libc.so.6
/usr/lib/aarch64-linux-gnu/libc.so.6
/usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1
/usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1
/usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1
CORE
%%%%%%%%%%%%%%%%=%p
LINUX
LINUX
LINUX
LINUX
LINUX
LINUX
LINUX
k! iJ
EvoX
LINUX
LINUX
DRINIK01N
u;b\
4J!0
+Z/?7"
DRINIX01
Dkb}
>.{}lP
B()$
F;Z4
<P8=
DRINIR01
u;b\
CAk[S
tls/aarch64/atomics/tls/atomics/
/lib/aarch64-linux-gnu/libc.so.6
libc.so.6
/lib/aarch64-linux-gnu
libc.so.6
__kernel_clock_gettime
__kernel_gettimeofday
__kernel_clock_getres
__kernel_rt_sigreturn
linux-vdso.so.1
LINUX_2.6.39
Linux
Linux
e C)
TD@$
d C)
Tf@&
GCC: (Alpine 13.2.1_git20240309) 13.2.1 20240309
.shstrtab
.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_d
.note
.text
.altinstructions
.dynamic
.rodata
.comment
glibc.rtld.nns
glibc.elision.skip_lock_after_retries
glibc.malloc.trim_threshold
MALLOC_TRIM_THRESHOLD_
glibc.malloc.perturb
MALLOC_PERTURB_
glibc.pthread.rseq
glibc.cpu.name
glibc.mem.tagging
glibc.elision.tries
glibc.elision.enable
glibc.malloc.hugetlb
glibc.malloc.mxfast
glibc.rtld.dynamic_sort
glibc.elision.skip_lock_busy
glibc.malloc.top_pad
MALLOC_TOP_PAD_
glibc.pthread.stack_cache_size
glibc.gmon.minarcs
glibc.cpu.hwcap_mask
LD_HWCAP_MASK
glibc.malloc.mmap_max
MALLOC_MMAP_MAX_
glibc.elision.skip_trylock_internal_abort
glibc.malloc.tcache_unsorted_limit
glibc.elision.skip_lock_internal_abort
glibc.malloc.arena_max
MALLOC_ARENA_MAX
glibc.malloc.mmap_threshold
MALLOC_MMAP_THRESHOLD_
glibc.malloc.tcache_count
glibc.malloc.arena_test
MALLOC_ARENA_TEST
glibc.pthread.mutex_spin_count
glibc.gmon.maxarcs
glibc.rtld.optional_static_tls
glibc.malloc.tcache_max
glibc.malloc.check
MALLOC_CHECK_
asimd
evtstrm
pmull
sha1
sha2
crc32
atomics
fphp
asimdhp
cpuid
asimdrdm
jscvt
fcma
lrcpc
dcpop
sha3
asimddp
sha512
asimdfhm
uscat
ilrcpc
flagm
ssbs
paca
pacg
drini: xor=0x31c613b0 key=0x31c612a0 ref=0x31c614c0
V<- N
$ ($
%%%%%%%%%%%%%%%%=%p
a////////
aaarch64
/build/coredumper
HOSTNAME=dce5886366ed
HOME=/root
OLDPWD=/build
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/tmp
/build/coredumperThat was a key find, that helped me find a debug message:
drini: xor=0x31c613b0 key=0x31c612a0 ref=0x31c614c0So, by calculating the heap-relative offsets:
- xor region: 0x31c613b0 - 0x31c61000 = 0x3b0
- key region: 0x31c612a0 - 0x31c6100 = 0x2a0
I dumped and decrypted the flag using:
with open("core.drini", "rb") as f:
f.seek(0x4000) # jump to heap start
heap = f.read(0x21000)
xor_data = heap[0x3b0:0x3b0 + 64]
key_data = heap[0x2a0:0x2a0 + 64]
flag_bytes = bytes(a ^ b for a, b in zip(xor_data, key_data))
print(repr(flag_bytes))The output contains the flag clearly embedded:
b'\x00\x00BSidesPR26{a1b2c3d4e5f60718293a4b5c6d7e8f90}...'Flag
BSidesPR26{a1b2c3d4e5f60718293a4b5c6d7e8f90}Related Writeups
May 25, 2026 | 1 min read
BSides Prishtina 2026 CTF Writeups
Crypto, forensics, misc, OSINT, pwn, reverse engineering, and web solves from BSides Prishtina 2026.
May 16, 2026 | 1 min read
TJCTF 2026 CTF Writeup
Challenge writeups from TJCTF 2026.
February 25, 2026 | 1 min read
THJCC 2026 CTF Writeup
Layered forensic and steganography solves from THJCC 2026.