PWN1

RET(return address) 변조와 쉘코드를 활용한 exploit

1. 개요

기본적으로 C언어에서 함수에는 프롤로그와 에필로그가 있다. 프롤로그는 어떤 함수를 실행하기 위해 ebpesp를 세팅하는 명령어이고, 에필로그는 함수를 호출한 이전 함수에 다시 복귀하기 위한 필수 명령어이다. 위에서 메모리는 스택의 낮은 주소부터 buffer -> SFP(Stack Frame Pointer) -> RET의 순으로 채워져 있는데, SFPRET는 모두 4byte씩이다. 따라서 RET의 주소는 buffer의 시작주소에 buffer의 크기와 SFP의 크기인 4byte를 더하여 구한다. 우리는 RET의 값을 변조하여 쉘코드를 실행하는 기법을 사용할 것이다.

 

2. exploit 실전

다음 예시 바이너리 001을 분석하여 쉘을 따보도록 하겠다.

 이 코드에서는 사용자가 입력한 argv의 내용을 buf에 복사하는 간단한 코드이다. argv[1]의 내용은 글자수 제한이 없으므로 Buffer OverFlow가 발생한다. 메모리에 할당되어있는 buf에는 sfpret가 존재하고, 일반적인 쉘코드의 길이는 25byte이므로 ret 다음 영역을 활용할 것이다.

 

이 문제는 C언어를 직접 컴파일하여 만들어졌기 때문에 기존에 보았던 바이너리와 Exploit이 약간 다를 수 있다.

 먼저 strcpy 함수가 실행되고 난 후의 메모리를 확인하여야 하므로 main+37break를 설정한다. 그런 다음 쉘코드를 실행시키기 위한 주소를 알아내기 위해 nop sled와 쉘코드를 집어넣을 것이다. 쉘코드는 다음을 이용할 것이다.

, C언어를 컴파일하였기 때문에 ‘push ebx’에 의해 4byte만큼 buffer에 더 더해주어야 한다.

- 25바이트 코드 일반적인 쉘코드

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89

\xe1\x89\xc2\xb0\x0b\xcd\x80

 그런 다음 메모리가 잘 변환되었는지 확인하기 위해 ‘x/50x $esp’ 명령어를 사용하였다.

여기서 buffer의 시작 주소는 0x4141……이 시작되는 0xffffd514이다. 또한 RET의 시작 주소는 0x43434343이 시작되는 0xffffd52c이다. 0x90nop sled이므로 이걸 타고 가면 0x31로 시작하는 쉘코드가 있는 것을 알 수 있다. 따라서 nop sled 부분의 주소 중 하나인 0xffffd54cRET에 넣으면 쉘코드가 실행될 것이다.

메모리에서는 리틀엔디안 방식으로 주소를 집어넣어야 하므로 0xffffd54c\x4c\xd5\xff\xff로 생각하여 exploit code를 작성한다.

     Exploit code에서 nop은 최대로 깔아주어야 쉘을 안전하게 딸 수 있다. nop100개일 때 쉘이 잘 안따여 300개로 늘렸다.

001의 쉘이 따졌다. 이러면 한 문제가 해결된 것이다.

댓글

댓글 본문
버전 관리
2019-2020STEALTH
현재 버전
선택 버전
graphittie 자세히 보기