# Jersey CTF ## lottery (exit hijacking) - về bug thì khá là cơ bản (lộ thiên) với heap overflow; hướng khai thác sẽ là tcache poisonning - Tuy nhiên vấn đề chính là ở phiên bản libc mới thì malloc_hook, free_hook, ... đã bị xóa - Thêm đó kêt thúc chương trình lại dùng exit() ## way 1: exit hijacking - Để thực hiện được thì cần leak : - offset 0x30 của fs_base -> Việc này bắt buộc chúng ta phải có phải có địa chỉ của TLS hoặc ít nhất là địa chỉ libc vì offset của TLS của libc hên xui thì cố định -> Sau đó leak như leak biến environ - Để giải thích tại sao thì phải đọc source (nhưng mà cái này cũng tùy vào phiên bản nhưng mih làm cái khó nhất thì cái sau sẽ dễ thui ) - ta có [source code](https://elixir.bootlin.com/glibc/glibc-2.35/source/stdlib/exit.c#L141) - Khi exit -> exit_handle -> ở đây sẽ call `function_pointer` hoặc `_exit` ![image](https://hackmd.io/_uploads/SJ5A21d6ke.png) - Ở 1 : đưa hàm vào con trỏ hàm onfct - ở 2 : giải mã (đây chính là lí do phải leak fs_base:0x30) - call con trỏ hàm ![image](https://hackmd.io/_uploads/SyMwTyO6Je.png) -> nó sẽ call hàm ở `initial+24` (đen là bị mã hóa nhưng đã có cách ) -> Target sẽ là ghi system sẽ vào đó -> còn ở initial + 32 = địa chỉ /bin/sh - Mã hóa ```py def rol(value, bits, size=64): return ((value << bits) | (value >> (size - bits))) & ((1 << size) - 1) # Thuật toán mã hóa def encrypt_exit(original_value, fs_30): # Bước 1: XOR với fs_30 xor_result = original_value ^ fs_30 # Bước 2: Xoay trái (ROL) 17 bit encrypted = rol(xor_result, 0x11) return encrypted ``` -> original_value chính là địa chỉ hàm system nếu muốn gọi shell ## way 2: overwrite return address of read function