57 lines
2.4 KiB
C
57 lines
2.4 KiB
C
/*
|
|
* DIRTYFAIL — exploit_su.h
|
|
*
|
|
* V4bel-style page-cache shellcode injection against /usr/bin/su.
|
|
*
|
|
* Different chain than the /etc/passwd UID-flip exploits:
|
|
* - Targets /usr/bin/su's ELF entry point in the page cache
|
|
* - Plants ~48 bytes of x86_64 shellcode (setuid(0); setgid(0);
|
|
* execve("/bin/sh")) via 12 chained 4-byte writes
|
|
* - When /usr/bin/su is exec'd, kernel sets euid=0 (setuid bit on
|
|
* disk, unaffected by page-cache mods), dynamic linker resolves,
|
|
* control transfers to entry point → our shellcode → /bin/sh
|
|
*
|
|
* Mitigation profile vs. /etc/passwd flip:
|
|
* + Bypasses `pam_unix nullok` removal — no PAM dependency at all
|
|
* + Works even if password rotation policy enforces complex passwords
|
|
* - Crashes /usr/bin/su system-wide if shellcode is wrong (until
|
|
* drop_caches or reboot)
|
|
* - Stash-and-revert is the safety net: cleanup-su restores the
|
|
* original 48 bytes from /var/tmp/.dirtyfail-su.state.
|
|
*
|
|
* Architecture: x86_64 only for now. The shellcode is hardcoded for
|
|
* the SYSV amd64 syscall ABI. arm64/aarch64 would need a different
|
|
* shellcode blob and possibly a different entry-point fixup.
|
|
*
|
|
* Reference: V4bel/dirtyfrag's xfrm-ESP variant uses the same target
|
|
* file pattern with a different (4-byte) primitive. Theori's Xint
|
|
* disclosure uses /usr/bin/su as the canonical target.
|
|
*/
|
|
|
|
#ifndef DIRTYFAIL_EXPLOIT_SU_H
|
|
#define DIRTYFAIL_EXPLOIT_SU_H
|
|
|
|
#include "common.h"
|
|
|
|
/* End-to-end PoC: locate /usr/bin/su (or DIRTYFAIL_SU_PATH override),
|
|
* stash original entry-point bytes, plant shellcode, verify, and
|
|
* (if do_shell) invoke `su -` so the kernel exec's our hijacked
|
|
* /usr/bin/su as setuid root → shellcode runs → /bin/sh.
|
|
*
|
|
* `do_shell=false` runs the plant + verify + revert sequence — useful
|
|
* for testing the primitive without leaving the system in a broken
|
|
* state (su would otherwise be unusable until drop_caches). */
|
|
df_result_t exploit_su_shellcode(bool do_shell);
|
|
|
|
/* Restore /usr/bin/su's original entry-point bytes from
|
|
* /var/tmp/.dirtyfail-su.state and drop_caches to evict the modified
|
|
* page. Returns DF_OK on success, DF_TEST_ERROR if state file is
|
|
* missing or the on-disk file no longer matches. */
|
|
df_result_t cleanup_su_shellcode(void);
|
|
|
|
/* Used by --list-state. Returns true if /var/tmp/.dirtyfail-su.state
|
|
* is present (and prints a summary), false if absent. Side-effect free. */
|
|
bool exploit_su_list_state(void);
|
|
|
|
#endif
|