passcode : beg for me
(NO DRAG, NO PASSCODE)
이번 문제에서는 상당히 제약이 많다. 라이브러리 함수도 사용할 수 없으며 버퍼도 이용할 수 없고, RET의 뒷부분은 물론이거니와 ret, leave 함수들도 사용할 수 없다.
대신에 fgets 함수로 입력을 받는다. 바로 이 부분을 이용하면 될 것 같다. fgets 와 같이 어떠한 값들을 입력받는 함수들을 이용할 때 메모리에는 이 입력받은 값들을 일시적으로 저장하는 임시 버퍼가 생성된다.
모든 함수들은 스택에 올라갈 때 인자부터 올라가게 되므로, gdb 로 분석해보면 fgets를 call 하기 전에 0x8049a3c, 즉 stdin 임시 버퍼의 주소를 올린다.
우선 적당한 위치에 bp를 걸어준다. 걸어줄 부분은 fgets 호출 전, 호출 후, 그리고 프로그램 종료 직전이다.
우선 첫번째 bp 까지 이동해보자.
0x401068c0 라는 주소값이 나왔다. 이를 다시 살펴보니 <_IO_2_1_stdin_> 가 나왔다. 이 stdin 의 객체는 _IO_FILEtype 으로 /usr/include/libio.h 파일에 그에 대한 형식이 나와있다.
struct _IO_FILE {
int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags
/* The following pointers correspond to the C++ streambuf protocol. */
/* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
char* _IO_read_ptr; /* Current read pointer */
char* _IO_read_end; /* End of get area. */
char* _IO_read_base; /* Start of putback+get area. */
char* _IO_write_base; /* Start of put area. */
...
}
위와 같이 두번째 영역은 임시 버퍼의 끝지점, 그리고 네번째 영역은 임시 버퍼의 시작 지점이다.
이를 이용하여 임시 버퍼에 shellcode를 넣어주고 RET 주소를 임시 버퍼의 시작 주소로 변조하면 다음과 같은 과정에 의해서 쉘이 따질 것 같다. 또한 xavius.c 코드에서 보면 임시버퍼에 NOP 가 포함되어 있어야 while 문을 벗어날 수 있을 것 같다.
- buffer 에 NOP + shellcode + SFP + RET(&(임시 버퍼)) 가 저장됨
- RET에 임시 버퍼의 시작 주소가 들어가 있으므로 eip가 임시버퍼 주소로 이동
- 임시버퍼에 NOP + shellcode 가 있으므로 쉘 실행
바로 payload를 짜서 exploit 해보자.
[xavius] : throw me away
'Pwnable > LOB' 카테고리의 다른 글
[LOB] 20. DEATH_KNIGHT (0) | 2020.08.28 |
---|---|
[LOB] 19. XAVIUS (0) | 2020.08.28 |
[LOB] 17. SUCCUBUS (0) | 2020.08.28 |
[LOB] 16. ZOMBIE_ASSASSIN (0) | 2020.08.28 |
[LOB] 15. ASSASSIN (0) | 2020.08.28 |