LEVEL 3

iofile_aw

pwnable
  • 문제 정보
  • 풀이 55
  • 난이도 투표 72
  • 질문 6
  • 최근 풀이자 461
  • 댓글 35

문제 설명

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이 제공됩니다.

난이도 투표 72

질문 6

문제 풀이에 어려움이 있으신가요?
커뮤니티에서 문제에 대한 질문하고 답변 얻기
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_
LEVEL 3

iofile_aw

pwnable

출제자 정보

avatar
Dreamhack
대표 업적 없음

First Blood!

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

최근 풀이자 461

avatar
NT_Abdullah
암호학 중급자
yeonwookim
.HACK 2024 참가자
kwww
대표 업적 없음
avatar
Axii
시스템 해킹 전문가
rockstaar
대표 업적 없음
avatar
foundme
대표 업적 없음
아이스아메리카노
대표 업적 없음
Ggozil
대표 업적 없음
avatar
Unreal
웹해킹 고인물

댓글 35

haehae
대표 업적 없음
뭔 종일 lb구하고있었네 ㅠ
c0met
.HACK 2025 참가자
그 누구도 믿지 말것
avatar
KnightChaser
공부벌레
Always interesting
avatar
Rosieblue
워게임 고인물
fgets 이용하는 문제
avatar
연님
답변 등록: 1
함수 내부 동작원리는 아직 헷갈리지만 재밌네요ㅎㅎ
arbitrary write & structure
whoamiii
대표 업적 없음
그게 그 구조를 가지고 있을꺼라고는 생각도 못했다...T.T 재미있고, 많이 배웠습니다.ㅎ
avatar
msh1307
대표 업적 없음
:)
avatar
5un9hun
세계수
좀만 생각해보면 엄청 쉬운 문제였습니다.
avatar
Polang
워게임: 1
이걸 왜 생각못했지 ㅎ