vtable_bypass.py질문!!!
  1. lock값에 왜 저 값이 들어가는지 의문(fp+0x80)

  2. vtable다음에 쉘 함수가 있어도 어떻게 fp->_s.allocate_buffer가 이 위치를 알 수 있나
    즉, fp->_s.allocate_buffer함수가 쉘 함수(?)의 위치를 어떻게 특정하나?

#시스템해킹
작성자 정보
답변 1
Karatus
워게임: 50

lock값은 어따 쓰는지 저도 코드 찾아보다가 포기했고(멀티스레드 환경에서 쓰이는 값이니까 아마 그런 관련 헤더파일에 있지 않을까는 싶은데..)

두 번째 질문에 대한 답은 해드리겠습니다.

코드 확인

코드 확인해보시면 이렇게 되어있습니다.

int
_IO_str_overflow (_IO_FILE *fp, int c)
{
	...
	new_buf = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
    	...
}

fp는 저희가 봤던 _IO_FILE의 포인터인데 지금 강제형변환으로 _IO_strfile 포인터라고 해석하게 해놨습니다.
그럼 기존에 각 오프셋 별로 해석되던게 어떻게 바뀌었는지만 확인하면 도대체 _s._allocate_buffer가 뭔지 알 수 있습니다.

_IO_strfile 구조체

glibc-2.27/source/libio/strfile.h에 다음과 같이 정의되어 있습니다.

struct _IO_str_fields
{
  _IO_alloc_type _allocate_buffer;
  _IO_free_type _free_buffer;
};

struct _IO_streambuf
{
  struct _IO_FILE _f;
  const struct _IO_jump_t *vtable;
};

typedef struct _IO_strfile_
{
  struct _IO_streambuf _sbf;
  struct _IO_str_fields _s;
} _IO_strfile;

_IO_strfile 내부에 또다시 _IO_streambuf, _IO_str_fields 구조체가 있습니다.
바로 위에 있는 _IO_streambuf 구조체를 보면 생김새가 어디서 많이 본 구조체 아닙니까?

네 바로 _IO_FILE_plus와 그냥 같습니다. (앞에 struct, const 붙은거 제외하면 같음. 결국 틀은 같음)
그렇다면 이제 살펴볼 건 바로 밑에 있는 _IO_str_fields 구조체 밖에 없습니다.

마침 이름도 _s라 저희가 찾던 녀석 중 하나입니다.
멤버를 보면 저희가 유심히 살펴봐야 할 _allocate_buffer이 보입니다.
이 녀석의 타입이 뭐냐하면 같은 헤더 파일 내부에 정의되어 있는 void * 입니다.

typedef void *(*_IO_alloc_type) (_IO_size_t);
typedef void (*_IO_free_type) (void*);

결국 이 구조체가 지닌 구조는 알기 쉽게 풀면 이렇습니다.

_IO_FILE_plus 
-----------------------------
void * (_s._allocate_buffer)

그러니까 그냥 구조체에서 전달한 버퍼(new_size) 조작해준 다음에 마지막에 하나(system) 붙이면 system(new_size)가 호출되었던 겁니다.

2021.04.25. 23:24
질문에 대한 답을 알고 계신가요?
지식을 나누고 포인트를 획득해보세요.
답변하고 포인트 받기