LEVEL 3

iofile_aw

pwnable
  • 문제 정보
  • 풀이 41
  • 난이도 투표 28
  • 질문 5
  • 최근 풀이자 281
  • 댓글 34

문제 설명

Description

이 문제는 서버에서 작동하고 있는 서비스(iofile_aw)의 바이너리와 소스 코드가 주어집니다.
프로그램의 취약점을 찾고 익스플로잇해 get_shell 함수를 실행시키세요.
셸을 획득한 후, "flag" 파일을 읽어 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
플래그의 형식은 DH{...} 입니다.

Environment
Ubuntu 16.04
Arch:     amd64-64-little
RELRO:    Full RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x400000)
Reference

_IO_FILE

Challenge Updates

2023.05.09: Dockerfile이 제공됩니다.

출제자 정보

avatar
Dreamhack
대표 업적 없음

First Blood!

avatar
빈체로파스타 포일점
워게임: 20
출제된 지 2일 만에 풀이 완료!

난이도 투표 28

질문 5

문제 풀이에 어려움이 있으신가요?
커뮤니티에서 문제에 대한 질문하고 답변 얻기
fgets 작동원리 질문..
우선 풀다가 못풀겠어서 다른 사람들이 푼 writeup을 봤습니다. 봤는데 char* _IO_buf_base; 이 변수를 조작해서 exploit했습니다. 그러나 제가 지금 분석하는 과정에서는 _IO_buf_base를 어디서 사용하는지 알수가 없습니다 ㅠㅠ glibc-2.23 source code를 보면서 fgets함수의 구현을 보면서 디버깅하니 fgets는 결국 _IO_getline(char *buf, size_t size, int n, _IO_FILE *fp) 함수를 호출합니다. char * __fgets_chk (char *buf, size_t size, int n, _IO_FILE *fp) { // 중략 fp->_IO_file_flags &= ~_IO_ERR_SEEN; count = _IO_getline (fp, buf, MIN ((size_t) n - 1, size), '\n', 1); // 중략 return result; } 그리고 _IO_getline함수는 _IO_getline_info를 호출합니다. _IO_size_t _IO_getline (_IO_FILE *fp, char *buf, _IO_size_t n, int delim, int extract_delim) { return _IO_getline_info (fp, buf, n, delim, extract_delim, (int *) 0); } 그리고 이제 _IO_getline_info 함수를 보면 _IO_size_t _IO_getline_info (_IO_FILE *fp, char *buf, _IO_size_t n, int delim, int extract_delim, int *eof) { char *ptr = buf; if (eof != NULL) *eof = 0; if (__builtin_expect (fp->_mode, -1) == 0) _IO_fwide (fp, -1); while (n != 0) { _IO_ssize_t len = fp->_IO_read_end - fp->_IO_read_ptr; if (len <= 0) { int c = __uflow (fp); if (c == EOF) { if (eof) *eof = c; break; } if (c == delim) { if (extract_delim > 0) *ptr++ = c; else if (extract_delim < 0) _IO_sputbackc (fp, c); if (extract_delim > 0) ++len; return ptr - buf; } *ptr++ = c; n--; } else { char *t; if ((_IO_size_t) len >= n) len = n; t = (char *) memchr ((void *) fp->_IO_read_ptr, delim, len); if (t != NULL) { _IO_size_t old_len = ptr-buf; len = t - fp->_IO_read_ptr; if (extract_delim >= 0) { ++t; if (extract_delim > 0) ++len; } memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len); fp->_IO_read_ptr = t; return old_len + len; } memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len); fp->_IO_read_ptr += len; ptr += len; n -= len; } } return ptr - buf; } 이 부분을 아무리 봐도 _IO_buf_base를 어디서 사용하는지 모르겠습니다. 답변해주시면 감사하겠습니다 ㅠ 수정--------- 성급한 질문 죄송합니다.. writeup 코드로 디버깅하는 과정에서 호출되는 부분을 찾았습니다. int c = __uflow (fp); ... return _IO_UFLOW (fp); // _IO_default_uflow 호출 ... int ch = _IO_UNDERFLOW (fp); // _IO_file_underflow 호출 ... int _IO_new_file_underflow (_IO_FILE *fp) // 내부에 있습니다.. `
dong_

최근 풀이자 281

avatar
urdekcah
워게임 고인물
avatar
Ajirika
대표 업적 없음
abcde
강의 수강: 1
avatar
MurphyLaw
대표 업적 없음
mii
대표 업적 없음
M1r
대표 업적 없음
Bluebird
Dreamhack CTF S2 Ⅵ 참여
이부리
대표 업적 없음
찌롱이
대표 업적 없음
avatar
Tjdmin1
워게임 고인물

댓글 34

avatar
KnightChaser
공부벌레
Always interesting
avatar
Rosieblue
워게임 고인물
fgets 이용하는 문제
avatar
연님
답변 등록: 1
함수 내부 동작원리는 아직 헷갈리지만 재밌네요ㅎㅎ
avatar
착한 범고래
워게임: 50
arbitrary write & structure
whoamiii
대표 업적 없음
그게 그 구조를 가지고 있을꺼라고는 생각도 못했다...T.T 재미있고, 많이 배웠습니다.ㅎ
avatar
msh1307
대표 업적 없음
:)
avatar
5un9hun
워게임 고인물
좀만 생각해보면 엄청 쉬운 문제였습니다.
avatar
Polang
워게임: 1
이걸 왜 생각못했지 ㅎ
eean
워게임 고인물
문제 구조가 재밌네요
ReverserInThirties
대표 업적 없음
.... Stack Buffer Overflow.....