본문 바로가기

My Study/Exploit

Hackerschool level19 쉘코드 줄이기, 환경변수 사용하지 않기

저번에 제가 level19번을 풀긴했지만 마음에 안드는 구석이 상당히 많았습니다.
첫번째, 쉘코드 길이가 너무 길다. 버퍼의 크기는 44Byte인데 43Byte의 쉘코드를 만들었습니다.
두번째, 에그쉘을 사용했다. 환경변수를 사용해서 문제를 풀었다는 것입니다. 별로 좋아하진 않죠.

그래서 저 두개를 보안하는 방안으로 문제를 풀어보았습니다.

첫번째, 쉘코드 길이를 줄이자.
제가 비록 잘하는건 아니지만 어떻게하면 쉘코드를 줄일 수 있을까..라는 많은 생각을 했습니다.
그 결과 제가 다시 만든 소스코드 입니다.

제가 RTL ( Return to Lib )를 공부하면서 "/bin/sh"라는 문자열을 라이브러리에서 가져온 기억을 살려서
execve함수의 첫번째 인자로 전달되는 "/bin/sh"를 라이브러리에 있는 주소로 대체 했습니다.
그리고 중복되는 부분은 최대한 레지스터를 활용하며 상수를 사용하지 않으려고 했습니다.

그 결과 위와 같은 코드가 나왔고 해당 소스를 덤프코드로 봐보겠습니다.

저번에 43Byte였던 소스코드가 35Byte로 8Byte나 줄였습니다.
저로선 나름대로 만족입니다. ^^ 쉘코드는 짧을 수록 좋으므로 더 생각해보면 더욱 짧은 쉘코드가 나올 꺼 같습니다.

이제 35Byte의 쉘코드는 만들어졌습니다.

\x31\xdb\x31\xc9\x31\xc0\x66\xbb\x1c\x0c\x66\x89\xd9\xb0\x46\xcd\x80\x31\xd2\x31
\xc0\x68\x24\xad\x14\x40\x5b\x52\x53\x89\xe1\xb0\x0b\xcd\x80

두번째 입니다. 환경 변수를 사용하지 않기..!
저번에 환경변수를 사용한 이유는 쉘코드가 있는 주소로 제대로 리턴 값을 바꿔준지 알았는데 그게 아니었던거 같습니다.
그래서 환경변수를 사용할 수 밖에 없었습니다. 이번에는 어떻게든 쉘코드가 있는 주소를 찾도록 하겠습니다.


gets의 첫번째 인자는 입력 값이 들어갈 주소 입니다. 그래서 해당 주소를 봐보니 " 0xbffffaf0 "이라는 값이 있었습니다.
그래서 리턴 값을 저 주소로 바꿔서 공격을 해보겠습니다.

마지막 리턴 주소는 해당 주소로 넣어주었고... 하지만 결과를 보니 세그멘테이션 오류가 떴습니다. 역시나.. 무언가 잘못됬습니다. 그래서 다른 방법을 사용하도록하겠습니다. 세그멘테이션 오류가 나는 곳을 덤프를 뜨는 것입니다.

방법은 이렇습니다.
먼저 attackme를 tmp폴더로 복사합니다.

제대로 복사가 됬습니다.

이제 해당 폴더에서 "ulimit -c unlimited" 명령어를 쳐줍니다.

위와 같이 되면 셋팅은 된 것입니다. 해당 명령어는 세그멘테이션 오류가 났을 때 그 부분의 메모리를 덤프파일로 만들어주는 효과를 만들어 줍니다. 이제 다시한번 공격을 해보겠습니다.

역시나 세그멘테이션 오류가 나지만 코어 덤프가 생겼습니다.

core.682라는 파일(뒤 숫자는 랜덤)이 생겼습니다. 이제 해당 덤프 파일을 가지고 메모리를 봐보겠습니다.


위와 같이 명령어를 쳐주면 덤프 파일을 분석할 수 있습니다.

우리가 궁금해 하던 주소는 0xbffffaf0 이므로 해당 주소로 가보겠습니다.

빨간색 네모친 부분은 쉘코드의 끝 3Byte입니다. 쉘코드가 짤린거 같습니다. 그러면 위쪽으로 가서 쉘코드의 처음 부분을 찾도록 하겠습니다.
빨간색으로 네모친 부분이 쉘코드 시작 부분입니다. 쉘코드와 비교해보시면 알 수 있습니다.
분명히 gdb상에서는 0xbffffaf0에 쉘코드가 들어가는 것으로 나와있는데 직접 덤프 파일을 보니 0xbffffad0에 들어가 있습니다.
왜 gdb상에서 주소와 실제 공격할 때 주소가 다른지는 잘 모르겠지만 gdb는 절대 경로로 가져오고 실제 공격할 땐 상대경로로 가져와서 그렇게 다르다는 말도 있습니다.

이제 제대로 쉘코드가 들어가는 주소를 알았으니 해당 주소로 리턴 값을 바꾸고 공격해 보도록 하겠습니다.

리턴 주소를 0xbffffad0으로 바꿔서 공격하니 제대로 됬습니다.

level19번 전까지는 이러한 현상은 없었는데 왜 level19번에서만 이러는지는 모르겠네요. 컴파일 시 어떠한 옵션을 준건 아닌지..

'My Study > Exploit' 카테고리의 다른 글

geteuid()를 사용한 쉘코드 만들기  (0) 2010.05.21
버퍼 오버플로우 취약점에 대한 대처 방안들  (0) 2010.04.29
RTL로 푼 해커스쿨 level11  (4) 2010.04.07
Hackerschool level20  (0) 2010.03.30
Hackerschool level19  (2) 2010.03.27