본문 바로가기

system/writeup

2015 codegate yocto

yocto

2015 codegate - yocto

glob 전역 변수에 80바이트 입력을 받는다.

그리고 밑에서 v2로 점프하는데 이 부분에 대한 어셈을 보면

push eax, push edx를 하고 점프를 하는데 eax와 edx를 보면

ebp+var_14, ebp+var_C를 넣고 점프를 한다. 이에 대한 값을 확인해 보면

atoi의 반환 값이 들어간다는 것을 알 수 있다.

즉, ebp+var_14에는 atoi(glob)의 반환 값이,

ebp+var_C에는 atoi(v0+1)의 값이 들어가는 것이다.

 

payload를 입력할 전역변수 glob과 값을 push하고 jmp할 수 있는 구문은 RTDL(Return To Dynamic Linker)을 가능하게 한다.

 

RTDL 과정을 간략히 설명하면

  1. reloc_offset, link_map 두 개를 push한 후 _dl_runtime_reslove 함수를 부름
  2. reloc_offset, link_map 두 개를 인자로 _dl_fixup 함수를 부름
  3. _dl_fixup 함수에서 해당 함수의 STRTAB과 JMPREL의 주소를 구한 후 JMPREL의 인덱스를 참조하여 해당 함수의 SYMTAB을, SYMTAB에서 함수의 offset을 구한 후 STRTAB에서 함수 이름을 가져온다.
  4. 가져온 함수 이름을 인자로 _dl_lookup_symbol_x 함수를 부른다. 여기서 인자로 넘겨준 함수의 실제 got가 반환 값으로 오게 된다.

 

그리고 이를 토대로 한 yocto RTDL 과정은 다음과 같다.

  1. reloc_offset을 조작하여 JMPREL이 아닌 나의 payload를 가르키도록 설정한다.
  2. JMPREL의 인덱스를 조작하여 내 payload 안에 있는 SYMTAB을 가르키도록 설정한다.
  3. SYMTAB의 함수 offset을 조작하여 내 payload 안에 있는 "system" string을 가르키도록 설정한다.

 

또, 익스플로잇 과정에서 undefined_symbol 오류가 나는 경우가 있는데, _dl_lookup_symbol_x 함수 내에서의 패딩 관련 문제인 것 같다. 그래서 '\x00'을 dummy로 조금 넣어줬다.

또, 풀고 나서 다른 사람들꺼 라업을 보니 이상한 설명이 좀 있던데 system 함수 실행 후 들어가는 인자는 다음과 같다.

jmp ecx 하기 전 push eax, push edx를 해주는데 여기서 eax는 atoi(glob)의 반환 값이고 ecx는 atoi(v0+1)의 반환 값이다.

즉 eax에 우리의 payload가 들어간다. 스택에서 보이는 .456 부분이다. (.123.456을 입력했음)

이게 인자가 되는 이유는 push reloc_offset을 건너 뛰고 dl로 바로 이동했으므로 0x7b는 신경 안써도 되고 0x0은 ret 부분이기 때문에 .456이 인자가 되는 것이다.

 

성공적으로 쉘을 획득하였다.


'system > writeup' 카테고리의 다른 글

2014 codegate angry_doraemon  (0) 2019.01.04
2013 hdcon luckyzzang  (0) 2019.01.02
2016 whithat malloc  (0) 2019.01.01
pwnable.kr alloca - 80pt  (0) 2018.12.27
pwnable.kr loveletter - 50pt  (0) 2018.12.26