diff --git a/src/binary-exploitation/libc-heap/house-of-orange.md b/src/binary-exploitation/libc-heap/house-of-orange.md index b1c18ade18c..c39fc1ead40 100644 --- a/src/binary-exploitation/libc-heap/house-of-orange.md +++ b/src/binary-exploitation/libc-heap/house-of-orange.md @@ -8,7 +8,7 @@ - Find an example in [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c) - The exploitation technique was fixed in this [patch](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=stdlib/abort.c;h=117a507ff88d862445551f2c07abb6e45a716b75;hp=19882f3e3dc1ab830431506329c94dcf1d7cc252;hb=91e7cf982d0104f0e71770f5ae8e3faf352dea9f;hpb=0c25125780083cbba22ed627756548efe282d1a0) so this is no longer working (working in earlier than 2.26) -- Same example **with more comments** in [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html) +- Same example **with more comments** in [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)[[2]](#references) ### Goal @@ -21,7 +21,7 @@ ### Background -Some needed background from the comments from [**this example**](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)**:** +Some needed background from the comments from [**this example**](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)**:**[[2]](#references) Thing is, in older versions of libc, when the `malloc_printerr` function was called it would **iterate through a list of `_IO_FILE` structs stored in `_IO_list_all`**, and actually **execute** an instruction pointer in that struct.\ This attack will forge a **fake `_IO_FILE` struct** that we will write to **`_IO_list_all`**, and cause `malloc_printerr` to run.\ @@ -29,13 +29,13 @@ Then it will **execute whatever address** we have stored in the **`_IO_FILE`** s ### Attack -The attack starts by managing to get the **top chunk** inside the **unsorted bin**. This is achieved by calling `malloc` with a size greater than the current top chunk size but smaller than **`mmp_.mmap_threshold`** (default is 128K), which would otherwise trigger `mmap` allocation. Whenever the top chunk size is modified, it's important to ensure that the **top chunk + its size** is page-aligned and that the **prev_inuse** bit of the top chunk is always set.[[1]](#references) +The attack starts by managing to get the **top chunk** inside the **unsorted bin**. This is achieved by calling `malloc` with a size greater than the current top chunk size but smaller than **`mmp_.mmap_threshold`** (default is 128K), which would otherwise trigger `mmap` allocation. Whenever the top chunk size is modified, it's important to ensure that the **top chunk + its size** is page-aligned and that the **prev_inuse** bit of the top chunk is always set. -To get the top chunk inside the unsorted bin, allocate a chunk to create the top chunk, change the top chunk size (with an overflow in the allocated chunk) so that **top chunk + size** is page-aligned with the **prev_inuse** bit set. Then allocate a chunk larger than the new top chunk size. Note that `free` is never called to get the top chunk into the unsorted bin. +To get the top chunk inside the unsorted bin, allocate a chunk to create the top chunk, change the top chunk size (with an overflow in the allocated chunk) so that **top chunk + size** is page-aligned with the **prev_inuse** bit set. Then allocate a chunk larger than the new top chunk size. Note that `free` is never called to get the top chunk into the unsorted bin.[[1]](#references) The old top chunk is now in the unsorted bin. Assuming we can read data inside it (possibly due to a vulnerability that also caused the overflow), it’s possible to leak libc addresses from it and get the address of **\_IO_list_all**. -An unsorted bin attack is performed by abusing the overflow to write `topChunk->bk->fwd = _IO_list_all - 0x10`. When a new chunk is allocated, the old top chunk will be split, and a pointer to the unsorted bin will be written into **`_IO_list_all`**. +An unsorted bin attack is performed by abusing the overflow to write `topChunk->bk->fwd = _IO_list_all - 0x10`. When a new chunk is allocated, the old top chunk will be split, and a pointer to the unsorted bin will be written into **`_IO_list_all`**.[[2]](#references) The next step involves shrinking the size of the old top chunk to fit into a small bin, specifically setting its size to **0x61**. This serves two purposes: @@ -69,7 +69,7 @@ This approach exploits heap management mechanisms, libc information leaks, and h ## References -- [1] [CTF-wiki - House of Orange](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/) -- [2] [Nightmare - House of Orange (guyinatuxedo)](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html) +- [1] [House of Orange - CTF Wiki](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/) +- [2] [House of Orange exploitation walkthrough - guyinatuxedo](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/house-of-rabbit.md b/src/binary-exploitation/libc-heap/house-of-rabbit.md index 1e388b2c76f..c34cc00fa33 100644 --- a/src/binary-exploitation/libc-heap/house-of-rabbit.md +++ b/src/binary-exploitation/libc-heap/house-of-rabbit.md @@ -16,7 +16,7 @@ ### POC 1: Modify the size of a fast bin chunk -**Objective**: Create an overlapping chunk by manipulating the size of a fastbin chunk. +**Objective**: Create an overlapping chunk by manipulating the size of a fastbin chunk.[[1]](#references)[[2]](#references) - **Step 1: Allocate Chunks** @@ -57,7 +57,7 @@ After consolidation, `chunk1` overlaps with `chunk2`, allowing for further explo ### POC 2: Modify the `fd` pointer -**Objective**: Create a fake chunk by manipulating the fast bin `fd` pointer. +**Objective**: Create a fake chunk by manipulating the fast bin `fd` pointer.[[1]](#references)[[2]](#references) - **Step 1: Allocate Chunks** @@ -108,7 +108,9 @@ The fake chunk becomes part of the fastbin list, making it a legitimate chunk fo The **House of Rabbit** technique involves either modifying the size of a fast bin chunk to create overlapping chunks or manipulating the `fd` pointer to create fake chunks. This allows attackers to forge legitimate chunks in the heap, enabling various forms of exploitation. Understanding and practicing these steps will enhance your heap exploitation skills. -{{#include ../../banners/hacktricks-training.md}} - +## References +- [1] [House_of_Rabbit - shift-crops (original technique/PoC)](https://github.com/shift-crops/House_of_Rabbit) +- [2] [House of Rabbit - CTF Wiki EN](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_rabbit/) +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/large-bin-attack.md b/src/binary-exploitation/libc-heap/large-bin-attack.md index 58e827431ba..c7045cf2fc9 100644 --- a/src/binary-exploitation/libc-heap/large-bin-attack.md +++ b/src/binary-exploitation/libc-heap/large-bin-attack.md @@ -15,7 +15,7 @@ It's possible to find a great example in [**how2heap - large bin attack**](https Basically here you can see how, in the latest "current" version of glibc (2.35), it's not checked: **`P->bk_nextsize`** allowing to modify an arbitrary address with the value of a large bin chunk if certain conditions are met. -In that example you can find the following conditions: +In that example you can find the following conditions:[[1]](#references) - A large chunk is allocated - A large chunk smaller than the first one but in the same index is allocated @@ -52,14 +52,14 @@ You can find another great explanation of this attack in [**guyinatuxedo**](http ### Other examples - [**La casa de papel. HackOn CTF 2024**](https://7rocky.github.io/en/ctf/other/hackon-ctf/la-casa-de-papel/)[[3]](#references) - - Large bin attack in the same situation as it appears in [**how2heap**](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/large_bin_attack.c). + - Large bin attack in the same situation as it appears in [**how2heap**](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/large_bin_attack.c).[[1]](#references) - The write primitive is more complex, because `global_max_fast` is useless here. - FSOP is needed to finish the exploit. ## References -- [1] [how2heap - large bin attack](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/large_bin_attack.c) -- [2] [guyinatuxedo - Large Bin Attack explanation](https://guyinatuxedo.github.io/32-largebin_attack/largebin_explanation0/index.html) -- [3] [La casa de papel. HackOn CTF 2024](https://7rocky.github.io/en/ctf/other/hackon-ctf/la-casa-de-papel/) +- [1] [how2heap - large_bin_attack.c (glibc 2.35)](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/large_bin_attack.c) +- [2] [Large Bin Attack explanation - guyinatuxedo](https://guyinatuxedo.github.io/32-largebin_attack/largebin_explanation0/index.html) +- [3] [La casa de papel. HackOn CTF 2024 - 7rocky](https://7rocky.github.io/en/ctf/other/hackon-ctf/la-casa-de-papel/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/linux-kernel-exploitation/ksmbd-streams_xattr-oob-write-cve-2025-37947.md b/src/binary-exploitation/linux-kernel-exploitation/ksmbd-streams_xattr-oob-write-cve-2025-37947.md index 62e8d0126b6..e9ea2f9d7d1 100644 --- a/src/binary-exploitation/linux-kernel-exploitation/ksmbd-streams_xattr-oob-write-cve-2025-37947.md +++ b/src/binary-exploitation/linux-kernel-exploitation/ksmbd-streams_xattr-oob-write-cve-2025-37947.md @@ -23,7 +23,7 @@ Root cause (allocation clamped, memcpy at unclamped offset) Why the write offset matters - The vulnerable path is not just "write more than 64KiB". The missing check was that `*pos` was not validated against the current stream length (`v_len`) before the append/copy logic ran. -- Upstream fixed this by rejecting writes where `*pos >= v_len` with `-EINVAL`. Pre-fix, an attacker could reuse a valid authenticated handle to a named stream and send a raw SMB2 WRITE whose `file_offset` already points at or past the end of the existing stream, which turns the post-clamp `memcpy()` into a deterministic page overflow.[[1]](#references)[[2]](#references) +- Upstream fixed this by rejecting writes where `*pos >= v_len` with `-EINVAL`.[[2]](#references) Pre-fix, an attacker could reuse a valid authenticated handle to a named stream and send a raw SMB2 WRITE whose `file_offset` already points at or past the end of the existing stream, which turns the post-clamp `memcpy()` into a deterministic page overflow. - The public PoC demonstrates this by authenticating with `libsmb2`, opening a stream path such as `1337:`, extracting `SessionId`/`TreeId`/`FileId`, and then sending a handcrafted SMB2 WRITE with `file_offset = 0x10018` and a small `Length`.[[1]](#references)[[3]](#references)
@@ -53,12 +53,12 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
Offset steering and OOB length -- Example: set file offset (pos) to 0x10018 and original length (count) to 8. After clamping, count' = (0x10018 + 8) - 0x10000 = 0x20, but memcpy writes 32 bytes starting at stream_buf[0x10018], i.e., 0x18 bytes beyond the 16-page allocation. +- Example: set file offset (pos) to 0x10018 and original length (count) to 8. After clamping, count' = (0x10018 + 8) - 0x10000 = 0x20, but memcpy writes 32 bytes starting at stream_buf[0x10018], i.e., 0x18 bytes beyond the 16-page allocation.[[1]](#references) Triggering the bug via SMB streams write - Use the same authenticated SMB connection to open a file on the share and issue a write to a named stream (streams_xattr). Set file_offset ≥ 0x10000 with a small length to generate a deterministic OOB write of controllable size. - libsmb2 can be used to authenticate and craft such writes over SMB2/3. -- In practice, reusing the negotiated SMB session is convenient because the exploit only needs to patch a few dynamic fields in the WRITE request (`TreeId`, `SessionId`, `FileId`) and can then transmit the malformed packet directly on the same socket. +- In practice, reusing the negotiated SMB session is convenient because the exploit only needs to patch a few dynamic fields in the WRITE request (`TreeId`, `SessionId`, `FileId`) and can then transmit the malformed packet directly on the same socket.[[1]](#references)[[3]](#references) Minimal reachability (concept) ```c @@ -71,12 +71,12 @@ smb2_pwrite(fd, payload, 8, 0x0000010018ULL); // yields 32-byte OOB Allocator behavior and why page shaping is required - kvmalloc(0x10000, GFP_KERNEL|__GFP_ZERO) requests an order-4 (16 contiguous pages) allocation from the buddy allocator when size > KMALLOC_MAX_CACHE_SIZE. This is not a SLUB cache object. - memcpy occurs immediately after allocation; post-allocation spraying is ineffective. You must pre-groom physical memory so that a chosen target lies immediately after the allocated 16-page block. -- On Ubuntu, GFP_KERNEL often pulls from the Unmovable migrate type in zone Normal. Exhaust order-3 and order-4 freelists to force the allocator to split an order-5 block into an adjacent order-4 + order-3 pair, then park an order-3 slab (kmalloc-cg-4k) directly after the stream buffer. +- On Ubuntu, GFP_KERNEL often pulls from the Unmovable migrate type in zone Normal. Exhaust order-3 and order-4 freelists to force the allocator to split an order-5 block into an adjacent order-4 + order-3 pair, then park an order-3 slab (kmalloc-cg-4k) directly after the stream buffer.[[1]](#references) Practical page shaping strategy - Spray ~1000–2000 msg_msg objects of ~4096 bytes (fits kmalloc-cg-4k) to populate order-3 slabs. - Receive some messages to punch holes and encourage adjacency. -- Trigger the ksmbd OOB repeatedly until the order-4 stream buffer lands immediately before a msg_msg slab. Use eBPF tracing to confirm addresses and alignment if available. +- Trigger the ksmbd OOB repeatedly until the order-4 stream buffer lands immediately before a msg_msg slab. Use eBPF tracing to confirm addresses and alignment if available.[[1]](#references) Useful observability ```bash @@ -89,9 +89,9 @@ sudo ./bpf-tracer.sh What to trace while tuning - `kvmalloc_node(0x10000)` confirms when the vulnerable stream write actually consumes an order-4 allocation. - `load_msg`/`kretprobe:load_msg` lets you estimate how many `msg_msgseg` allocations are attached to each sprayed message, which is useful when tuning primary/secondary message sizes for a specific kernel build. -- If the exploit is ported to a different distro/kernel, re-check cache names, inline `msg_msg` payload sizes, `anon_pipe_buf_ops` offsets, and gadget addresses rather than assuming the Ubuntu 22.04 LTS `5.15.0-153-generic` constants still match. +- If the exploit is ported to a different distro/kernel, re-check cache names, inline `msg_msg` payload sizes, `anon_pipe_buf_ops` offsets, and gadget addresses rather than assuming the Ubuntu 22.04 LTS `5.15.0-153-generic` constants still match.[[1]](#references) -Exploitation plan (msg_msg + pipe_buffer), adapted from CVE-2021-22555[[1]](#references) +Exploitation plan (msg_msg + pipe_buffer), adapted from CVE-2021-22555 1) Spray many System V msg_msg primary/secondary messages (4KiB-sized to fit kmalloc-cg-4k). 2) Trigger ksmbd OOB to corrupt a primary message’s next pointer so that two primaries share one secondary. 3) Detect the corrupted pair by tagging queues and scanning with msgrcv(MSG_COPY) to find mismatched tags. @@ -99,15 +99,15 @@ Exploitation plan (msg_msg + pipe_buffer), adapted from CVE-2021-22555[[1]] 5) Leak kernel heap pointers by abusing m_ts over-read in copy_msg to obtain mlist.next/mlist.prev (SMAP bypass). 6) With an sk_buff spray, rebuild a consistent fake msg_msg with valid links and free it normally to stabilize state. 7) Reclaim the UAF with struct pipe_buffer objects; leak anon_pipe_buf_ops to compute kernel base (defeat KASLR). -8) Spray a fake pipe_buf_operations with release pointing to a stack pivot/ROP gadget; close pipes to execute and gain root. +8) Spray a fake pipe_buf_operations with release pointing to a stack pivot/ROP gadget; close pipes to execute and gain root.[[1]](#references) Bypasses and notes - KASLR: leak anon_pipe_buf_ops, compute base (kbase_addr) and gadget addresses. - SMEP/SMAP: execute ROP in kernel context via pipe_buf_operations->release flow; avoid userspace derefs until after disable/prepare_kernel_cred/commit_creds chain. -- Hardened usercopy: not applicable to this page overflow primitive; corruption targets are non-usercopy fields. +- Hardened usercopy: not applicable to this page overflow primitive; corruption targets are non-usercopy fields.[[1]](#references) Reliability -- High once adjacency is achieved; occasional misses or panics (<10%). Tuning spray/free counts improves stability. Overwriting two LSBs of a pointer to induce specific collisions was reported as effective (e.g., write 0x0000_0000_0000_0500 pattern into the overlap). +- High once adjacency is achieved; occasional misses or panics (<10%). Tuning spray/free counts improves stability. Overwriting two LSBs of a pointer to induce specific collisions was reported as effective (e.g., write 0x0000_0000_0000_0500 pattern into the overlap).[[1]](#references) Key parameters to tune - Number of msg_msg sprays and hole pattern @@ -116,7 +116,7 @@ Key parameters to tune Mitigations and reachability - Fix: clamp both allocation and destination/length or bound memcpy against the allocated size; upstream patches track as CVE-2025-37947.[[2]](#references) -- Remote exploitation would additionally require a reliable infoleak and remote heap grooming; this write-up focuses on local LPE. +- Remote exploitation would additionally require a reliable infoleak and remote heap grooming; this write-up focuses on local LPE.[[1]](#references) See also @@ -130,6 +130,7 @@ References PoC and tooling - Minimal reachability PoC and full local exploit are publicly available (see References) ## References + - [1] [ksmbd - Exploiting CVE-2025-37947 (3/3) — Doyensec](https://blog.doyensec.com/2025/10/08/ksmbd-3.html) - [2] [Linux upstream fix: `ksmbd: prevent out-of-bounds stream writes by validating *pos`](https://github.com/torvalds/linux/commit/0ca6df4f40cf4c32487944aaf48319cb6c25accc) - [3] [KSMBD-CVE-2025-37947 PoC repository](https://github.com/doyensec/KSMBD-CVE-2025-37947) diff --git a/src/binary-exploitation/linux-kernel-exploitation/pixel-bigwave-bigo-job-timeout-uaf-kernel-write.md b/src/binary-exploitation/linux-kernel-exploitation/pixel-bigwave-bigo-job-timeout-uaf-kernel-write.md index e9ee87c07bc..fc8d85c02d6 100644 --- a/src/binary-exploitation/linux-kernel-exploitation/pixel-bigwave-bigo-job-timeout-uaf-kernel-write.md +++ b/src/binary-exploitation/linux-kernel-exploitation/pixel-bigwave-bigo-job-timeout-uaf-kernel-write.md @@ -4,9 +4,9 @@ ## TL;DR -- From the SELinux-confined **mediacodec** context, `/dev/bigwave` (Pixel AV1 hardware accelerator) is reachable. A backlog of jobs makes `BIGO_IOCX_PROCESS` hit its **16s wait_for_completion_timeout()** and return while the worker thread concurrently dequeues the same inline `job` structure. -- Closing the FD immediately frees `struct bigo_inst` (which embeds `struct bigo_job`). The worker reconstructs `inst = container_of(job, ...)` and later uses freed fields such as **`job->regs`** inside `bigo_run_job()`, yielding a **Use-After-Free on the inline job/inst**. -- `bigo_pull_regs(core, job->regs)` performs `memcpy_fromio(regs, core->base, core->regs_size)`. By reclaiming the freed slab and overwriting `job->regs`, an attacker gets a **~2144-byte arbitrary kernel write** to a chosen address, with partial control of the bytes by pre-programming register values before the timeout.[[1]](#references) +- From the SELinux-confined **mediacodec** context, `/dev/bigwave` (Pixel AV1 hardware accelerator) is reachable. A backlog of jobs makes `BIGO_IOCX_PROCESS` hit its **16s wait_for_completion_timeout()** and return while the worker thread concurrently dequeues the same inline `job` structure.[[1]](#references)[[2]](#references) +- Closing the FD immediately frees `struct bigo_inst` (which embeds `struct bigo_job`). The worker reconstructs `inst = container_of(job, ...)` and later uses freed fields such as **`job->regs`** inside `bigo_run_job()`, yielding a **Use-After-Free on the inline job/inst**.[[1]](#references)[[2]](#references) +- `bigo_pull_regs(core, job->regs)` performs `memcpy_fromio(regs, core->base, core->regs_size)`. By reclaiming the freed slab and overwriting `job->regs`, an attacker gets a **~2144-byte arbitrary kernel write** to a chosen address, with partial control of the bytes by pre-programming register values before the timeout.[[1]](#references)[[2]](#references) - Tracked as **CVE-2025-36934**; fixed in the **2026-01-05 Pixel/2025-12-01 ASB** builds.[[3]](#references) ## Attack surface mapping (SELinux → /dev reachability) @@ -54,7 +54,7 @@ sleep(1); // let worker memcpy_fr ## Related successor primitive on Pixel 10: unbounded `/dev/vpu` `mmap()` → physical-memory R/W -Project Zero's Pixel 10 follow-up replaced BigWave with another **mediacodec-reachable** driver: `/dev/vpu` for the **Chips&Media Wave677DV** decoder. The bug class is even shallower: the driver intends to expose only the VPU MMIO CSR window, but its `mmap` handler trusts the attacker-controlled VMA length.[[4]](#references) +Project Zero's Pixel 10 follow-up replaced BigWave with another **mediacodec-reachable** driver: `/dev/vpu` for the **Chips&Media Wave677DV** decoder. The bug class is even shallower: the driver intends to expose only the VPU MMIO CSR window, but its `mmap` handler trusts the attacker-controlled VMA length.[[4]](#references)[[5]](#references) ```c static int vpu_mmap(struct file *fp, struct vm_area_struct *vm) @@ -73,7 +73,7 @@ static int vpu_mmap(struct file *fp, struct vm_area_struct *vm) - The mapped length is **`vm->vm_end - vm->vm_start`**, i.e. the user-requested `mmap()` size. - There is **no check** that the requested size is bounded by the real MMIO resource length. -Therefore, if `/dev/vpu` is reachable from a compromised app/service domain, a large `mmap()` does not stop at the register window: it keeps mapping the **contiguous physical pages after the VPU MMIO range** into userspace.[[4]](#references)[[5]](#references) +Therefore, if `/dev/vpu` is reachable from a compromised app/service domain, a large `mmap()` does not stop at the register window: it keeps mapping the **contiguous physical pages after the VPU MMIO range** into userspace.[[4]](#references) ### Exploitation model @@ -81,7 +81,7 @@ Therefore, if `/dev/vpu` is reachable from a compromised app/service domain, a l 2. `open("/dev/vpu", O_RDWR)`. 3. `mmap()` a region much larger than the real CSR/MMIO window. 4. Compute the offset from the returned mapping to the kernel physical base. -5. Read or overwrite kernel `.text`, `.data`, credentials, function pointers, or build a more convenient arbitrary R/W primitive. +5. Read or overwrite kernel `.text`, `.data`, credentials, function pointers, or build a more convenient arbitrary R/W primitive.[[4]](#references) Representative pattern: @@ -100,7 +100,7 @@ uint8_t *kbase = (uint8_t *)map + (KERNEL_PHYS_BASE - VPU_PHYS_BASE); arm64-static-linear-map-kaslr-bypass.md {{#endref}} -- Compared with the earlier BigWave UAF, this bug skips heap feng shui almost entirely: once the oversized mapping succeeds, the attacker gets **direct userspace access to kernel physical memory**.[[4]](#references) +- Compared with the earlier BigWave UAF, this bug skips heap feng shui almost entirely: once the oversized mapping succeeds, the attacker gets **direct userspace access to kernel physical memory**.[[4]](#references)[[5]](#references) - Review pattern: any driver that exposes MMIO via `remap_pfn_range()` must clamp `requested_len <= resource_size`, align offsets carefully, and reject arbitrary expansion beyond the device BAR/resource. ## Takeaways for driver reviewers diff --git a/src/binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md b/src/binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md index c41539bf4c1..842dc52cdac 100644 --- a/src/binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md +++ b/src/binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md @@ -2,14 +2,14 @@ {{#include ../../banners/hacktricks-training.md}} -This page documents a TOCTOU race condition in Linux/Android POSIX CPU timers that can corrupt timer state and crash the kernel, and under some circumstances be steered toward privilege escalation.[[1]](#references)[[5]](#references)[[6]](#references)[[7]](#references) +This page documents a TOCTOU race condition in Linux/Android POSIX CPU timers that can corrupt timer state and crash the kernel, and under some circumstances be steered toward privilege escalation.[[1]](#references)[[5]](#references) - Affected component: kernel/time/posix-cpu-timers.c - Primitive: expiry vs deletion race under task exit - Config sensitive: CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n (IRQ-context expiry path) Quick internals recap (relevant for exploitation) -- Three CPU clocks drive accounting for timers via cpu_clock_sample(): +- Three CPU clocks drive accounting for timers via cpu_clock_sample():[[1]](#references)[[5]](#references) - CPUCLOCK_PROF: utime + stime - CPUCLOCK_VIRT: utime only - CPUCLOCK_SCHED: task_sched_runtime() @@ -147,11 +147,11 @@ Sequence 2) collect_timerqueue() sets ctmr->firing = 1 and moves the timer to the temporary firing list. 3) handle_posix_cpu_timers() drops sighand via unlock_task_sighand() to deliver timers outside the lock. 4) Immediately after unlock, the exiting task can be reaped; a sibling thread executes posix_cpu_timer_del(). -5) In this window, posix_cpu_timer_del() may fail to acquire state via cpu_timer_task_rcu()/lock_task_sighand() and thus skip the normal in-flight guard that checks timer->it.cpu.firing. Deletion proceeds as if not firing, corrupting state while expiry is being handled, leading to crashes/UB.[[1]](#references) +5) In this window, posix_cpu_timer_del() may fail to acquire state via cpu_timer_task_rcu()/lock_task_sighand() and thus skip the normal in-flight guard that checks timer->it.cpu.firing. Deletion proceeds as if not firing, corrupting state while expiry is being handled, leading to crashes/UB.[[1]](#references)[[5]](#references) Why TASK_WORK mode is safe by design - With CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y, expiry is deferred to task_work; exit_task_work runs before exit_notify, so the IRQ-time overlap with reaping does not occur. -- Even then, if the task is already exiting, task_work_add() fails; gating on exit_state makes both modes consistent. +- Even then, if the task is already exiting, task_work_add() fails; gating on exit_state makes both modes consistent.[[1]](#references)[[5]](#references) Fix (Android common kernel) and rationale - Add an early return if current task is exiting, gating all processing: @@ -165,7 +165,7 @@ if (tsk->exit_state) - This prevents entering handle_posix_cpu_timers() for exiting tasks, eliminating the window where posix_cpu_timer_del() could miss it.cpu.firing and race with expiry processing.[[2]](#references)[[3]](#references) Impact -- Kernel memory corruption of timer structures during concurrent expiry/deletion can yield immediate crashes (DoS) and is a strong primitive toward privilege escalation due to arbitrary kernel-state manipulation opportunities.[[1]](#references) +- Kernel memory corruption of timer structures during concurrent expiry/deletion can yield immediate crashes (DoS) and is a strong primitive toward privilege escalation due to arbitrary kernel-state manipulation opportunities. Triggering the bug (safe, reproducible conditions) Build/config @@ -199,7 +199,7 @@ void *deleter(void *arg) { } ``` -- Race amplifiers: high scheduler tick rate, CPU load, repeated thread exit/re-create cycles. The crash typically manifests when posix_cpu_timer_del() skips noticing firing due to failing task lookup/locking right after unlock_task_sighand(). +- Race amplifiers: high scheduler tick rate, CPU load, repeated thread exit/re-create cycles. The crash typically manifests when posix_cpu_timer_del() skips noticing firing due to failing task lookup/locking right after unlock_task_sighand().[[1]](#references)[[5]](#references) Detection and hardening - Mitigation: apply the exit_state guard; prefer enabling CONFIG_POSIX_CPU_TIMERS_TASK_WORK when feasible. @@ -217,9 +217,9 @@ Notes for exploitation research ### Chronomaly exploit strategy (priv-esc without fixed text offsets) - **Tested target & configs:** x86_64 v5.10.157 under QEMU (4 cores, 3 GB RAM). Critical options: `CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n`, `CONFIG_PREEMPT=y`, `CONFIG_SLAB_MERGE_DEFAULT=n`, `DEBUG_LIST=n`, `BUG_ON_DATA_CORRUPTION=n`, `LIST_HARDENED=n`.[[4]](#references) -- **Race steering with CPU timers:** A racing thread (`race_func()`) burns CPU while CPU timers fire; `free_func()` polls `SIGUSR1` to confirm if the timer fired. Tune `CPU_USAGE_THRESHOLD` so signals arrive only sometimes (intermittent "Parent raced too late/too early" messages). If timers fire every attempt, lower the threshold; if they never fire before thread exit, raise it. -- **Dual-process alignment into `send_sigqueue()`:** Parent/child processes try to hit a second race window inside `send_sigqueue()`. The parent sleeps `PARENT_SETTIME_DELAY_US` microseconds before arming timers; adjust downward when you mostly see "Parent raced too late" and upward when you mostly see "Parent raced too early". Seeing both indicates you are straddling the window; success is expected within ~1 minute once tuned. -- **Cross-cache UAF replacement:** The exploit frees a `struct sigqueue` then grooms allocator state (`sigqueue_crosscache_preallocs()`) so both the dangling `uaf_sigqueue` and the replacement `realloc_sigqueue` land on a pipe buffer data page (cross-cache reallocation). Reliability assumes a quiet kernel with few prior `sigqueue` allocations; if per-CPU/per-node partial slab pages already exist (busy systems), the replacement will miss and the chain fails. The author intentionally left it unoptimized for noisy kernels. +- **Race steering with CPU timers:** A racing thread (`race_func()`) burns CPU while CPU timers fire; `free_func()` polls `SIGUSR1` to confirm if the timer fired. Tune `CPU_USAGE_THRESHOLD` so signals arrive only sometimes (intermittent "Parent raced too late/too early" messages). If timers fire every attempt, lower the threshold; if they never fire before thread exit, raise it.[[4]](#references)[[7]](#references) +- **Dual-process alignment into `send_sigqueue()`:** Parent/child processes try to hit a second race window inside `send_sigqueue()`. The parent sleeps `PARENT_SETTIME_DELAY_US` microseconds before arming timers; adjust downward when you mostly see "Parent raced too late" and upward when you mostly see "Parent raced too early". Seeing both indicates you are straddling the window; success is expected within ~1 minute once tuned.[[4]](#references)[[6]](#references) +- **Cross-cache UAF replacement:** The exploit frees a `struct sigqueue` then grooms allocator state (`sigqueue_crosscache_preallocs()`) so both the dangling `uaf_sigqueue` and the replacement `realloc_sigqueue` land on a pipe buffer data page (cross-cache reallocation). Reliability assumes a quiet kernel with few prior `sigqueue` allocations; if per-CPU/per-node partial slab pages already exist (busy systems), the replacement will miss and the chain fails. The author intentionally left it unoptimized for noisy kernels.[[4]](#references)[[6]](#references) ### See also @@ -228,12 +228,13 @@ ksmbd-streams_xattr-oob-write-cve-2025-37947.md {{#endref}} ## References + - [1] [Race Against Time in the Kernel’s Clockwork (StreyPaws)](https://streypaws.github.io/posts/Race-Against-Time-in-the-Kernel-Clockwork/) - [2] [Android security bulletin – September 2025](https://source.android.com/docs/security/bulletin/2025-09-01) - [3] [Android common kernel patch commit 157f357d50b5…](https://android.googlesource.com/kernel/common/+/157f357d50b5038e5eaad0b2b438f923ac40afeb%5E%21/#F0) - [4] [Chronomaly exploit PoC (CVE-2025-38352)](https://github.com/farazsth98/chronomaly) - [5] [CVE-2025-38352 analysis – Part 1](https://faith2dxy.xyz/2025-12-22/cve_2025_38352_analysis/) -- [6] [CVE-2025-38352 analysis – Part 2](https://faith2dxy.xyz/2025-12-24/cve_2025_38352_analysis_part_2/) -- [7] [CVE-2025-38352 analysis – Part 3](https://faith2dxy.xyz/2026-01-03/cve_2025_38352_analysis_part_3/) +- [6] [CVE-2025-38352 analysis – Part 3](https://faith2dxy.xyz/2026-01-03/cve_2025_38352_analysis_part_3/) +- [7] [CVE-2025-38352 analysis – Part 2](https://faith2dxy.xyz/2025-12-24/cve_2025_38352_analysis_part_2/) -{{#include ../../banners/hacktricks-training.md}} \ No newline at end of file +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/README.md b/src/binary-exploitation/rop-return-oriented-programing/README.md index 29f13765680..e40d7da2ff4 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/README.md +++ b/src/binary-exploitation/rop-return-oriented-programing/README.md @@ -34,7 +34,7 @@ First, let's assume we've identified the necessary gadgets within the binary or ### **ROP Chain** -Using **pwntools**, we prepare the stack for the ROP chain execution as follows aiming to execute `system('/bin/sh')`, note how the chain starts with:[[1]](#references) +Using **pwntools**, we prepare the stack for the ROP chain execution as follows aiming to execute `system('/bin/sh')`, note how the chain starts with: 1. A `ret` instruction for alignment purposes (optional) 2. Address of `system` function (supposing ASLR disabled and known libc, more info in [**Ret2lib**](ret2lib/index.html)) @@ -79,7 +79,7 @@ p.interactive() ### **x64 (64-bit) Calling conventions** -- Uses the **System V AMD64 ABI** calling convention on Unix-like systems, where the **first six integer or pointer arguments are passed in the registers `RDI`, `RSI`, `RDX`, `RCX`, `R8`, and `R9`**. Additional arguments are passed on the stack. The return value is placed in `RAX`. +- Uses the **System V AMD64 ABI** calling convention on Unix-like systems, where the **first six integer or pointer arguments are passed in the registers `RDI`, `RSI`, `RDX`, `RCX`, `R8`, and `R9`**. Additional arguments are passed on the stack. The return value is placed in `RAX`.[[1]](#references) - **Windows x64** calling convention uses `RCX`, `RDX`, `R8`, and `R9` for the first four integer or pointer arguments, with additional arguments passed on the stack. The return value is placed in `RAX`. - **Registers**: 64-bit registers include `RAX`, `RBX`, `RCX`, `RDX`, `RSI`, `RDI`, `RBP`, `RSP`, and `R8` to `R15`. @@ -300,8 +300,7 @@ write(fd, shellcode, shellcode_len); ((void(*)())target_addr)(); // ARM Thumb: jump to target_addr | 1 ``` -If preserving `fd` is hard, calling `open()` multiple times can make it feasible to **guess the descriptor** used for `/proc/self/mem`. On ARM Thumb targets, remember to **set the low bit** when branching (`addr | 1`). - +If preserving `fd` is hard, calling `open()` multiple times can make it feasible to **guess the descriptor** used for `/proc/self/mem`. On ARM Thumb targets, remember to **set the low bit** when branching (`addr | 1`).[[5]](#references)[[6]](#references) ## Protections Against ROP and JOP @@ -336,12 +335,12 @@ rop-syscall-execv/ ## References -- [1] [Exploiting calling conventions (ir0nstone notes)](https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/exploiting-calling-conventions) -- [2] [Nightmare: hacklu15 stackstuff](https://guyinatuxedo.github.io/15-partial_overwrite/hacklu15_stackstuff/index.html) +- [1] [Exploiting Calling Conventions - ir0nstone's Notes](https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/exploiting-calling-conventions) +- [2] [Hack.lu CTF 2015 - stackstuff writeup](https://guyinatuxedo.github.io/15-partial_overwrite/hacklu15_stackstuff/index.html) - 64 bit, Pie and nx enabled, no canary, overwrite RIP with a `vsyscall` address with the sole purpose or return to the next address in the stack which will be a partial overwrite of the address to get the part of the function that leaks the flag -- [3] [Using mprotect to bypass NX protection (ARM64 Part 4, 8ksec)](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/) +- [3] [ARM64 Reversing and Exploitation Part 4: Using mprotect to Bypass NX Protection - 8kSec Blogs](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/) - arm64, no ASLR, ROP gadget to make stack executable and jump to shellcode in stack -- [4] [In-the-wild iOS exploit chain 4 (Google Project Zero)](https://googleprojectzero.blogspot.com/2019/08/in-wild-ios-exploit-chain-4.html) +- [4] [In the Wild iOS Exploit Chain 4 - Google Project Zero](https://googleprojectzero.blogspot.com/2019/08/in-wild-ios-exploit-chain-4.html) - [5] [Now You See mi: Now You're Pwned](https://labs.taszk.io/articles/post/nowyouseemi/) - [6] [TaszkSecLabs/xiaomi-c400-pwn](https://github.com/TaszkSecLabs/xiaomi-c400-pwn) diff --git a/src/binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.md b/src/binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.md index 429764a22d4..b23866736ab 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.md +++ b/src/binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.md @@ -4,8 +4,8 @@ ## Basic Information -The goal of this attack is to be able to **abuse a ROP via a buffer overflow without any information about the vulnerable binary**.[[1]](#references)[[2]](#references)\ -This attack is based on the following scenario: +The goal of this attack is to be able to **abuse a ROP via a buffer overflow without any information about the vulnerable binary**.\ +This attack is based on the following scenario:[[1]](#references) - A stack vulnerability and knowledge of how to trigger it. - A server application that restarts after a crash. @@ -22,11 +22,11 @@ You can find more information about these processes [here (BF Forked & Threaded ### **4. Find the stop gadget** -This gadget basically allows to confirm that something interesting was executed by the ROP gadget because the execution didn't crash. Usually, this gadget is going to be something that **stops the execution** and it's positioned at the end of the ROP chain when looking for ROP gadgets to confirm a specific ROP gadget was executed +This gadget basically allows to confirm that something interesting was executed by the ROP gadget because the execution didn't crash. Usually, this gadget is going to be something that **stops the execution** and it's positioned at the end of the ROP chain when looking for ROP gadgets to confirm a specific ROP gadget was executed[[2]](#references) ### **5. Find BROP gadget** -This technique uses the [**ret2csu**](ret2csu.md) gadget. And this is because if you access this gadget in the middle of some instructions you get gadgets to control **`rsi`** and **`rdi`**: +This technique uses the [**ret2csu**](ret2csu.md) gadget. And this is because if you access this gadget in the middle of some instructions you get gadgets to control **`rsi`** and **`rdi`**:[[1]](#references)

https://www.scs.stanford.edu/brop/bittau-brop.pdf

@@ -35,7 +35,7 @@ These would be the gadgets: - `pop rsi; pop r15; ret` - `pop rdi; ret` -Notice how with those gadgets it's possible to **control 2 arguments** of a function to call.[[1]](#references) +Notice how with those gadgets it's possible to **control 2 arguments** of a function to call. Also, notice that the ret2csu gadget has a **very unique signature** because it's going to be poping 6 registers from the stack. SO sending a chain like: @@ -51,7 +51,7 @@ Knowing the address of the ret2csu gadget, it's possible to **infer the address ### 6. Find PLT -The PLT table can be searched from 0x400000 or from the **leaked RIP address** from the stack (if **PIE** is being used). The **entries** of the table are **separated by 16B** (0x10B), and when one function is called the server doesn't crash even if the arguments aren't correct. Also, checking the address of a entry in the **PLT + 6B also doesn't crash** as it's the first code executed. +The PLT table can be searched from 0x400000 or from the **leaked RIP address** from the stack (if **PIE** is being used). The **entries** of the table are **separated by 16B** (0x10B), and when one function is called the server doesn't crash even if the arguments aren't correct. Also, checking the address of a entry in the **PLT + 6B also doesn't crash** as it's the first code executed.[[2]](#references) Therefore, it's possible to find the PLT table checking the following behaviours: @@ -61,7 +61,7 @@ Therefore, it's possible to find the PLT table checking the following behaviours ### 7. Finding strcmp -The **`strcmp`** function sets the register **`rdx`** to the length of the string being compared. Note that **`rdx`** is the **third argument** and we need it to be **bigger than 0** in order to later use `write` to leak the program. +The **`strcmp`** function sets the register **`rdx`** to the length of the string being compared. Note that **`rdx`** is the **third argument** and we need it to be **bigger than 0** in order to later use `write` to leak the program.[[2]](#references) It's possible to find the location of **`strcmp`** in the PLT based on its behaviour using the fact that we can now control the 2 first arguments of functions: @@ -92,7 +92,7 @@ Having found `strcmp` it's possible to set **`rdx`** to a value bigger than 0. ### 8. Finding Write or equivalent -Finally, it's needed a gadget that exfiltrates data in order to exfiltrate the binary. And at this moment it's possible to **control 2 arguments and set `rdx` bigger than 0.** +Finally, it's needed a gadget that exfiltrates data in order to exfiltrate the binary. And at this moment it's possible to **control 2 arguments and set `rdx` bigger than 0.**[[2]](#references) There are 3 common funtions taht could be abused for this: @@ -104,7 +104,7 @@ However, the original paper only mentions the **`write`** one, so lets talk abou The current problem is that we don't know **where the write function is inside the PLT** and we don't know **a fd number to send the data to our socket**. -However, we know **where the PLT table is** and it's possible to find write based on its **behaviour**. And we can create **several connections** with the server an d use a **high FD** hoping that it matches some of our connections.[[1]](#references) +However, we know **where the PLT table is** and it's possible to find write based on its **behaviour**. And we can create **several connections** with the server an d use a **high FD** hoping that it matches some of our connections. Behaviour signatures to find those functions: @@ -118,7 +118,7 @@ Behaviour signatures to find those functions: ## References -- [1] [Hacking Blind (original BROP paper)](https://www.scs.stanford.edu/brop/bittau-brop.pdf) -- [2] [Blind Return Oriented Programming - BROP (CTF Recipes)](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/blind-return-oriented-programming-brop) +- [1] [Hacking Blind - the original BROP paper by Bittau et al., Stanford](https://www.scs.stanford.edu/brop/bittau-brop.pdf) +- [2] [Blind Return Oriented Programming (BROP) - CTF Recipes](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/blind-return-oriented-programming-brop) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2dlresolve.md b/src/binary-exploitation/rop-return-oriented-programing/ret2dlresolve.md index 4fd180c9d2d..61458e94aae 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2dlresolve.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2dlresolve.md @@ -35,7 +35,7 @@ Or check these pages for a step-by-step explanation:[[2]](#references)[[4]] 4. **Call** `_dl_runtime_resolve` 5. **`system`** will be resolved and called with `'/bin/sh'` as argument -From the [**pwntools documentation**](https://docs.pwntools.com/en/stable/rop/ret2dlresolve.html), this is how a **`ret2dlresolve`** attack look like: +From the [**pwntools documentation**](https://docs.pwntools.com/en/stable/rop/ret2dlresolve.html), this is how a **`ret2dlresolve`** attack look like:[[7]](#references) ```python context.binary = elf = ELF(pwnlib.data.elf.ret2dlresolve.get('amd64')) @@ -199,6 +199,7 @@ target.interactive() - [4] [ret2dlresolve - CTF Recipes](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/ret2dlresolve#how-it-works) - [5] [ret2dlresolve exploitation - ir0nstone notes](https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve/exploitation) - [6] [0CTF 2018 babystack write-up - sajjadium](https://github.com/sajjadium/ctf-writeups/tree/master/0CTFQuals/2018/babystack) +- [7] [pwntools - ret2dlresolve documentation](https://docs.pwntools.com/en/stable/rop/ret2dlresolve.html) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/one-gadget.md b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/one-gadget.md index 4b06dd3b201..9fd6e87e1de 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/one-gadget.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/one-gadget.md @@ -4,8 +4,8 @@ ## Basic Information -[**One Gadget**](https://github.com/david942j/one_gadget) allows to obtain a shell instead of using **system** and **"/bin/sh". One Gadget** will find inside the libc library some way to obtain a shell (`execve("/bin/sh")`) using just one **address**.\ -However, normally there are some constrains, the most common ones and easy to avoid are like `[rsp+0x30] == NULL` As you control the values inside the **RSP** you just have to send some more NULL values so the constrain is avoided. +[**One Gadget**](https://github.com/david942j/one_gadget) allows to obtain a shell instead of using **system** and **"/bin/sh". One Gadget** will find inside the libc library some way to obtain a shell (`execve("/bin/sh")`) using just one **address**.[[1]](#references)\ +However, normally there are some constrains, the most common ones and easy to avoid are like `[rsp+0x30] == NULL` As you control the values inside the **RSP** you just have to send some more NULL values so the constrain is avoided.[[1]](#references) ![One Gadget: However, normally there are some constrains, the most common ones and easy to avoid are like (rsp+0x30) == NULL As you control the values inside the RSP you just have to send...](<../../../images/image (754).png>) @@ -21,12 +21,12 @@ To the address indicated by One Gadget you need to **add the base address where ### ARM64 -The github repo mentions that **ARM64 is supported** by the tool, but when running it in the libc of a Kali 2023.3 **it doesn't find any gadget**. +The github repo mentions that **ARM64 is supported** by the tool, but when running it in the libc of a Kali 2023.3 **it doesn't find any gadget**.[[1]](#references) ## Angry Gadget -From the [**github repo**](https://github.com/ChrisTheCoolHut/angry_gadget): Inspired by [OneGadget](https://github.com/david942j/one_gadget) this tool is written in python and uses [angr](https://github.com/angr/angr) to test constraints for gadgets executing `execve('/bin/sh', NULL, NULL)`\ -If you've run out gadgets to try from OneGadget, Angry Gadget gives a lot more with complicated constraints to try! +From the [**github repo**](https://github.com/ChrisTheCoolHut/angry_gadget): Inspired by [OneGadget](https://github.com/david942j/one_gadget) this tool is written in python and uses [angr](https://github.com/angr/angr) to test constraints for gadgets executing `execve('/bin/sh', NULL, NULL)`[[1]](#references)[[2]](#references)\ +If you've run out gadgets to try from OneGadget, Angry Gadget gives a lot more with complicated constraints to try![[2]](#references) ```bash pip install angry_gadget @@ -34,7 +34,9 @@ pip install angry_gadget angry_gadget.py examples/libc6_2.23-0ubuntu10_amd64.so ``` -{{#include ../../../banners/hacktricks-training.md}} - +## References +- [1] [one_gadget - The best exploit tool of magic, find one gadget to rule them all](https://github.com/david942j/one_gadget) +- [2] [angry_gadget - Find one gadgets using angr and satisfiability](https://github.com/ChrisTheCoolHut/angry_gadget) +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/ret2lib-printf-leak-arm64.md b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/ret2lib-printf-leak-arm64.md index 536c87126f2..c24ebd61f00 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/ret2lib-printf-leak-arm64.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/ret2lib-printf-leak-arm64.md @@ -29,7 +29,7 @@ clang -o rop-no-aslr rop-no-aslr.c -fno-stack-protector -mbranch-protection=none echo 0 | sudo tee /proc/sys/kernel/randomize_va_space ``` -- Recent toolchains may emit **PAC/BTI** instrumentation by default on some ARM64 targets. If you are building a lab binary for practice, **`-mbranch-protection=none`** keeps the classic ret2lib flow reproducible. +- Recent toolchains may emit **PAC/BTI** instrumentation by default on some ARM64 targets. If you are building a lab binary for practice, **`-mbranch-protection=none`** keeps the classic ret2lib flow reproducible.[[1]](#references) - You can quickly verify whether the binary carries branch-protection notes with: ```bash @@ -49,11 +49,11 @@ objdump -d rop-no-aslr | grep -E 'bti|paci|auti' ### Find offset - x30 offset -Creating a pattern with **`pattern create 200`**, using it, and checking for the offset with **`pattern search $x30`** we can see that the offset is **`108`** (0x6c).[[1]](#references) +Creating a pattern with **`pattern create 200`**, using it, and checking for the offset with **`pattern search $x30`** we can see that the offset is **`108`** (0x6c).
-Taking a look to the dissembled main function we can see that we would like to **jump** to the instruction to jump to **`printf`** directly, whose offset from where the binary is loaded is **`0x860`**:[[1]](#references) +Taking a look to the dissembled main function we can see that we would like to **jump** to the instruction to jump to **`printf`** directly, whose offset from where the binary is loaded is **`0x860`**:
@@ -73,7 +73,7 @@ Using ropper an interesting gadget was found: 0x000000000006bdf0: ldr x0, [sp, #0x18]; ldp x29, x30, [sp], #0x20; ret; ``` -This gadget will load `x0` from **`$sp + 0x18`** and then load the addresses x29 and x30 form sp and jump to x30. So with this gadget we can **control the first argument and then jump to system**.[[1]](#references) +This gadget will load `x0` from **`$sp + 0x18`** and then load the addresses x29 and x30 form sp and jump to x30. So with this gadget we can **control the first argument and then jump to system**. ### Exploit @@ -166,11 +166,11 @@ Setting a breakpoint before calling printf it's possible to see that there are a
-Trying different offsets, the **`%21$p`** can leak a binary address (PIE bypass) and **`%25$p`** can leak a libc address:[[1]](#references) +Trying different offsets, the **`%21$p`** can leak a binary address (PIE bypass) and **`%25$p`** can leak a libc address:
-Subtracting the libc leaked address with the base address of libc, it's possible to see that the **offset** of the **leaked address from the base is `0x49c40`.**[[1]](#references) +Subtracting the libc leaked address with the base address of libc, it's possible to see that the **offset** of the **leaked address from the base is `0x49c40`.** > [!IMPORTANT] > The exact format-string positions are **build-dependent**. The values **`%21$p`** and **`%25$p`** are valid for this binary/libc combination, but different compilers, optimization levels or libc versions can move the interesting pointers. On AArch64 this is especially visible because **`printf`** receives its first arguments in registers first, and only later consumes stack values. In a new target, brute-force several **`%p`** positions or inspect the state right before the **`printf`** call to re-discover the correct offsets. @@ -211,7 +211,7 @@ Using ropper another interesting gadget was found: 0x0000000000049c40: ldr x0, [sp, #0x78]; ldp x29, x30, [sp], #0xc0; ret; ``` -This gadget will load `x0` from **`$sp + 0x78`** and then load the addresses x29 and x30 form sp and jump to x30. So with this gadget we can **control the first argument and then jump to system**.[[1]](#references) +This gadget will load `x0` from **`$sp + 0x78`** and then load the addresses x29 and x30 form sp and jump to x30. So with this gadget we can **control the first argument and then jump to system**. When you need to re-find a similar gadget in another libc, a quick ARM64-oriented workflow is: @@ -276,11 +276,10 @@ p.sendline(payload) p.interactive() ``` - - ## References - [1] [ARM64 Reversing And Exploitation Part 7 – Bypassing ASLR and NX - 8kSec](https://8ksec.io/arm64-reversing-and-exploitation-part-7-bypassing-aslr-and-nx/) - [2] [Procedure Call Standard for the Arm 64-bit Architecture (AArch64)](https://github.com/ARM-software/abi-aa/releases) + {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/README.md b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/README.md index ddedc6ff4cc..5a0e122ae2f 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/README.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/README.md @@ -12,7 +12,7 @@ ## Other tutorials and binaries to practice This tutorial is going to exploit the code/binary proposed in this tutorial: [https://tasteofsecurity.com/security/ret2libc-unknown-libc/](https://tasteofsecurity.com/security/ret2libc-unknown-libc/)[[1]](#references)\ -Another useful tutorials: [https://made0x78.com/bseries-ret2libc/](https://made0x78.com/bseries-ret2libc/), [https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html)[[2]](#references)[[3]](#references) +Another useful tutorials: [https://made0x78.com/bseries-ret2libc/](https://made0x78.com/bseries-ret2libc/)[[2]](#references), [https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html)[[3]](#references) ## Code @@ -252,8 +252,8 @@ Finally, the **address of exit function** is **called** so the process **exists ## 4(2)- Using ONE_GADGET -You could also use [**ONE_GADGET** ](https://github.com/david942j/one_gadget)to obtain a shell instead of using **system** and **"/bin/sh". ONE_GADGET** will find inside the libc library some way to obtain a shell using just one **ROP address**.\ -However, normally there are some constrains, the most common ones and easy to avoid are like `[rsp+0x30] == NULL` As you control the values inside the **RSP** you just have to send some more NULL values so the constrain is avoided. +You could also use [**ONE_GADGET** ](https://github.com/david942j/one_gadget)to obtain a shell instead of using **system** and **"/bin/sh". ONE_GADGET** will find inside the libc library some way to obtain a shell using just one **ROP address**.[[4]](#references)\ +However, normally there are some constrains, the most common ones and easy to avoid are like `[rsp+0x30] == NULL` As you control the values inside the **RSP** you just have to send some more NULL values so the constrain is avoided.[[4]](#references) ![Interact with the shell - 4(2)- Using ONE GADGET: However, normally there are some constrains, the most common ones and easy to avoid are like (rsp+0x30) == NULL As you control the...](<../../../../images/image (754).png>) @@ -305,8 +305,9 @@ BINSH = next(libc.search("/bin/sh")) - 64 ## References -- [1] [tasteofsecurity - ret2libc with unknown libc](https://tasteofsecurity.com/security/ret2libc-unknown-libc/) -- [2] [made0x78 - Binary exploitation series: ret2libc](https://made0x78.com/bseries-ret2libc/) -- [3] [guyinatuxedo - csaw19 babyboi](https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html) +- [1] [Ret2libc - Unknown libc - Taste of Security](https://tasteofsecurity.com/security/ret2libc-unknown-libc/) +- [2] [B-series: ret2libc - made0x78](https://made0x78.com/bseries-ret2libc/) +- [3] [CSAW 2019 Quals - babyboi (guyinatuxedo)](https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html) +- [4] [one_gadget - The best exploit tool of magic, find one gadget to rule them all](https://github.com/david942j/one_gadget) {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/rop-leaking-libc-template.md b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/rop-leaking-libc-template.md index 163560a1f8c..371d53ae8be 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/rop-leaking-libc-template.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/rop-leaking-libc-template.md @@ -219,8 +219,4 @@ Try to **subtract 64 bytes to the address of "/bin/sh"**: BINSH = next(libc.search("/bin/sh")) - 64 ``` - {{#include ../../../../banners/hacktricks-training.md}} - - - diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2vdso.md b/src/binary-exploitation/rop-return-oriented-programing/ret2vdso.md index 8f130b946e3..ead7b692ada 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2vdso.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2vdso.md @@ -10,7 +10,7 @@ There might be **gadgets in the vDSO region**, which is a small ELF DSO mapped b The vDSO base address is passed in the auxiliary vector as `AT_SYSINFO_EHDR`, so if you can read `/proc//auxv` (or call `getauxval` in a helper process), you can recover the base without relying on a memory leak. See [Auxiliary Vector (auxv) and vDSO](../basic-stack-binary-exploitation-methodology/elf-tricks.md) for practical ways to obtain it. -Once you have the base, treat the vDSO like a normal ELF DSO (`linux-vdso.so.1`): dump the mapping and use `readelf -Ws`/`objdump -d` (or the kernel reference parser `tools/testing/selftests/vDSO/parse_vdso.c`) to resolve exported symbols and look for gadgets. On x86 32-bit the vDSO commonly exports `__kernel_vsyscall`, `__kernel_sigreturn`, and `__kernel_rt_sigreturn`; on x86_64 typical exports include `__vdso_clock_gettime`, `__vdso_gettimeofday`, and `__vdso_time`. Because the vDSO uses symbol versioning, match the expected version when resolving symbols. +Once you have the base, treat the vDSO like a normal ELF DSO (`linux-vdso.so.1`): dump the mapping and use `readelf -Ws`/`objdump -d` (or the kernel reference parser `tools/testing/selftests/vDSO/parse_vdso.c`) to resolve exported symbols and look for gadgets. On x86 32-bit the vDSO commonly exports `__kernel_vsyscall`, `__kernel_sigreturn`, and `__kernel_rt_sigreturn`; on x86_64 typical exports include `__vdso_clock_gettime`, `__vdso_gettimeofday`, and `__vdso_time`. Because the vDSO uses symbol versioning, match the expected version when resolving symbols.[[1]](#references)[[2]](#references) Following the example from [https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/) it's possible to see how it was possible to dump the vdso section and move it to the host with:[[3]](#references) @@ -76,8 +76,8 @@ srop-sigreturn-oriented-programming/srop-arm64.md ## References - [1] [vdso(7) - Linux manual page](https://man7.org/linux/man-pages/man7/vdso.7.html) -- [2] [Linux vDSO kernel ABI documentation](https://www.kernel.org/doc/Documentation/ABI/stable/vdso) -- [3] [Maze of Mist - HTB Cyber Apocalypse writeup](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/) +- [2] [Linux kernel vDSO ABI documentation](https://www.kernel.org/doc/Documentation/ABI/stable/vdso) +- [3] [Maze of Mist - HTB Cyber Apocalypse](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/) - [4] [Linux kernel: bypassing ASLR via VDSO](https://vigilance.fr/vulnerability/Linux-kernel-bypassing-ASLR-via-VDSO-11639) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/README.md b/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/README.md index d91136ed062..c35f9623c81 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/README.md +++ b/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/README.md @@ -20,7 +20,7 @@ So, basically it's needed to write the string `/bin/sh` somewhere and then perfo ## Register gadgets -Let's start by finding **how to control those registers**: +Let's start by finding **how to control those registers**:[[1]](#references) ```bash ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret" @@ -30,7 +30,7 @@ ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret" 0x00000000004498b5 : pop rdx ; ret ``` -With these addresses it's possible to **write the content in the stack and load it into the registers**.[[1]](#references) +With these addresses it's possible to **write the content in the stack and load it into the registers**. ## Write string @@ -186,11 +186,11 @@ target.interactive() ## References -- [1] [Defcon Quals 2019 Speedrun1](https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html) +- [1] [dcquals19_speedrun1 - guyinatuxedo](https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html) - 64 bits, no PIE, nx, write in some memory a ROP to call `execve` and jump there. -- [2] [Boston Key Party 2016 Simple Calc](https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html) +- [2] [bkp16_simplecalc - guyinatuxedo](https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html) - 64 bits, nx, no PIE, write in some memory a ROP to call `execve` and jump there. In order to write to the stack a function that performs mathematical operations is abused -- [3] [Defcon Quals 2016 feedme](https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html) +- [3] [dcquals16_feedme - guyinatuxedo](https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html) - 64 bits, no PIE, nx, BF canary, write in some memory a ROP to call `execve` and jump there. {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md b/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md index 90716bbe468..30f23cb587b 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md +++ b/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md @@ -128,5 +128,3 @@ p.interactive() ``` {{#include ../../../banners/hacktricks-training.md}} - - diff --git a/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md b/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md index 9bac2130dea..5b51335ae14 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md +++ b/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md @@ -67,7 +67,7 @@ https://youtu.be/ADULSwnQs-s?feature=shared ## Example -You can [**find an example here**](https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop/using-srop) where the call to signeturn is constructed via ROP (putting in rxa the value `0xf`), although this is the final exploit from there:[[2]](#references) +You can [**find an example here**](https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop/using-srop) where the call to signeturn is constructed via ROP (putting in rxa the value `0xf`), although this is the final exploit from there:[[2]](#references)[[8]](#references) ```python from pwn import * @@ -145,6 +145,7 @@ target.interactive() - 64 bits assembly program, no relro, no canary, nx, no pie. The flow allows to write in the stack, control several registers, and call a syscall and then it calls `exit`. The selected syscall is a `sigreturn` that will set registries and move `eip` to call a previous syscall instruction and run `memprotect` to set the binary space to `rwx` and set the ESP in the binary space. Following the flow, the program will call read intro ESP again, but in this case ESP will be pointing to the next intruction so passing a shellcode will write it as the next instruction and execute it. - [7] [CTF Recipes - Sigreturn-Oriented Programming (SROP)](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/sigreturn-oriented-programming-srop#disable-stack-protection) - SROP is used to give execution privileges (memprotect) to the place where a shellcode was placed. +- [8] [ir0nstone - Using SROP](https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop/using-srop) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/stack-overflow/pointer-redirecting.md b/src/binary-exploitation/stack-overflow/pointer-redirecting.md index def495ed22d..130c6d35526 100644 --- a/src/binary-exploitation/stack-overflow/pointer-redirecting.md +++ b/src/binary-exploitation/stack-overflow/pointer-redirecting.md @@ -4,9 +4,9 @@ ## String pointers -If a function call is going to use an address of a string that is located in the stack, it's possible to abuse the buffer overflow to **overwrite this address** and put an **address to a different string** inside the binary.[[1]](#references) +If a function call is going to use an address of a string that is located in the stack, it's possible to abuse the buffer overflow to **overwrite this address** and put an **address to a different string** inside the binary. -If for example a **`system`** function call is going to **use the address of a string to execute a command**, an attacker could place the **address of a different string in the stack**, **`export PATH=.:$PATH`** and create in the current directory an **script with the name of the first letter of the new string** as this will be executed by the binary. +If for example a **`system`** function call is going to **use the address of a string to execute a command**, an attacker could place the **address of a different string in the stack**, **`export PATH=.:$PATH`** and create in the current directory an **script with the name of the first letter of the new string** as this will be executed by the binary.[[1]](#references) In real targets, **repointing a stack string pointer is usually more interesting than just changing the printed text**: @@ -103,9 +103,9 @@ The same idea also works for **read** primitives if the corrupted pointer is lat ### Modern AArch64 note: PAC / BTI -On current AArch64 targets, a classic **saved return address overwrite** may fail because the epilogue authenticates `x30` with PAC. In those cases, **non-return hijacks** such as corrupted local function pointers or callback pointers become more attractive.[[3]](#references) +On current AArch64 targets, a classic **saved return address overwrite** may fail because the epilogue authenticates `x30` with PAC. In those cases, **non-return hijacks** such as corrupted local function pointers or callback pointers become more attractive. -However, if **BTI** is enabled, the overwritten indirect-call target must still land on a **valid landing pad** (typically a function entry with **`bti c`**, or in PAC-enabled code a prologue starting with **`paciasp`/`pacibsp`**). Also, distinguish between plain indirect calls such as **`blr xN`** and authenticated ones such as **`blraa` / `blrab`**: the latter authenticate the branch target as part of the call, so redirecting the pointer to an unsigned gadget will usually fail even if the destination is executable. Therefore, when redirecting a stack function pointer on AArch64, prefer: +However, if **BTI** is enabled, the overwritten indirect-call target must still land on a **valid landing pad** (typically a function entry with **`bti c`**, or in PAC-enabled code a prologue starting with **`paciasp`/`pacibsp`**). Also, distinguish between plain indirect calls such as **`blr xN`** and authenticated ones such as **`blraa` / `blrab`**: the latter authenticate the branch target as part of the call, so redirecting the pointer to an unsigned gadget will usually fail even if the destination is executable.[[3]](#references) Therefore, when redirecting a stack function pointer on AArch64, prefer: - Real function entries instead of mid-function gadgets - Targets whose prologue already satisfies BTI @@ -120,9 +120,9 @@ You can find an example in: ## References -- [1] [Stack buffer overflow internship notes – Pointer redirecting](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#pointer-redirecting) +- [1] [stack-buffer-overflow-internship - NOTES.md: Pointer Redirecting](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#pointer-redirecting) - [2] [Exploiting CVE-2024-20017 four different ways](https://blog.coffinsec.com/0day/2024/08/30/exploiting-CVE-2024-20017-four-different-ways.html) -- [3] [Arm – Enabling PAC and BTI on AArch64](https://developer.arm.com/community/arm-community-blogs/b/architectures-and-processors-blog/posts/enabling-pac-and-bti-on-aarch64) -- [4] [GHSL-2024-197: GStreamer security advisory](https://securitylab.github.com/advisories/GHSL-2024-197_GStreamer/) +- [3] [Enabling PAC and BTI on AArch64 - Arm Community](https://developer.arm.com/community/arm-community-blogs/b/architectures-and-processors-blog/posts/enabling-pac-and-bti-on-aarch64) +- [4] [GHSL-2024-197: Uninitialized variable in GStreamer's Matroska demuxer leading to function pointer hijack (CVE-2024-47540)](https://securitylab.github.com/advisories/GHSL-2024-197_GStreamer/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/stack-overflow/ret2win/ret2win-arm64.md b/src/binary-exploitation/stack-overflow/ret2win/ret2win-arm64.md index 75f3af30466..a4c6c117097 100644 --- a/src/binary-exploitation/stack-overflow/ret2win/ret2win-arm64.md +++ b/src/binary-exploitation/stack-overflow/ret2win/ret2win-arm64.md @@ -188,7 +188,7 @@ p.close()
-You can find another off-by-one example in ARM64 in [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), which is a real off-by-**one** in a fictitious vulnerability. +You can find another off-by-one example in ARM64 in [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), which is a real off-by-**one** in a fictitious vulnerability.[[5]](#references) ## With PIE @@ -527,10 +527,10 @@ p.interactive() ## Notes on modern AArch64 hardening (PAC/BTI) and ret2win - Current GCC/Clang toolchains support `-mbranch-protection=standard`, which enables the common PAC/BTI hardening profile. For labs, keep using `-mbranch-protection=none` so your saved-`x30` overwrite behaves like a classic ret2win.[[1]](#references) -- If the binary is compiled with AArch64 Branch Protection, you may see `paciasp`/`autiasp` or `bti c` emitted in function prologues/epilogues. Some hardened entries use `paciasp`/`pacibsp` as the landing instruction instead of a separate `bti c`, so do not grep only for `bti`. In that case: +- If the binary is compiled with AArch64 Branch Protection, you may see `paciasp`/`autiasp` or `bti c` emitted in function prologues/epilogues. Some hardened entries use `paciasp`/`pacibsp` as the landing instruction instead of a separate `bti c`, so do not grep only for `bti`.[[2]](#references) In that case: - Returning to an address that is not a valid BTI landing pad may raise a `SIGILL`. Prefer targeting the exact function entry that contains `bti c`. - `pac-ret` signs functions that actually spill the return address to memory, so non-leaf functions are usually affected first. A leaf `win()` may still lack PAC unless the binary was built with `pac-ret+leaf`. - - If PAC is enabled for returns, naive return-address overwrites may fail because the epilogue authenticates `x30`. For learning scenarios, rebuild with `-mbranch-protection=none` (shown above). When attacking real targets, prefer non-return hijacks (e.g., function pointer overwrites) or build ROP that never executes an `autiasp`/`ret` pair that authenticates your forged LR.[[2]](#references) + - If PAC is enabled for returns, naive return-address overwrites may fail because the epilogue authenticates `x30`. For learning scenarios, rebuild with `-mbranch-protection=none` (shown above). When attacking real targets, prefer non-return hijacks (e.g., function pointer overwrites) or build ROP that never executes an `autiasp`/`ret` pair that authenticates your forged LR. - To check features quickly: - `readelf --notes -W ./ret2win` and look for `AARCH64_FEATURE_1_BTI` / `AARCH64_FEATURE_1_PAC` notes. - `objdump -d ./ret2win | head -n 40` and look for `bti c`, `paciasp`, `autiasp`. @@ -567,13 +567,13 @@ gdb-multiarch ./ret2win -ex 'set architecture arm64' -ex 'target remote :1234' ../../rop-return-oriented-programing/ret2lib/ret2lib-printf-leak-arm64.md {{#endref}} - - ## References -- [1] [GCC AArch64 options (`-mbranch-protection=standard`, `pac-ret`, `bti`)](https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html) -- [2] [Enabling PAC and BTI on AArch64 for Linux (Arm Community, Nov 2024)](https://developer.arm.com/community/arm-community-blogs/b/architectures-and-processors-blog/posts/enabling-pac-and-bti-on-aarch64) -- [3] [Preparing your app to work with pointer authentication (Apple)](https://developer.apple.com/documentation/security/preparing-your-app-to-work-with-pointer-authentication) +- [1] [GCC AArch64 Options (`-mbranch-protection=standard`, `pac-ret`, `bti`)](https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html) +- [2] [Enabling PAC and BTI on AArch64 for Linux - Arm Community](https://developer.arm.com/community/arm-community-blogs/b/architectures-and-processors-blog/posts/enabling-pac-and-bti-on-aarch64) +- [3] [Preparing your app to work with pointer authentication - Apple Developer Documentation](https://developer.apple.com/documentation/security/preparing-your-app-to-work-with-pointer-authentication) - [4] [pwntools cyclic documentation (`cyclic(..., n=8)` / `cyclic_find(..., n=8)`)](https://docs.pwntools.com/en/stable/util/cyclic.html) +- [5] [8kSec - ARM64 Reversing and Exploitation Part 9: Exploiting an Off-By-One Overflow Vulnerability](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/) + {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/stack-overflow/stack-shellcode/README.md b/src/binary-exploitation/stack-overflow/stack-shellcode/README.md index 3527098dea4..015cb280e81 100644 --- a/src/binary-exploitation/stack-overflow/stack-shellcode/README.md +++ b/src/binary-exploitation/stack-overflow/stack-shellcode/README.md @@ -4,7 +4,7 @@ ## Basic Information -**Stack shellcode** is a technique used in **binary exploitation** where an attacker writes shellcode to a vulnerable program's stack and then modifies the **Instruction Pointer (IP)** or **Extended Instruction Pointer (EIP)** to point to the location of this shellcode, causing it to execute. This is a classic method used to gain unauthorized access or execute arbitrary commands on a target system. Here's a breakdown of the process, including a simple C example and how you might write a corresponding exploit using Python with **pwntools**. +**Stack shellcode** is a technique used in **binary exploitation** where an attacker writes shellcode to a vulnerable program's stack and then modifies the **Instruction Pointer (IP)** or **Extended Instruction Pointer (EIP)** to point to the location of this shellcode, causing it to execute. This is a classic method used to gain unauthorized access or execute arbitrary commands on a target system. Here's a breakdown of the process, including a simple C example and how you might write a corresponding exploit using Python with **pwntools**.[[1]](#references) ### C Example: A Vulnerable Program @@ -80,8 +80,8 @@ The **NOP slide** (`asm('nop')`) is used to increase the chance that execution w On modern Windows the stack is non-executable (DEP/NX). A common way to still execute stack-resident shellcode after a stack BOF is to build a 64-bit ROP chain that calls VirtualAlloc (or VirtualProtect) from the module Import Address Table (IAT) to make a region of the stack executable and then return into shellcode appended after the chain.[[6]](#references) -Key points (Win64 calling convention):[[7]](#references) -- VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect) +Key points (Win64 calling convention): +- VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect)[[7]](#references) - RCX = lpAddress → choose an address in the current stack (e.g., RSP) so the newly allocated RWX region overlaps your payload - RDX = dwSize → large enough for your chain + shellcode (e.g., 0x1000) - R8 = flAllocationType = MEM_COMMIT (0x1000) @@ -152,14 +152,14 @@ Tips: ## References -- [1] [ir0nstone - Stack Shellcode](https://ir0nstone.gitbook.io/notes/types/stack/shellcode) -- [2] [Nightmare - csaw17 pilot](https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html) +- [1] [ir0nstone's Notes - Shellcode (Stack)](https://ir0nstone.gitbook.io/notes/types/stack/shellcode) +- [2] [guyinatuxedo - csaw17_pilot writeup](https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html) - 64bit, ASLR with stack address leak, write shellcode and jump to it -- [3] [Nightmare - tamu19 pwn3](https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html) +- [3] [guyinatuxedo - tamu19_pwn3 writeup](https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html) - 32 bit, ASLR with stack leak, write shellcode and jump to it -- [4] [Nightmare - tu18 shellaeasy](https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html) +- [4] [guyinatuxedo - tu18_shellaeasy writeup](https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html) - 32 bit, ASLR with stack leak, comparison to prevent call to exit(), overwrite variable with a value and write shellcode and jump to it -- [5] [ARM64 Reversing and Exploitation Part 4 - Using mprotect to bypass NX protection](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/) +- [5] [8kSec - ARM64 Reversing and Exploitation Part 4: Using mprotect to Bypass NX Protection](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/) - arm64, no ASLR, ROP gadget to make stack executable and jump to shellcode in stack - [6] [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE)](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html) - [7] [VirtualAlloc documentation](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc) diff --git a/src/binary-exploitation/stack-overflow/stack-shellcode/stack-shellcode-arm64.md b/src/binary-exploitation/stack-overflow/stack-shellcode/stack-shellcode-arm64.md index 251b7078d8a..c07a77ea8f4 100644 --- a/src/binary-exploitation/stack-overflow/stack-shellcode/stack-shellcode-arm64.md +++ b/src/binary-exploitation/stack-overflow/stack-shellcode/stack-shellcode-arm64.md @@ -45,7 +45,7 @@ If you still see PAC/BTI notes or prologues such as `paciasp` / `autiasp`, the c ### AArch64 shellcode reminders -- Linux syscalls pass arguments in **`x0`** to **`x7`**, place the syscall number in **`x8`**, and trigger the transition with **`svc #0`**. +- Linux syscalls pass arguments in **`x0`** to **`x7`**, place the syscall number in **`x8`**, and trigger the transition with **`svc #0`**.[[1]](#references) - AArch64 instructions are always **4 bytes**, so a NOP sled is usually repeated `nop` instructions (`0xd503201f`, bytes `\x1f\x20\x03\xd5`) instead of x86's single-byte `\x90`. - Shellcode is usually **position independent** and commonly uses `adr` / `adrp` style addressing to reach embedded strings such as `/bin/sh`.[[1]](#references) diff --git a/src/binary-exploitation/stack-overflow/uninitialized-variables.md b/src/binary-exploitation/stack-overflow/uninitialized-variables.md index 4a1191959ec..404c6631c29 100644 --- a/src/binary-exploitation/stack-overflow/uninitialized-variables.md +++ b/src/binary-exploitation/stack-overflow/uninitialized-variables.md @@ -105,13 +105,11 @@ From an attacker perspective, knowing whether the binary was built with these fl This doesn't change at all in ARM64 as local variables are also managed in the stack, you can [**check this example**](https://8ksec.io/arm64-reversing-and-exploitation-part-6-exploiting-an-uninitialized-stack-variable-vulnerability/) were this is shown.[[3]](#references) - - ## References - [1] [CONFIG_INIT_STACK_ALL_PATTERN documentation](https://www.kernelconfig.io/config_init_stack_all_pattern) - [2] [GHSL-2024-197: GStreamer uninitialized stack variable leading to function pointer overwrite](https://securitylab.github.com/advisories/GHSL-2024-197_GStreamer/) -- [3] [Exploiting an Uninitialized Stack Variable Vulnerability (ARM64 Reversing and Exploitation Part 6, 8ksec)](https://8ksec.io/arm64-reversing-and-exploitation-part-6-exploiting-an-uninitialized-stack-variable-vulnerability/) +- [3] [ARM64 Reversing and Exploitation Part 6: Exploiting an Uninitialized Stack Variable Vulnerability](https://8ksec.io/arm64-reversing-and-exploitation-part-6-exploiting-an-uninitialized-stack-variable-vulnerability/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/stack-overflow/windows-seh-overflow.md b/src/binary-exploitation/stack-overflow/windows-seh-overflow.md index 14829930262..baedea00331 100644 --- a/src/binary-exploitation/stack-overflow/windows-seh-overflow.md +++ b/src/binary-exploitation/stack-overflow/windows-seh-overflow.md @@ -21,7 +21,7 @@ This technique is specific to 32-bit processes (x86). On modern systems, prefer - Crash the process and verify the SEH chain is overwritten (e.g., in x32dbg/x64dbg, check the SEH view). - Send a cyclic pattern as the overflowing data and compute offsets of the two dwords that land in nSEH and SEH. -Example with peda/GEF/pwntools on a 1000-byte POST body: +Example with peda/GEF/pwntools on a 1000-byte POST body:[[1]](#references) ```bash # generate pattern (any tool is fine) diff --git a/src/binary-exploitation/vmware-workstation-pvscsi-lfh-escape.md b/src/binary-exploitation/vmware-workstation-pvscsi-lfh-escape.md index 45d018f761e..64c6c602c75 100644 --- a/src/binary-exploitation/vmware-workstation-pvscsi-lfh-escape.md +++ b/src/binary-exploitation/vmware-workstation-pvscsi-lfh-escape.md @@ -2,12 +2,12 @@ {{#include ../banners/hacktricks-training.md}} -This is the public **Workstation-on-Windows 11** variant of **CVE-2025-41238**. Broadcom later fixed it in **Workstation 17.6.4** and **Fusion 13.6.4**; Broadcom also notes that on **ESXi** the same PVSCSI bug is normally contained by the **VMX sandbox**, except in unsupported configurations.[[1]](#references)[[2]](#references) +This is the public **Workstation-on-Windows 11** variant of **CVE-2025-41238**.[[1]](#references) Broadcom later fixed it in **Workstation 17.6.4** and **Fusion 13.6.4**; Broadcom also notes that on **ESXi** the same PVSCSI bug is normally contained by the **VMX sandbox**, except in unsupported configurations.[[2]](#references) ## Bug anatomy: fixed-size realloc + scattered OOB writes -- `PVSCSI_FillSGI` copies guest scatter/gather entries into an internal array. It starts with a 512-entry static buffer (0x2000). Above 512 entries it reallocates to **0x4000** bytes and, because of a functional bug, **reallocates on every iteration**.[[1]](#references) -- The reallocation size never grows: 0x4000 / 0x10-byte entries = **1024 usable entries**. When the guest supplies **>1024 entries**, each new entry is written **16 bytes past the freshly allocated 0x4000 chunk**, corrupting the adjacent chunk header or object. +- `PVSCSI_FillSGI` copies guest scatter/gather entries into an internal array. It starts with a 512-entry static buffer (0x2000). Above 512 entries it reallocates to **0x4000** bytes and, because of a functional bug, **reallocates on every iteration**. +- The reallocation size never grows: 0x4000 / 0x10-byte entries = **1024 usable entries**. When the guest supplies **>1024 entries**, each new entry is written **16 bytes past the freshly allocated 0x4000 chunk**, corrupting the adjacent chunk header or object.[[1]](#references) - Overflow content: VMware stores `{u64 addr; u64 len}`; guest provides `{u64 addr; u32 len; u32 flags}`. The 32-bit `len` is **zero-extended**, so the last dword of every 16-byte OOB element is **always 0x00000000**. ## Guest-controlled host objects used by the chain diff --git a/src/blockchain/blockchain-and-crypto-currencies/defi-amm-virtual-balance-cache-exploitation.md b/src/blockchain/blockchain-and-crypto-currencies/defi-amm-virtual-balance-cache-exploitation.md index a47c2a33db8..ec2a1948ba0 100644 --- a/src/blockchain/blockchain-and-crypto-currencies/defi-amm-virtual-balance-cache-exploitation.md +++ b/src/blockchain/blockchain-and-crypto-currencies/defi-amm-virtual-balance-cache-exploitation.md @@ -121,7 +121,7 @@ Related: for swap-hook precision abuse that does **not** rely on stale persisten ## References -- [1] [Yearn Security Disclosure - Incident disclosure 2025-12-01](https://github.com/yearn/yearn-security/blob/master/disclosures/2025-12-01.md) +- [1] [Yearn Security Disclosure – Incident disclosure 2025-12-01](https://github.com/yearn/yearn-security/blob/master/disclosures/2025-12-01.md) - [2] [Check Point Research – The $9M yETH Exploit: How 16 Wei Became Infinite Tokens](https://research.checkpoint.com/2025/16-wei/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/blockchain/blockchain-and-crypto-currencies/erc-4337-smart-account-security-pitfalls.md b/src/blockchain/blockchain-and-crypto-currencies/erc-4337-smart-account-security-pitfalls.md index 844ac8bd409..fb095a7fb62 100644 --- a/src/blockchain/blockchain-and-crypto-currencies/erc-4337-smart-account-security-pitfalls.md +++ b/src/blockchain/blockchain-and-crypto-currencies/erc-4337-smart-account-security-pitfalls.md @@ -80,7 +80,7 @@ require(predicted == sender, "bad sender"); ``` ## 7) Validation logic that bundlers reject -Validation code can be correct in local tests and still be unusable in real bundlers. Public bundlers simulate `validateUserOp()` / `validatePaymasterUserOp()` off-chain and commonly run a full `debug_traceCall(handleOps)` before inclusion. +Validation code can be correct in local tests and still be unusable in real bundlers. Public bundlers simulate `validateUserOp()` / `validatePaymasterUserOp()` off-chain and commonly run a full `debug_traceCall(handleOps)` before inclusion.[[3]](#references) That makes these patterns dangerous inside validation: @@ -128,12 +128,11 @@ function initialize(address newOwner) external { - Run full bundler simulation (`simulateValidation` plus a traced `handleOps`) before shipping. - For ERC-7702, allow init only on self-call and only once. - - ## References - [1] [Six mistakes in ERC-4337 smart accounts (Trail of Bits)](https://blog.trailofbits.com/2026/03/11/six-mistakes-in-erc-4337-smart-accounts/) - [2] [ERC-4337: Account Abstraction Using Alt Mempool](https://eips.ethereum.org/EIPS/eip-4337) +- [3] [ERC-7562: Account Abstraction Validation Scope Rules](https://eips.ethereum.org/EIPS/eip-7562) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/blockchain/blockchain-and-crypto-currencies/web3-signing-workflow-compromise-safe-delegatecall-proxy-takeover.md b/src/blockchain/blockchain-and-crypto-currencies/web3-signing-workflow-compromise-safe-delegatecall-proxy-takeover.md index 5a015ebaf1b..a0d9e23216f 100644 --- a/src/blockchain/blockchain-and-crypto-currencies/web3-signing-workflow-compromise-safe-delegatecall-proxy-takeover.md +++ b/src/blockchain/blockchain-and-crypto-currencies/web3-signing-workflow-compromise-safe-delegatecall-proxy-takeover.md @@ -6,7 +6,7 @@ A cold-wallet theft chain combined a **supply-chain compromise of the Safe{Wallet} web UI** with an **on-chain delegatecall primitive that overwrote a proxy’s implementation pointer (slot 0)**. The key takeaways are: -- If a dApp can inject code into the signing path, it can make a signer produce a valid **EIP-712 signature over attacker-chosen fields** while restoring the original UI data so other signers remain unaware. +- If a dApp can inject code into the signing path, it can make a signer produce a valid **EIP-712 signature over attacker-chosen fields**[[4]](#references) while restoring the original UI data so other signers remain unaware. - Safe proxies store `masterCopy` (implementation) at **storage slot 0**. A delegatecall to a contract that writes to slot 0 effectively “upgrades” the Safe to attacker logic, yielding full control of the wallet. ## Off-chain: Targeted signing mutation in Safe{Wallet} @@ -35,7 +35,7 @@ if (isVictimSafe && isVictimSigner && tx.data.operation === 0) { - **EIP-712 opacity**: wallets showed structured data but did not decode nested calldata or highlight `operation = delegatecall`, making the mutated message effectively blind-signed. ### Gateway validation relevance -Safe proposals are submitted to the **Safe Client Gateway**. Prior to hardened checks, the gateway could accept a proposal where `safeTxHash`/signature corresponded to different fields than the JSON body if the UI rewrote them post-signing. After the incident, the gateway now rejects proposals whose hash/signature do not match the submitted transaction. Similar server-side hash verification should be enforced on any signing-orchestration API. +Safe proposals are submitted to the **Safe Client Gateway**.[[5]](#references) Prior to hardened checks, the gateway could accept a proposal where `safeTxHash`/signature corresponded to different fields than the JSON body if the UI rewrote them post-signing. After the incident, the gateway now rejects proposals whose hash/signature do not match the submitted transaction. Similar server-side hash verification should be enforced on any signing-orchestration API. ### 2025 Bybit/Safe incident highlights - The February 21, 2025 Bybit cold-wallet drain (~401k ETH) reused the same pattern: a compromised Safe S3 bundle only triggered for Bybit signers and swapped `operation=0` → `1`, pointing `to` at a pre-deployed attacker contract that writes slot 0.[[1]](#references)[[3]](#references) diff --git a/src/blockchain/smart-contract-security/mutation-testing-with-slither.md b/src/blockchain/smart-contract-security/mutation-testing-with-slither.md index ebf96d5234d..d9d09da34e5 100644 --- a/src/blockchain/smart-contract-security/mutation-testing-with-slither.md +++ b/src/blockchain/smart-contract-security/mutation-testing-with-slither.md @@ -48,9 +48,9 @@ Older mutation engines relied on regex or line-oriented rewrites. That works, bu - Generating every possible variant on a weak line wastes large amounts of runtime AST- or Tree-sitter-based tooling improves this by targeting structured nodes instead of raw lines:[[1]](#references) -- **slither-mutate** uses Slither's Solidity AST -- **mewt** uses Tree-sitter as a language-agnostic core -- **MuTON** builds on `mewt` and adds first-class support for TON languages such as FunC, Tolk, and Tact +- **slither-mutate** uses Slither's Solidity AST[[4]](#references) +- **mewt** uses Tree-sitter as a language-agnostic core[[6]](#references) +- **MuTON** builds on `mewt` and adds first-class support for TON languages such as FunC, Tolk, and Tact[[7]](#references) This makes multi-line constructs and expression-level mutations much more reliable than regex-only approaches. @@ -98,7 +98,7 @@ Mutation campaigns can take hours or days. Tips to reduce cost:[[1]](#refer - Parallelize tests if your runner allows it; cache dependencies/builds. - Fail-fast: stop early when a change clearly demonstrates an assertion gap. -The runtime math is brutal: `1000 mutants x 5-minute tests ~= 83 hours`, so campaign design matters as much as the mutator itself. +The runtime math is brutal: `1000 mutants x 5-minute tests ~= 83 hours`, so campaign design matters as much as the mutator itself.[[1]](#references) ## Persistent campaigns and triage at scale diff --git a/src/crypto/README.md b/src/crypto/README.md index 064ee1c0dc5..c246145b5a7 100644 --- a/src/crypto/README.md +++ b/src/crypto/README.md @@ -49,6 +49,6 @@ ctf-misc/README.md - Python: `python3 -m venv .venv && source .venv/bin/activate` - Libraries: `pip install pycryptodome gmpy2 sympy pwntools` -- SageMath (often essential for lattice/RSA/ECC): https://www.sagemath.org/ +- SageMath (often essential for lattice/RSA/ECC): {{#include ../banners/hacktricks-training.md}} diff --git a/src/crypto/crypto-in-malware/README.md b/src/crypto/crypto-in-malware/README.md index 3f5fa948b1c..3453414098e 100644 --- a/src/crypto/crypto-in-malware/README.md +++ b/src/crypto/crypto-in-malware/README.md @@ -20,7 +20,7 @@ If these are used, the second parameter is an `ALG_ID`: ![Windows crypto/compression APIs - CryptDeriveKey / CryptCreateHash: If these are used, the second parameter is an ALG ID](<../../images/image (156).png>) -Table: https://learn.microsoft.com/en-us/windows/win32/seccrypto/alg-id +Table: https://learn.microsoft.com/en-us/windows/win32/seccrypto/alg-id[[1]](#references) #### RtlCompressBuffer / RtlDecompressBuffer @@ -69,4 +69,8 @@ Packers transform a binary so static analysis is misleading (junk code, encrypte - A sudden strings explosion after a jump often indicates you reached unpacked code. - Dump memory and fix headers with tools like PE-bear. +## References + +- [1] [ALG_ID enumeration (Windows Win32 API reference)](https://learn.microsoft.com/en-us/windows/win32/seccrypto/alg-id) + {{#include ../../banners/hacktricks-training.md}} diff --git a/src/crypto/ctf-misc/README.md b/src/crypto/ctf-misc/README.md index 7c50de16772..e4ea35c0dcc 100644 --- a/src/crypto/ctf-misc/README.md +++ b/src/crypto/ctf-misc/README.md @@ -16,10 +16,14 @@ If a challenge gives you code that does not look like a standard language: - Use an online interpreter or a Docker image. - If the output is weird, look for layered encoding/compression after execution. -Good starting list: +Good starting list:[[1]](#references) {{#ref}} https://esolangs.org/wiki/Main_Page {{#endref}} +## References + +- [1] [Esolang, the esoteric programming languages wiki](https://esolangs.org/wiki/Main_Page) + {{#include ../../banners/hacktricks-training.md}} diff --git a/src/crypto/ctf-workflow/README.md b/src/crypto/ctf-workflow/README.md index fe63eea66a6..2e187549fca 100644 --- a/src/crypto/ctf-workflow/README.md +++ b/src/crypto/ctf-workflow/README.md @@ -177,4 +177,3 @@ pip install pycryptodome gmpy2 sympy pwntools z3-solver ``` {{#include ../../banners/hacktricks-training.md}} - diff --git a/src/crypto/public-key/README.md b/src/crypto/public-key/README.md index 533fe4e750a..949a7d6390c 100644 --- a/src/crypto/public-key/README.md +++ b/src/crypto/public-key/README.md @@ -2,6 +2,7 @@ {{#include ../../banners/hacktricks-training.md}} + Most CTF hard crypto ends up here: RSA, ECC/ECDSA, lattices, and bad randomness. ## Recommended tooling diff --git a/src/crypto/tls-and-certificates/README.md b/src/crypto/tls-and-certificates/README.md index 8bfcd95f743..0e6d07f3b7e 100644 --- a/src/crypto/tls-and-certificates/README.md +++ b/src/crypto/tls-and-certificates/README.md @@ -2,6 +2,7 @@ {{#include ../../banners/hacktricks-training.md}} + This area is about **X.509 parsing, formats, conversions, and common mistakes**. ## X.509: parsing, formats & common mistakes diff --git a/src/generic-hacking/archive-extraction-path-traversal.md b/src/generic-hacking/archive-extraction-path-traversal.md index 21106635dab..6d0ffcc0d41 100644 --- a/src/generic-hacking/archive-extraction-path-traversal.md +++ b/src/generic-hacking/archive-extraction-path-traversal.md @@ -5,7 +5,7 @@ ## Overview Many archive formats (ZIP, RAR, TAR, 7-ZIP, etc.) allow each entry to carry its own **internal path**. When an extraction utility blindly honours that path, a crafted filename containing `..` or an **absolute path** (e.g. `C:\Windows\System32\`) will be written outside of the user-chosen directory. -This class of vulnerability is widely known as *Zip-Slip* or **archive extraction path traversal**. +This class of vulnerability is widely known as *Zip-Slip* or **archive extraction path traversal**.[[6]](#references) Consequences range from overwriting arbitrary files to directly achieving **remote code execution (RCE)** by dropping a payload in an **auto-run** location such as the Windows *Startup* folder. @@ -114,9 +114,9 @@ ESET reported RomCom (Storm-0978/UNC2596) spear-phishing campaigns that attached ## Additional Affected / Historical Cases -* 2018 – Massive *Zip-Slip* advisory by Snyk affecting many Java/Go/JS libraries. +* 2018 – Massive *Zip-Slip* advisory by Snyk affecting many Java/Go/JS libraries.[[6]](#references) * 2023 – 7-Zip CVE-2023-4011 similar traversal during `-ao` merge. -* 2025 – HashiCorp `go-slug` (CVE-2025-0377) TAR extraction traversal in slugs (patch in v1.2). +* 2025 – HashiCorp `go-slug` (CVE-2025-0377) TAR extraction traversal in slugs (patch in v1.2).[[7]](#references) * Any custom extraction logic that fails to call `PathCanonicalize` / `realpath` prior to write. ## References @@ -126,6 +126,8 @@ ESET reported RomCom (Storm-0978/UNC2596) spear-phishing campaigns that attached - [3] [Meziantou – Prevent Zip Slip in .NET](https://www.meziantou.net/prevent-zip-slip-in-dotnet.htm) - [4] [0xdf – HTB Bruno ZipSlip → DLL hijack chain](https://0xdf.gitlab.io/2026/02/24/htb-bruno.html) - [5] [ESET Research – Update WinRAR tools now: RomCom and others exploiting zero-day vulnerability (CVE-2025-8088)](https://www.welivesecurity.com/en/eset-research/update-winrar-tools-now-romcom-and-others-exploiting-zero-day-vulnerability/) +- [6] [Snyk – Public Disclosure of a Critical Arbitrary File Overwrite Vulnerability: Zip Slip](https://snyk.io/blog/zip-slip-vulnerability/) +- [7] [HashiCorp – HCSEC-2025-01: go-slug Vulnerable to Zip Slip Attack (CVE-2025-0377)](https://discuss.hashicorp.com/t/hcsec-2025-01-hashicorp-go-slug-vulnerable-to-zip-slip-attack/72719) {{#include ../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/anti-forensic-techniques.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/anti-forensic-techniques.md index 9b8186b795c..8eb20229a0d 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/anti-forensic-techniques.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/anti-forensic-techniques.md @@ -178,7 +178,7 @@ Defenders should monitor for changes to those registry keys and high-volume remo Endpoint security products rely heavily on ETW. A popular 2024 evasion method is to patch `ntdll!EtwEventWrite`/`EtwEventWriteFull` in memory so every ETW call returns `STATUS_SUCCESS` -without emitting the event: +without emitting the event:[[5]](#references) ```c // 0xC3 = RET on x64 @@ -189,7 +189,7 @@ WriteProcessMemory(GetCurrentProcess(), ``` Public PoCs (e.g. `EtwTiSwallow`) implement the same primitive in PowerShell or C++. -Because the patch is **process-local**, EDRs running inside other processes may miss it. +Because the patch is **process-local**, EDRs running inside other processes may miss it.[[5]](#references) Detection: compare `ntdll` in memory vs. on disk, or hook before user-mode. ### Alternate Data Streams (ADS) Revival @@ -307,5 +307,6 @@ Defenders should correlate these artifacts with external exposure and service pa - [2] [Red Canary – Patching EtwEventWrite for Stealth: Detection & Hunting (June 2024)](https://redcanary.com/blog/etw-patching-detection) - [3] [Red Canary – Patching for persistence: How DripDropper Linux malware moves through the cloud](https://redcanary.com/blog/threat-intelligence/dripdropper-linux-malware/) - [4] [CVE‑2023‑46604 – Apache ActiveMQ OpenWire RCE (NVD)](https://nvd.nist.gov/vuln/detail/CVE-2023-46604) +- [5] [Hiding Your .NET - ETW (Adam Chester / XPN)](https://blog.xpnsec.com/hiding-your-dotnet-etw/) {{#include ../../banners/hacktricks-training.md}}