From 9be247edc07185a8e034e5788f0efe9a5c3049c7 Mon Sep 17 00:00:00 2001 From: CPol Date: Wed, 12 Jun 2024 15:23:07 +0000 Subject: [PATCH] GITBOOK-4354: No subject --- SUMMARY.md | 3 +- .../aw2exec-__malloc_hook.md | 27 +++++++++++- binary-exploitation/heap/fast-bin-attack.md | 15 +++++-- binary-exploitation/heap/large-bin-attack.md | 19 +++++++- binary-exploitation/heap/tcache-bin-attack.md | 43 +++++++++++++++++++ .../heap/unsorted-bin-attack.md | 18 ++++++-- 6 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 binary-exploitation/heap/tcache-bin-attack.md diff --git a/SUMMARY.md b/SUMMARY.md index c76bee72e..e688d3892 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -736,6 +736,7 @@ * [Fast Bin Attack](binary-exploitation/heap/fast-bin-attack.md) * [Unsorted Bin Attack](binary-exploitation/heap/unsorted-bin-attack.md) * [Large Bin Attack](binary-exploitation/heap/large-bin-attack.md) + * [Tcache Bin Attack](binary-exploitation/heap/tcache-bin-attack.md) * [Off by one overflow](binary-exploitation/heap/off-by-one-overflow.md) * [House of Spirit](binary-exploitation/heap/house-of-spirit.md) * [House of Lore](binary-exploitation/heap/house-of-lore.md) @@ -762,7 +763,7 @@ * [WWW2Exec - atexit()](binary-exploitation/arbitrary-write-2-exec/www2exec-atexit.md) * [WWW2Exec - .dtors & .fini\_array](binary-exploitation/arbitrary-write-2-exec/www2exec-.dtors-and-.fini\_array.md) * [WWW2Exec - GOT/PLT](binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md) - * [WWW2Exec - \_\_malloc\_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-\_\_malloc\_hook.md) + * [WWW2Exec - \_\_malloc\_hook & \_\_free\_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-\_\_malloc\_hook.md) * [Common Exploiting Problems](binary-exploitation/common-exploiting-problems.md) * [Windows Exploiting (Basic Guide - OSCP lvl)](binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md) diff --git a/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md b/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md index a332eb9d7..413a9f045 100644 --- a/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md +++ b/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md @@ -1,4 +1,4 @@ -# WWW2Exec - \_\_malloc\_hook +# WWW2Exec - \_\_malloc\_hook & \_\_free\_hook
@@ -30,6 +30,31 @@ More info about One Gadget in: Note that hooks are **disabled for GLIBC >= 2.34**. There are other techniques that can be used on modern GLIBC versions. See: [https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md). {% endhint %} +## Free Hook + +This was abused in one of the example from the page abusing a fast bin attack after having abused an unsorted bin attack: + +{% content-ref url="../heap/unsorted-bin-attack.md" %} +[unsorted-bin-attack.md](../heap/unsorted-bin-attack.md) +{% endcontent-ref %} + +Now a **fast bin attack** is performed: + +* First of all it's discovered that it's possible to work with fast **chunks of size 200** in the **`__free_hook`** location: +*
gef➤  p &__free_hook
+  $1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
+  gef➤  x/60gx 0x7ff1e9e607a8 - 0x59
+  0x7ff1e9e6074f: 0x0000000000000000      0x0000000000000200
+  0x7ff1e9e6075f: 0x0000000000000000      0x0000000000000000
+  0x7ff1e9e6076f <list_all_lock+15>:      0x0000000000000000      0x0000000000000000
+  0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000      0x0000000000000000
+  
+ * If we manage to get a fast chunk of size 0x200 in this location, it'll be possible to overwrite a function pointer that will be executed +* For this, a new chunk of size `0xfc` is created and the merged function is called with that pointer twice, this way we obtain a pointer to a freed chunk of size `0xfc*2 = 0x1f8` in the fast bin. +* Then, the edit function is called in this chunk to modify the **`fd`** address of this fast bin to point to the previous **`__free_hook`** function. +* Then, a chunk with size `0x1f8` is created to retrieve from the fast bin the previous useless chunk so another chunk of size `0x1f8` is created to get a fast bin chunk in the **`__free_hook`** which is overwritten with the address of **`system`** function. +* And finally a chunk containing the string `/bin/sh\x00` is freed calling the delete function, triggering the **`__free_hook`** function which points to system with `/bin/sh\x00` as parameter. + ## References * [https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook](https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook) diff --git a/binary-exploitation/heap/fast-bin-attack.md b/binary-exploitation/heap/fast-bin-attack.md index bfcdc88ab..a13b8e937 100644 --- a/binary-exploitation/heap/fast-bin-attack.md +++ b/binary-exploitation/heap/fast-bin-attack.md @@ -16,6 +16,12 @@ Other ways to support HackTricks: ## Basic Information +For more information about what is a fast bin check this page: + +{% content-ref url="bins-and-memory-allocations.md" %} +[bins-and-memory-allocations.md](bins-and-memory-allocations.md) +{% endcontent-ref %} + Because the fast bin is single linked, there are much less protections than in other bins and just **modifying an address in a freed fast bin** chunk is enough to be able to **allocate later a chunk in any memory address**. As summary: @@ -127,9 +133,12 @@ int main(void) printf("\n\nJust like that, we executed a fastbin attack to allocate an address to a stack variable using malloc!\n"); } - ``` +{% hint style="danger" %} +If it's possible to overwrite the value of the global variable **`global_max_fast`** with a big number, this allows to generate fast bin of bigger sizes, potentially allowing to perform fast bin attacks in scenarios where it wasn't possible previously. +{% endhint %} + ## Examples * **CTF** [**https://guyinatuxedo.github.io/28-fastbin\_attack/0ctf\_babyheap/index.html**](https://guyinatuxedo.github.io/28-fastbin\_attack/0ctf\_babyheap/index.html)**:** @@ -141,8 +150,8 @@ int main(void) * There is a heap overflow and user after free and double free because when a chunk is freed it's possible to reuse and re-free the pointers * **Libc info leak**: Just free some chunks and they will get a pointer to a part of the main arena location. As you can reuse freed pointers, just read this address. * **Fast bin attack**: All the pointers to the allocations are stored inside an array, so we can free a couple of fast bin chunks and in the last one overwrite the address to point a bit before this array of pointers. Then, allocate a couple of chunks with the same size and we will get first the legit one and then the fake one containing the array of pointers. We can now overwrite this allocation pointers to point to the got address of `free` to point to system and then write chunk 1 `"/bin/sh"` to then `free(chunk1)` which will execute `system("/bin/sh")`. - -You can find a Fast Bin attack abused through an unsorted bin attack in the examples from: +* You can find a Fast Bin attack abused through an unsorted bin attack. + * Note {% content-ref url="unsorted-bin-attack.md" %} [unsorted-bin-attack.md](unsorted-bin-attack.md) diff --git a/binary-exploitation/heap/large-bin-attack.md b/binary-exploitation/heap/large-bin-attack.md index e3f03d0ec..e82e4c214 100644 --- a/binary-exploitation/heap/large-bin-attack.md +++ b/binary-exploitation/heap/large-bin-attack.md @@ -16,22 +16,34 @@ Other ways to support HackTricks: ## Basic Information +For more information about what is a large bin check this page: + +{% content-ref url="bins-and-memory-allocations.md" %} +[bins-and-memory-allocations.md](bins-and-memory-allocations.md) +{% endcontent-ref %} + It's possible to find a great example in [**how2heap - large bin attack**](https://github.com/shellphish/how2heap/blob/master/glibc\_2.35/large\_bin\_attack.c). -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. +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: * A large chunk is allocated * A large chunk smaller than the first one but in the same index is allocated + * Must be smalled so in the bin it must go first * (A chunk to prevent merging with the top chunk is created) * Then, the first large chunk is freed and a new chunk bigger than it is allocated -> Chunk1 goes to the large bin * Then, the second large chunk is freed * Now, the vulnerability: The attacker can modify `chunk1->bk_nextsize` to `[target-0x20]` * Then, a larger chunk than chunk 2 is allocated, so chunk2 is inserted in the large bin overwriting the address `chunk1->bk_nextsize->fd_nextsize` with the address of chunk2 -This is the code (and the reason why chunk2 must be smaller than chunk1). Comments have been added to understand betetr how the address was overwritten: +{% hint style="success" %} +There are other potential scenarios, the thing is to add to the large bin a chunk that is **smaller** than a current X chunk in the bin, so it need to be inserted just before it in the bin, and we need to be able to modify X's **`bk_nextsize`** as thats where the address of the smaller chunk will be written to. +{% endhint %} +This is the relevant code from malloc. Comments have been added to understand better how the address was overwritten: + +{% code overflow="wrap" %} ```c /* if smaller than smallest, bypass loop below */ assert (chunk_main_arena (bck->bk)); @@ -45,9 +57,12 @@ if ((unsigned long) (size) < (unsigned long) chunksize_nomask (bck->bk)) fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; // p1->fd->bk_nextsize->fd_nextsize = p2 } ``` +{% endcode %} This could be used to **overwrite the `global_max_fast` global variable** of libc to then exploit a fast bin attack with larger chunks. +You can find another great explanation of this attack in [**guyinatuxedo**](https://guyinatuxedo.github.io/32-largebin\_attack/largebin\_explanation0/index.html). +
Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)! diff --git a/binary-exploitation/heap/tcache-bin-attack.md b/binary-exploitation/heap/tcache-bin-attack.md new file mode 100644 index 000000000..afb04f957 --- /dev/null +++ b/binary-exploitation/heap/tcache-bin-attack.md @@ -0,0 +1,43 @@ +# Tcache Bin Attack + +
+ +Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)! + +Other ways to support HackTricks: + +* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)! +* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com) +* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family) +* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** +* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos. + +
+ +## Basic Information + +For more information about what is a tcache bin check this page: + +{% content-ref url="bins-and-memory-allocations.md" %} +[bins-and-memory-allocations.md](bins-and-memory-allocations.md) +{% endcontent-ref %} + +First of all, note that the Tcache was introduced in glibc version 2.26. + +The **Tcache** attack proposed in the [**guyinatuxido page**](https://guyinatuxedo.github.io/29-tcache/tcache\_explanation/index.html) is very similar to the fast bin attack where the goal is to overwrite the pointer to the next chunk in the bin inside a freed chunk to an arbitrary address so later it's possible to **allocate that specific address and potentially overwrite pointes**. + +However, nowadays, if you run the mentioned code you will get the error: **`malloc(): unaligned tcache chunk detected`**. So, it's needed to write as address in the new pointer an aligned address (or execute enough times the binary so the written address is actually aligned). + +
+ +Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)! + +Other ways to support HackTricks: + +* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)! +* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com) +* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family) +* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** +* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos. + +
diff --git a/binary-exploitation/heap/unsorted-bin-attack.md b/binary-exploitation/heap/unsorted-bin-attack.md index a92183403..f6ca0c98b 100644 --- a/binary-exploitation/heap/unsorted-bin-attack.md +++ b/binary-exploitation/heap/unsorted-bin-attack.md @@ -16,18 +16,30 @@ Other ways to support HackTricks: ## Basic Information -When malloc, unsorted lists are able to write the address to `unsorted_chunks (av)` in the `bk` address of the chunk. Therefore, if an attacker can modify the address of the bk pointer in a chunk inside the unsorted bin, he could be able to write that address in an arbitrary address (maybe in the stack in a variable he can read) which could be helpful to leak a libc addresses. +For more information about what is an unsorted bin check this page: + +{% content-ref url="bins-and-memory-allocations.md" %} +[bins-and-memory-allocations.md](bins-and-memory-allocations.md) +{% endcontent-ref %} + +Unsorted lists are able to write the address to `unsorted_chunks (av)` in the `bk` address of the chunk. Therefore, if an attacker can **modify the address of the bk pointer** in a chunk inside the unsorted bin, he could be able to **write that address in an arbitrary address** which could be helpful to leak a libc addresses or bypass some defense. + +So, basically, this attack allowed to **overwrite some arbitrary address with a big number** (an address which could be a heap address or a libc address) like some stack address that could be leak or some restriction like the global variable **`global_max_fast`** to allow to create fast bin bins with bigger sizes (and pass from an unsorted bin atack to a fast bin attack). {% hint style="success" %} -Taking a look to the example provided in [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted\_bin\_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted\_bin\_attack/#principle) and using 0x4000 and 0x5000 instead of 0x400 and 0x500 as chunk sizes (to avoid tcaches) it's possible to see that nowadays the error `malloc(): unsorted double linked list corrupted` is triggered. +Taking a look to the example provided in [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted\_bin\_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted\_bin\_attack/#principle) and using 0x4000 and 0x5000 instead of 0x400 and 0x500 as chunk sizes (to avoid tcaches) it's possible to see that **nowadays** the error **`malloc(): unsorted double linked list corrupted`** is triggered. Therefore, this unsorted bin attack now (among other checks) also requires to be able to fix the doubled linked list so this is bypassed `victim->bck->fd == victim` or not `victim->fd == av (arena)`. Which means that the address were we want to right must have the address of the fake chunk in its `fd` position and that the fake chunk `fd` is pointing to the arena. {% endhint %} {% hint style="danger" %} Note that this attack corrupts the unsorted bin (hence small and large too). So we can only **use allocations from the fast bin now** (a more complex program might do other allocations and crash), and to trigger this we must **alloc the same size or the program will crash.** + +Note that making **`global_max_fast`** might help in this case trusting that the fast bin will be able to take care of all the other allocations until the exploit is completed. {% endhint %} +The code from [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin\_attack/unsorted\_explanation/index.html) explains it very well, although if you modify the mallocs to allocate memory big enough so don't end in a tcache you can see that the previously mentioned error appears preventing this technique: **`malloc(): unsorted double linked list corrupted`** + ## References & Other examples * [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted\_bin\_attack/#hitcon-training-lab14-magic-heap**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted\_bin\_attack/#hitcon-training-lab14-magic-heap) @@ -40,7 +52,7 @@ Note that this attack corrupts the unsorted bin (hence small and large too). So * The merge function is vulnerable because if both indexes passed are the same one it'll realloc on it and then free it but returning a pointer to that freed region that can be used. * Therefore, **2 chunks are created**: **chunk0** which will be merged with itself and chunk1 to prevent consolidating with the top chunk. Then, the **merge function is called with chunk0** twice which will cause a use after free. * Then, the **`view`** function is called with index 2 (which the index of the use after free chunk), which will **leak a libc address**. - * As the binary has protections to only malloc sizes bigger than `global_max_fast` so no fastbin is used, an unsorted bin attack is going to be used to overwrite the global variable `global_max_fast`. + * As the binary has protections to only malloc sizes bigger than **`global_max_fast`** so no fastbin is used, an unsorted bin attack is going to be used to overwrite the global variable `global_max_fast`. * Then, it's possible to call the edit function with the index 2 (the use after free pointer) and overwrite the `bk` pointer to point to `p64(global_max_fast-0x10)`. Then, creating a new chunk will use the previously compromised free address (0x20) will **trigger the unsorted bin attack** overwriting the `global_max_fast` which a very big value, allowing now to create chunks in fast bins. * Now a **fast bin attack** is performed: * First of all it's discovered that it's possible to work with fast **chunks of size 200** in the **`__free_hook`** location: