🚧🚧 Currently, under construct! 🚧🚧
Underscored names are not struct (unnnamed buf or something).
name | cache size | usage |
---|---|---|
tty_struct |
kmalloc-1024 | kbase leak, RIP hijack |
tty_fle_private |
kmalloc-32 | kheap leak |
poll_list, pollfd |
kmalloc-32 ~ 1024 | kheap leak, arbitrary address free |
user_key_payload |
kmalloc-32 ~ 1024 | arbitrary value write |
_setxattr |
kmalloc-32 ~ 1024 | arbitrary value write |
seq_operations |
kmalloc-32 | kbase leak, RIP hijack |
subprocess_info |
kmalloc-128 | kbase leak, RIP hijack |
Alloced when open("/dev/ptmx")
from kmalloc-1024
, freed when close("/dev/ptmx")
.
You can leak kbase by reading tty_struct.ops
, which points to ptmx_fops
.
You can control RIP by overwriting tty_struct.ops
.
tty_struct.magic
must be0x5401
, otherwise paranoia check fails.tty_struct.driver
must be valid kptr.- This is really useful structure for kROP. For detail, reefr to tty_struct.md.
- corjail from CoRCTF2022
- this would be the best example of
tty_struct
- this would be the best example of
- klibrary from 3kCTF 2021
- nutty from Union CTF 2021
- meowmeow from zer0pts CTF 2020
Alloced when open("/dev/ptmx")
from kmalloc-32
, freed when close("/dev/ptmx")
.
You can leak kheap(kmalloc-1024
) by reading tty_file_private.tty
, which points to tty_struct
.
- corjail from CoRCTF2022
struct poll_list * next; /* 0 8 */
int len; /* 8 4 */
struct pollfd entries[]; /* 12 0 */
Alloced when poll()
from kmalloc-32 ~ 1024
, based on the number of polled fd. Freed when poll()
finishes, regardless timer expiration or event trigger. poll_list
contains array of pollfd
inside it.
poll_list.next
forms linked list. They are kfreed when poll()
finishes in order of this linked list. If you can overwrite next
pointer, you can free arbitrary address, leading to potential UAF.
- corjail from CoRCTF2022
struct callback_head rcu; /* 0 16 */
short unsigned int datalen; /* 16 2 */
char data[]; /* 24 0 */
Alloced when add_key()
from kmalloc-32 ~ 1024
based on the size of data
, freed when keyctl_revoke(); keyctl_unlink()
by GC. User-given content is embedded in data
.
- First 16 bytes are not untouched til initialized.
user_key_payload.type
is freed by specific GC, so you have to wait for GC to free it after you revoke the key.- This syscall is prohibited in default docker seccomp filter.
- corjail from CoRCTF2022
Alloced when setxattr("file", "user.x", data, ...)
, freed right after the call. You can use it to write arbitrary value in almost arbitrary cache.
- The buffer is freed in the same path with allocation, so you can't use it for spray.
- Combining with structs which doesn't initialize itself, you can write arbitrary value in that struct.
- nutty from Union CTF 2021
- corjail from CoRCTF2022
- Spark from HITCON 2020
TBD
TBD
- SharedHouse from ASIS 2020 Quals
- Linux useful structures for pwn by ptrYudai