Training 2020 #4 ( Trampoline )

이번 문제는 전과 같은 소스코드에 ASLR 보호기법이 추가된 문제이다. 우선 ASLR 보호기법에 대해 알아보자.

ASLR ( Address Space Layout Randomize ) : 각 프로세스 안의 스택이 임의의 주소의 위치하도록 하는 기법

말 그대로 주소를 계속 바꾸어주는 보호 기법이다.

여기서 이 ASLR 기법을 우회하기 위한 방법으로 고안된 것이 trampolline technique 이다.


ASLR 기법의 특징

ASLR은 위에서 설명한 것과 같이 각 프로세스 안의 스택이 임의의 주소의 위치하도록 하는 기법이다.

image

우리는 전에 이러한 과정을 통해 익스코드를 짯다.

image

하지만 ASLR 보호 기법을 적용하면 위와 같이 스택의 주소가 계속 바뀌게되어 어디로 변조해야 할지를 몰라 익스를 못하게 하는 보호 기법이다.

이 ASLR의 경우 Windows 와 리눅스의 경우로 나눌 수 있다.

  • Windows

    • 사용하는 DLL 중 어떤 DLL은 고정 주소를 가지고, 어떤 DLL은 ASLR기법을 적용하는 경우가 생길 수 있다. 이 때, 고정주소를 가지는 모듈( EXE, DLL )의 주소를 이용할 수 있다.
  • Linux

    • OS의 설정에 따라 ASLR이 적용된다.

우리는 Windows 환경에서 실습을 할건데 고정 주소를 가지고 있는 모듈을 이용하여 스택의 Return Address에 직접 점프하는 것이 아니라, "JMP 레지스터"가 있는 곳으로 점프하여 동적으로 버퍼 주소로 이동하는 기법이다.


Trampoline Technique 개념

image

  1. SFP까지 더미바이트 즉, 쓰레기 값을 채운다.
  2. 동적 주소를 가진 모듈의 JMP ESP 코드를 찾는다. ( 반드시 JMP ESP 코드일 필요는 없다. 특정 레지스터에 스택 주소가 들어있다면, 그리고 그 위치에 Stack BOF를 이용하여 원하는 값을 넣을 수 있다면 가능하다. )
  3. RET에 JMP ESP 코드의 주소를 넣고 그 뒷부분에 SHELL CODE로 채운다.
  4. JMP ESP 코드로 이동하여 JMP ESP를 실행
  5. ESP위치(SHELL CODE)에 EIP를 가져옴
  6. SHELL CODE 실행

이런 시나리오가 가능


실습

image

( imm으로 reader.exe 첫번째 실행 )

image

( imm으로 reader.exe 두번째 실행 )

첫번째 실행했을때는 main의 주소가 001E1000 이었지만 두번째에는 00D6100 으로 바뀌었다. 위와 같이 ASLR 기법이 적용되어 메모리의 주소가 계속 랜덤하게 바뀌는 것을 확인할 수 있다.

image

( imm 두번째 실행시 모듈들의 주소 )

image

( imm 세번째 실행시 모듈들의 주소 )

위와 같이 reader.exe에는 ASLR 기법이 적용되어 주소가 계속 바뀌지만 KERNELBASE.dll, kernel32.dll, ntdll.dll 들은 고정 주소를 가지고 있는 것을 확인할 수 있다.

image

저번에 옮겨둔 mona 플러그인으로 !mona modules 라는 명령어를 입력하면 어떤 보호기법이 걸려있는지 각 모듈마다 확인할 수 있다.

나는 kernel32.dll 에서 JMP ESP 코드를 찾기로 하였다.

  • 참고

    • 명령어 검색으로 JMP ESP 를 찾아도 되고 FF E4 기계어를 찾아도 된다.

    • 실제 코드가 JMP ESP 로 코딩된게 아니라 어떤 주소나 값 등이 우연히 FF E4 여도 된다.

      • Executable 하고 ASLR이 적용되지 않은 영역에 있는 것이 중요!

image

kernel32.dll 로 들어가 Ctrl + F 를 눌러 jmp esp를 검색해 주자.

image

나는 75C8F8F7에 JMP ESP 코드가 있었다. 이 주소를 기억해두자.

image

Lab4 폴더 안에 위 파일과 같은 excode가 있을텐데 jmp 주소를 위에서 기억해두었던 주소로 바꾸어주자.

image

그 후 파이썬 파일을 실행한뒤 생성된 test.txt 파일을 인자로 넣어주면 성공적으로 메세지 박스를 띄울 수 있었다.