https://www.corelan.be/index.php/2009/07/19/exploit-writing-tutorial-part-1-stack-based-overflows/
이 글은 위 글을 바탕으로 공부해서 실습까지 해보는 그러한 글입니다.
---------------------------------------------------------------------------------------
조만간 윈도우 환경에서 Exploit을 할 일이 있을 것 같으니, 윈도우즈 Exploit 관련 공부를 좀 해 볼까 한다.
사실 이 BOF 파트는 리눅스랑 거의 같은 것 같아서 그냥 대충 읽어만 보고 넘어갈려고 했는데, 뭐 컴퓨터 하는 사람이라면 직접 해봐야 알지 않겠는가?
무려 10년도 전에 작성된 글이라서 자료가 많이 다르고 할 수 있지만, 열심히 환경 구축해서 따라가보도록 하자.
환경구축
Windows XP 32bit
일단 윈도우즈 XP가 필요하다. 버그리포트는 SP2에서 되었지만, 코어랜 글 저자는 SP3에서 했다고 하니 어쨋든 XP와 virtual box를 이용해서 OS환경 구축을 해보자.
iso 이미지를 어디서 구해야 할지 모르겠는데, 일단 microsoft 공홈에서는 64bit만 있는 것 같다.
구글링 해보니, 여기서 받을 수 있었다.
https://isoriver.com/windows-xp-iso-download/
Virtual box에 Windows XP Service Pack 3 32bit ISO를 넣어서 열심히 설치를 해보고 있다.
나오는걸 그냥 엔터엔터 엔터 동의함 엔터엔터 하면 그냥 설치가 된다.
XP를 오랜만에 보니 좀 신기한듯.
라이센스 키를 쓰라고 으름장을 놓는데, 인터넷에 구글링해서 아무거나 쳐서 쓰도록 하겠다.
테스트용이기도 하고, 가상머신 안에 설치한것이기도 하고, 이미 판매가 종료된 버전이기도 하니깐, 큰 문제는 없지않을까? 하는 그런상황쓰이다.
Easy RM to MP3 Converter v2.7.3.700
이게 취약 프로그램인데, 코어랜 홈페이지에서는 다운로드 받으려면 로그인을 하라고 한다.
근데 회원가입 기능이 없다.
따라서 그냥 구글링을 해 보았는데, 나름 유명한 프로그램인지 쉽게 구할 수 있었다.
아래 링크로 가면 다운받을 수 있다.
https://easy-rm-to-mp3-converter.en.softonic.com/
심지어 버전도 같다. 굿!
이제 저녀석을 Windows XP VM안에다가 설치를 해버리면 될 것 같다.
파일 VM에 배포
이제 필요한 파일들을 VM안에 배포를 해야 하는데, 어떻게 옮겨야 할까?
안에 IE가 브라우저로 있긴 하지만 매우 오래된 버전이기도 하고, 크롬같은 경우에는 최근 버전들은 호환이 되지 않아서, 별도로 낮은 버전을 구해서 깔아야 한다. 그래서 그냥 호스트에서 필요한 파일들을 받아서 넘기기로 했다.
일단 Virtual box Guest 확장을 설치해야 한다.
위에 매뉴를 누르면 슥삭 하고 설치가 시작될 것이다.
중간에 계속 Warning이 뜰건데, 어쨋든 계속한다를 계속 눌러주면 된다.
게스트 확장을 설치하면, 파일공유도 되고 해상도 자동 조정도 된다 캬!
그리고 공유폴더를 지정하면 Host와 Guest간에 파일 공유가 되게 된다.
호스트 OS 공유폴더에는 필요한 파일을 다운받는 중이고, 게스트 공유폴더에 들어가보니, 다운로드 중인 파일이 보인다.
정상적으로 잘 다운이 되는 중인듯 하다.
Windows XP에 파이썬 설치
호스트에서 파이썬 스크립트로 페이로드 파일을 만들어서 넘겨도 되지만, 게스트에서 직접 스크립트를 실행하는 것도 괜찮아보인다. 사실 호스트-게스트간 파일 공유 시 약간 랙이 있어서 조금 답답할 수 있는 것 같다.
파이썬 공식 홈페이지를 보니 Python 3.5버전부터는 WinXP나 그 이전 버전에서 호환이 안되는 것 처럼 보인다. 그러니 3.4.1버전을 한번 받아보도록 하겠다.
https://www.python.org/downloads/windows/
가장 하단에 있는 Windows x86 MSI Installer로 파일을 받아보겠다.
다행히 잘 설치되는 것 같다. 그리고 환경변수까지 지정을 해 주자.
익스플로잇 재현
이제 환경구축은 얼추 끝난 것 같으니까, 취약점을 익스플로잇 해보도록 하자.
프로그램 실행
일단 취약한 프로그램인 Easy RM to MP3 Converter라는 프로그램을 한번 실행시켜보자.
공유폴더에서 바탕화면으로 설치 파일을 옮긴 뒤 실행을 해 보았다. 근데 이게 뭐하는 프로그램인지 아직은 잘 모르겠는데 RM이라는 포맷을 MP3로 변환해주는 그런 프로그램인가보다.
일단은 코어랜 블로그에서 \x41를 1만개 넣어서 파일을 만든 뒤 그냥 실행해보았었으니, 나도 똑같이 해보겠다.
코어랜에서는 perl로 스크립트를 짰던거같은데 나는 파이썬으로 짜겠다.
일단 crash.m3u파일을 만들었으니 저 파일을 guest vm으로 보내서 실행해보도록 하자.
Load를 누른 뒤 crash.m3u파일을 여니 아래와 같이 에러가 뜬다.
파일 이름을 덮어쓴걸로 봐서 bof가 일어난 듯 하다.
여기에 A를 2만개를 반복하는 것 까지 저렇게만 버그가 난다고 한다. 근데 3만개가 되면 프로그램 크래시로 종료가 된다.
Windbg 설치
맨처음에는 올리디버거를 써야 하나 싶었는데, 코어랜 블로그에서는 윈디버거(Windbg)를 쓴다고 했으니, 이번에 안써본 윈 디버거를 한번 써보도록 하겠다.
근데 Microsoft 공식 windbg 다운로드 페이지로 가니, Windows SDK를 설치할 때 그 패키지 안에 같이 포함되어있다고 한다. 그중 Debugging Tools for Windows를 고르면 된다고 한다.
Win10이전의 버전들은 별도의 페이지가 있다고 한다.
근데 해당 페이지로 가보면 Win8과 7까지밖에 없다.
근데 가장 과거인 Win7 SDK를 보면, Win XP도 사용 가능하다고 되어있다. 이를 설치해보도록 하자.
흠 근데 대략 이런 에러가 뜬다. .NET Framework 2.0 redistributable을 다운받아달라고 한다.
구글링을 하니 다운로드 페이지가 뜬다.
서비스 팩 1이라고 뜨긴 하는데, x64는 아닐테니 x86인 요녀석을 한번 받아보자.
다행히 설치는 잘 되는 듯 하다. 다시 Win SDK 설치를 시도해보자.
일부 컴포넌트는 설치가 불가능하다고 하는데, 어차피 나는 Windbg만 설치하면 되기 때문에 Ok를 눌러서 진행해본다.
잠시 반응이 없길래 설치가 안되는줄 알았는데, 조금 기다리니 위와 같은 창이 떴다.
Next랑 Agree를 누르니 아래와 같은 창이 나타났다.
Windbg는 당연 Debugging Tools에 있을 거니 체크를 해서 설치를 해주자. 나머지는 다 설치 체크를 해제한뒤 진행해보겠다.
근데 설치가 다 된거같은데, 우리의 windbg는 어디있을까...?
그래서 찾기로 가서 windbg로 검색해보니 아무것도 안나와서 debug로 검색을 해 보았더니 무언가가 나왔다.
dbg_x86라는 녀석 아이콘을 보니 또다시 설치파일인것 같았다. 더블클릭해서 실행해서 설치를 진행해보자.
그리고 나서 windbg로 검색을 해보니, windbg가 나타났다.
환경구축이 제일 빡샌거같기도 하고. 어쨋든 windbg까지 설치가 되었다.
그리고 코어랜 블로그에서 했던 것 처럼 postmortem debugger로 설정도 해주었다.
post-mortem 뜻을 검색해보니 사후(죽은 뒤)라는 뜻이라서, 아마 프로그램 크래시가 나서 종료되면 그 것들을 처리하는 기본 디버거라는 뜻 인것 같다.
그리고 "xxx프로그램이 문제가생겨서 꺼야합니다~"라는 팝업을 안 뜨게 하기위해서 레지스트리도 수정해주었다. 실행 창에서 regedit을 치면 레지스트리 수정 창을 띄울 수 있고, HKLM/Software/Microsoft/Windows NT/CurrentVersion/AeDebug/Auto를 0으로 셋팅하면 된다.
<TODO : 제대로 동작하게 하기>
그리고 windbg가 심볼이 없다고 불평하는 것을 막기 위해서 설정을 해준다.
하드드라이브에 폴더를 하나 만들고, c:\windbgsymbols와 같이 만들었다고 치자.
File-Symbol Search Path에 위와 같이 써준다.
근데 동작은 안하는것 같다. ㅠ
크래시 디버깅 - EIP 덮어쓰기
이렇게 설정을 하고 다시 Easy RM to MP3 프로그램을 크래시를 내보자.
A가 3만개 들어있는 파일을 열라고 시도하자 다음과 같이 나타난다.
저기서 Debug를 누르면 windbg가 숑 하고 나타날 것이다.
여기서 디버그 버튼을 눌러보자.
Windbg가 나타나고, eip가 41414141이 된 것을 알 수 있다.
이걸로 2만개 A는 크래시가 안나고 3만개 A는 크래시가 난다는 점을 이용해서 2만과 3만 사이 어딘가의 크기의 A를 쓰면 bof가 난다는 걸 알 수 있다.
이를 이용해서 정확히 얼마 A를 채워야 프로그램이 터지는지를 한번 알아보자.
그냥 간단하게 A를 2만5천개, B를 5천개를 넣고 확인, 그리고 그 결과에 따라서 다시 변경해서 확인 이런식으로 반복을 하면 알아낼 수 있다.
A를 2만5천개, B를 5천개를 넣으니 EIP가 42424242가 나온다. 즉 5천개인 B의 범위에 있다는 뜻.
따라서 25,000 ~ 30,000 사이의 값이다.
25,000 ~ 27,500 사이의 값인것을 알 수 있다. 일종의 바이너리 서치 같은 개념으로 볼 수 있다.
이번에도 42424242에서 터졌으니 B에서 터졌다고 보면 된다.
25,000 ~ 26,500 사이의 값이다.
D의 범위에서 터졌으니 대충 26,000 ~ 26,500 의 범위에 있다.
B에서 터졌다. 26,000 ~ 26,150 사이의 범위이다. 계속 쭉쭉 범위가 줄어들고 있다.
C의 범위이다.
26,050 ~ 26,100의 범위에 있다. 이러한 식으로 계속 줄여보자.
26,065 ~ 26,080에 있다.
결국 26067의 더미와 + (ret_addr)를 넣으면 eip를 덮어쓸 수 있다는 걸 알 수 있다.
이제 쉘코드를 넣은 뒤, 쉘코드로 점프만 뛰면 쉘을 띄울 수 있다.
쉘코드 넣을 자리를 찾기
그리고 d esp라고 치면 esp 주소에 있는 메모리 값들을 볼 수 있는데, gdb로 치면 x/x $esp와 비슷한 명령어 인 것 같다. 덮어쓴 eip이후의 값들이 그대로 있다.
코어랜 블로그에서 했던 것 처럼 EIP를 덮어쓴 뒤 esp가 가리키는 곳에 값을 쓰는 부분에 쉘코드를 올리도록 준비를 해 보자. 아래와 같이 m3u파일을 생성해서 실행해보니, 쉘코드의 0~3까지 즉 4byte가 잘리고 나머지 부분이 잘 올라가있다.
이러한 부분도 한번 고려를 해야 한다는 것이다. 아마 잘린 4byte는 saved ebp, 이전 스택 프레임 포인터에 해당할 것이다.
따라서 덮어쓴 eip 다음 값 4바이트를 버린 뒤 쉘코드를 올리면 될 것 같다.
그래서 아래와 같이 esp 주소로 점프를 하고, esp에는 NOP과 cc로 브레이크 포인트를 잡는 페이로드를 작성해서 실행해 보았다.
그런데 이게 왠걸, esp에는 알수없는 널값들이 좀 있고, 크래시가 또 났다.
eip는 잘 뛰었는데 왜그런걸까.
안전하게 쉘코드로 점프하기
esp주소에는 0x000ff730이다. 마지막에 널값이 있어서 Null terminate된다. 이렇게 하면 안될 것 같다. 그러면 어떻게 해야 할까?
만약 jmp esp와 같은 명령어를 실행시킬 수 있다면 esp로 안전하게 뛸 수 있을 것이다.
일단 windbg와 익스할 컨버터 프로그램을 다시 띄운 뒤, attach to the process를 이용해서 windbg를 붙여보자.
그리고 밑에 커맨드 창에 a 치고 엔터를 친다. 그러면 assemble 모드가 된다.
그리고 jmp esp를 치고 엔터를 친다.
그러면 지금 주소값에 jmp esp가 등록이 된다.
그리고 다시 엔터를 치면 assemble모드가 꺼진다.
그리고 u 7c90120e를 치면 아까 우리가 쓴 값의 부분이 디스어셈블되서 보인다.
여기서 우리가 알게된 것은 jmp esp의 opcode가 ffe4라는 점이다.
그러면 이 컨버터 프로그램이 실행하는 dll 라이브러리 중에 ffe4라는 opcode를 갖고 있는 녀석이 있을까?
커널 DLL말고 어플리케이션 dll중에 codec02라는 녀석으로 패턴을 찾아보았다. 코어랜 블로그와는 dll 로드되는 주소가 다르긴 했는데 잘 찾아졌다.
그리고 익스플로잇 코드를 조금 손봤다.
그런다음에 windbg랑 컨버터를 다시 새로 키고, 디버거를 붙인 뒤, g명령어로 실행을 시키고 해당 익스플로잇 파일을 로드해보았다.
breakpont에 잘 걸렸고, esp에 쉘코드도 잘 보인다.
Real 쉘코드 삽입 및 익스플로잇 마무리
이제 NOP + \xcc로 디버거 브레이크만 잡는게 아닌, 실제 쉘코드를 넣어서 익스플로잇이 잘 되는지를 확인해보도록 하자.
윈도에서는 계산기를 띄우는 쉘코드를 많이 쓰니, 이를 한번 이용한다. 메타스플로잇에 있는 쉘코드 generator를 이용해서 쉘코드를 얻는 것 같다.
쉘코드를 복붙하는게 귀찮으니, 호스트에서 만들어서 넘기도록 하겠다.
근데 안된다..
쉘코드 점프까진 되는데 왜 안되지.
그래서 코어랜 익스코드처럼 앞에 NOP을 25개 정도 붙이고 다시 해보았다.
위와 같이 익스코드를 생성해보았다.
그니깐 되네. 왜그럴까..
하고 생각을 해보았는데, 아마 쉘코드 내용에서 스택을 쓰는 녀석들이 있을 것이다.
push pop 등등을 좀 할건데, 쉘코드가 거기에 곧바로 있으면 실행하면서 그 쉘코드 자체를 변경해버려서 그렇게 되지 않을까 하는 추측이 된다.
쉘코드 시작부분이다.
일단 pop eax가 한번 나타난다. push 하는게 없었으니, 쉘코드가 하나 떨어져 나가겠다.
그리고 보면, NOP을 안넣었을때 크래시가 나는 곳이 0xff75f 부분인데 eax + 68에 접근을 한다. eax는 근데 쉘코드 맨 앞 부분과 관련이 있으므로 NOP을 넣으면 그 부분이 다른 값이 들어가게 된다.
뭐 어쨋든 NOP을 넣어서 꼭된다 이런거는 아니긴 하다. 영 아니면 다른 쉘코드를 집어넣거나 쉘코드도 직접 만드는 방법도 있겠다.
어쨋든 계산기를 봤으니 이만 글은 줄인다.
--------------------------------------------------------------------------------------
https://www.microsoft.com/ko-kr/download/details.aspx?id=16614
https://docs.microsoft.com/ko-kr/windows-hardware/drivers/debugger/debugger-download-tools
'해킹 & 보안 > 시스템 해킹' 카테고리의 다른 글
Virtual box에 포너블 환경 구축(Ubuntu 18.04+pwntools + gef) (0) | 2020.08.22 |
---|---|
[코어렌 튜토리얼] Windows Exploit 작성 튜토리얼 part6 : 보호기법 우회 (0) | 2020.02.28 |
[코어렌 튜토리얼] Windows Exploit 작성 튜토리얼 part3 : SEH (3) | 2020.02.28 |
유니코드 쉘코드 / 베니스 쉘코드 (0) | 2020.02.25 |