Training 2020 #2 ( VulnCode )
Lab2 목차 인 것 같다. Crash가 무엇인지에 대해 알아보고 왜 Crash가 발생하는지에 대해 알아보자.
Crash란 컴퓨터 자체 또는 응용 프로그램이 예기치 않게 기능을 정지하는 것
을 말한다. 그럼 이제는 왜 Crash가 발생하는지 알아 보도록 하겠다.
왜 Crash가 발생하는지 알아보기 위해 우리가 직접 취약점이 존재하는 코드를 작성하여 Crash를 발생시켜 보자. 환경은 Visual Studio 2010 Professional 이다.
New Project 를 눌러 Win32 Console Application 으로 생성해주자.
OK버튼을 눌러준 뒤 Next를 계속 눌러주다 보면 이런 화면이 나오는데 Empty project 목록란을 활성화 시켜주고 Finish 버튼을 눌러주자.
그리고 Source Files를 우클릭 한 뒤 새로운 아이템을 추가해주자.
C++ 로 새로운 아이템을 추가 해주자.
위에 취약한 코드를 작성시켜 주자.
이 코드의 취약한 점은 fgets 함수로 readbuf에 2000의 입력을 받는데 strcpy로 printbuf의 readbuf의 입력값을 복사하는 과정에서 printbuf의 크기를 넘길 수 있는 버퍼오버플로우 취약점이 발생하기 때문이다.
메모리 구조를 보면 대략 위와 같은 과정을 거칠텐데 이 과정에서 readbuf에 입력하는 문자열의 길이가 500을 넘게 된다면 다음과 같은 상황이 발생한다.
이렇게 되면 프로그램이 비정상 종료가 일어나게 될 것 이다.
그럼 이제 이러한 상황이 일어나는지 확인하기 위해 이 파일을 빌드 해줄건데 그 전에 거쳐야 할 과정이 있다. visual studio 에서 스스로 취약점 진단(?) 을 하는 과정을 거치기 때문에 이러한 과정을 거치지 않도록 설정을 해줘야 한다.
Project 메뉴에 test2 Properties 를 눌러준다.
그리고 다음 Configuration 메뉴에 Release 메뉴를 선택해준다.
C/C++ 메뉴에 Code Generation 에서 Buffer Security Check 를 No로 설정을 바꿔주고
다음은 Linker - Advanced 에 Randomized Base Address, Data Execution Prevention (DEP), Image Has Safe Exception Handlers 를 모두 No로 설정해준다.
Manifest Tool - Input and Output 메뉴에 Embed Manifest 설정도 No로 바꾸어주고 Apply를 누른뒤 OK로 적용시켜주자.
그럼 소스코드에 버퍼오버플로우 취약점이 있어도 성공적으로 빌드를 할 수 있다.
빌드는 Ctrl + F5 를 눌르면 된다.
빌드가 성공적으로 됬다면 다음과 같은 경로에 이런 파일들이 생성되었을 것이다.
우선 우리가 예상한 시나리오대로 문자열 입력을 500이상 하게 되면 프로그램이 비정상 종료되는지 확인하기 위해 익스 코드를 작성해 보자.
익스 코드는 다음과 같이 작성한 뒤 빌드된 프로그램과 같은 경로에 위치시켜 두면 된다. 이 코드는 간단하게 문자열 500이 넘는 인자를 넘기기 위해 A가 550개 작성된 텍스트 파일을 작성시키는 코드이다.
다음과 같이 경로창에 cmd 를 치면 현재 폴더 경로에서 cmd 창을 열어준다. 그럼 python 파일을 실행시켜보자.
다음과 같이 python [file name].py 를 실행시켜주면 A가 550개 작성된 test.txt 파일이 생성되는 것을 확인할 수 있다.
그럼 이 파일을 인자로 test2.exe를 실행시켜 보자.
[file name].exe test.txt 명령어를 입력하면 다음과 같이 A*500개가 입력되고 곧 크래시가 나는 것을 확인할 수 있다.
이제 windbg를 사용해 볼건데 우선 windbg 란 MicroSoft 에서 지원하는 공식 디버깅 툴 이며 ollydbg와 더불어 대표적인 디버깅 툴 이다. windbg에 대한 자세한 사항은 링크를 클릭해보자.
windbg를 사용하기에 앞서 분석할 크래시 덤프파일을 수집할 수 있도록 레지스트리 설정과 확장 DLL을 불러올 것이다.
이것을 보고 따라서 설정할 수 있다면 그대로 하면 되고 못하는 사람들은 자세히 적어둘테니 따라오면 되겠다.
Windows + R 키를 누르고 regedit을 열어주자.
그리고 다음의 경로를 따라가 주자.
그럼 다음 경로에 원래 LocalDumps 가 없을텐대 추가해주자.
추가 방법은 Windows Error Reporting 메뉴를 우클릭 한 뒤 New 메뉴에 Key를 눌러 추가해주면 된다.
그리고 다음과 같이 DWORD (32-bit) Value 를 눌러 DumpType 을 추가해주자.
그리고 DumpType 를 더블 클릭하여 열어 값을 2로 바꾸어주자. 덤프 타입 값을 2로 바꿔주는 이유는 덤프 타입 2 가 full dump 로 크래시가 날경우 전체 덤프를 진행하기 때문이다. 이렇게 설정을 했으면 이제부터 크래시가 나면 다음과 같은 경로에 덤프 파일이 생길 것 이다.
다음과 같이 덤프 파일이 생기면 성공적으로 설정이 된 것이다. 그럼 이제 windbg에 사용할 모듈을 추가해 보자.
위에 링크에 있는 파일을 복사하여 밑에 링크에 붙여넣기 해주자. 그럼 끝이다. ^^
windbg 를 본격적으로 사용해 보자. 크래시가 난 덤프 파일을 windbg를 통해 열어주자.
!load msec를 입력하여 위에 경로에 올려둔 msec를 불러와준다.
그리고 다음 명령어를 입력해주면 windbg님이 일을 시작하시면서 바쁘다고 표시를 하시는데
이 표시가 바로 windbg님께서 바쁘시다고 표내시는 것이다. 그러니 건들지 말고 가만~히 기다리도록 하자. 기다리면서 exploitable이라는 명령어에 대해 알아보자.
이 명령어는 프로그램에서 크래시가 발생한 경우, 현재 메모리상태나 레지스터 상태 등을 고려하여 위험도를 판단하는 명령어이다.
위험도는 총 4 가지로 분류되는데
- exploitable - 익스 가능
- probably exploitable - 아마 익스 가능
- probably not exploitable - 아마 익스 불가능
- not exploitable - 안됨
으로 분류된다.
지금은 우리가 만든 매우 취약한 프로그램이기 때문에 당연할지 모르겠지만 windbg도 익스가 가능하다고 판단했다.
그리고 다음과 같이 어떤 형식에 익스플로잇이 가능한지까지 알려준다.
이번 포스팅은 여기까지 취약한 코드를 작성하고 크래시를 낸뒤 windbg를 사용하는 방법까지 정리해보록 했다.