We have previously covered this bug, its an out-of-bounds access due to a broken assumption in every
dup command having an associated immediate. When that assumption is broken by manually crafting netfilter rules
nft_fwd_dup_netdev_offload function will perform an out of bounds access as it increments too far.
Where the post covers new ground is in the exploit strategy.
entry = &flow->rule->action.entries[ctx->num_actions++]; entry->id = id; entry->dev = dev;
In the vulnerable code above the
entries array may be access out of bound, performing two writes the the
dev fields. The
dev field was the interesting one as that it writing a pointer to the
net_device structure. This provided two basic primitives depending on the rules being added (attacker controlled)
- Write at 24 bytes into the next block in kmalloc32 or 192 cache
- Write at 8 bytes into the next block in kmalloc128.
Unfortunately for the authors writes at these offsets didn’t seem too useful and he couldn’t find a good target for the write. However by performing the attack multiple times, he could write another 80bytes head, in kmalloc128, this goes from an offset of 8 to 88 to 40 (168 mod 128). That 40 byte offset he realized after reading Alexander Popov’s Four Bytes of Power exploit aligns with
security pointer in a
security field leads to an arbitrary free primitive when the
msg_msg is received (attacker controlled) so if exploited in this scenario it would free the
net_device. Leading to a more complete attack chain:
- Spray System V message queue messages (
struct msg_msg) of a size to fit in kmalloc128
- Free some of the messages by recieving them
- Add a malicious netlink rule, trying to reuse one of these freed
- Perform the OOB access three times, overwriting the among other things the
securitypointer of one of these messages
- Scan the messages for ones that have had their data corrupted to find the corrupted messages.
- Free the message with a corrupted
securitypointer, causing a free of the
- Spray more messages this time of a size to fit in kmalloc4096, hopefully taking over the freed
- Above control of the
net_deviceto overwrite some of the
netsec_opsfunction pointers for control flow hijacking