- 참치군
- ?
- stalk.io
- :: 2013년, 스리는 여섯살
- 웹 강좌
- 점프 투 파이썬
- 요니나의 대학생 재테크
- This is CS50
- 애자일 이야기
- isao의 IT,게임번역소
- 소프트웨어 이야기
- Color Scripter
- 어디를 가든지 마음을 다해 가라
- VisuAlgo
- 서울대 평생교육원
- 몽환
- RegExr: Learn, Build, & Test R…
- Hello, Stranger :D
- I Like Exploit
- Z3alous Security Story
- Project Euler
- Blog
- pieces of code
- window 쪼물딱 거리기
- IT - Informatics Alphabet
- rop
- 국제 정보교육센터 I2sec 대구 1기
- This is the moment. :)
- blackmoon
- z3alous는 세상에 소리 z3alous~
- Acord
- FORENSIC-PROOF
- 어셈블리
- Outsider's Dev Story
- Open Tutorials
- 코드라이언
- 컴퓨터 그래픽스와 3D 프린팅
- HACKABILITY
- Lee, Jae-Hong
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Wireshark
- 블루블랙
- Hello World
- ubuntu
- 펌
- 호출규약
- 시간복잡도
- 피보나치
- 알고리즘
- 발표
- 공간복잡도
- 오지총
- Visual Studio
- BOF
- 창의공학설계
- 버퍼오버플로우
- Calling Convention
- 염색
- 소켓
- C언어
- Packet
- 추상데이터타입
- 파이썬
- 디버깅
- 레지스터
- 컴파일러
- 탈색
- Debug
- 동대구
- 베이스
- Today
- Total
c0smicb0y
[Lord of BOF] Level 12 (golem -> darkknight) 본문
1. 문제의 힌트 확인
level12(golem)에 접속하여 ls명령어로 디렉토리의 파일 목록을 살펴보면
[그림1] golem 계정의 디렉토리목록
darkknight 파일에 suid가 걸려 있는 것을 확인할 수 있다. 이 파일을 이용하여 쉘을 획득해야 할 것이다. vi를 통해 darkknight의 소스를 살펴보자.
[그림2] darkknight.c의 내용
힌트에 FPO라고 적혀있다. 그럼 우선 FPO에 대해 알아보아야 할 것이다.
2. FPO (Frame Pointer Overflow/Overwrite)
FPO는 간단하게 설명하여 서브루틴이 있는 프로그램에서 서브루틴의 SFP를 조작하여 main의 ebp를 다른 곳으로 보내버려서 main의 leave가 수행될 때 다른 곳으로 보내진 ebp로 esp가 이동하여 거기에서 ret을 수행하여 쉘을 작동시키는 공격방법이다.
일반적으로 버퍼오버플로우는 RET주소를 뒤집어씌워서 공격을 감행하는데 어떻게 SFP만을 조작하여 공격할 수 있는지 본격적으로 알아보자.
FPO를 이해하기 위해서는 먼저 SFP와 esp와 ebp, 어셈블리어 leave, ret의 동작을 알아야 한다. esp는 stack pointer로서 현재 스택의 가장 위에 들어있는 데이터를 가리키는 포인터이다. ebp는 base pointer로서 현재 스택의 가장 바닥을 가리키는 포인터이다. SFP는 saved frame pointer로서 함수의 프로시저에서 이전단계의 스택에 있던 ebp의 값을 저장하는 포인터이다.
leave 명령어는
mov ebp, esp
pop ebp
이 두 명령을 수행한다.
ret 명령어는
pop eip
jmp eip
두 명령을 수행한다.
서브루틴에서 SFP를 조작하여 ebp를 다른 곳으로 보내버린다면 main의 leave가 수행될 때 esp가 조작된 ebp로 이동하여 거기서부터 작동을 하여 ret명령을 수행하게 된다. 그림으로 나타내면
[그림3] 서브루틴이 실행되기 전 main의 스택상황
main 수행되기 전 스택의 상황이 이러하면 서브루틴의 프로시저까지 실행된 후에는
[그림4] 서브루틴의 프로시저까지 실행된 후의 스택상황
main의 ebp값이 서브루틴의 스택의 SFP에 들어갈 것이다. SFP의 값을 조작하여 leave명령을 수행하면
[그림5] 조작된 SFP로 인해 엉뚱한 곳을 가리키고 있는 ebp
이 상태에서 main의 leave명령이 수행되면
[그림6] main의 leave명령이 수행되고 엉뚱한 곳으로 가버린 esp
이곳에서 ret명령에 의해 eip값을 얻어 다음 명령을 수행하게 되는데 변경되어버린 ebp+4에 쉘코드의 주소가 있다면 이 프로그램은 마치 그것이 return address인양 eip로 꺼내어 쉘코드를 수행하게 되는 것이다.
3. 실제
다시 darkknight의 소스를 보자.
[그림7] darkknight의 소스
서브루틴에서 입력인자의 값을 41바이트만큼 40바이트 변수에 복사하고 있다. 이 부분에서 1바이트 오버플로우가 일어나서 SFP의 1바이트를 뒤집어씌울 수 있다.
[그림8] overflow되어 조작된 SFP
이렇게 되면 앞에서 설명했던 것처럼 엉뚱한 곳으로 ebp가 이동할 것이다 1바이트정도의 변위밖에 못가지지만 말이다.
gdb를 통해 main의 ebp의 값과 problem_child의 ebp값을 알아보자. main의 ebp를 어디로 보내서 그 부분에 쉘코드의 주소를 넣어야하니 말이다.
[그림9] gdb로 디스어셈블한 darkknight의 main
problem_child를 호출하기 전인 *main+45와 problem_child가 호출된 후 프로시저가 진행된 *problem_child+3에 브레이크 포인트를 걸어주자
[그림10] gdb로 브레이크 포인트를 거는 모습
각 브레이크 포인트에서의 ebp와 esp와 eip의 값을 살펴보자.
[그림11] 각 브레이크 포인트에서의 ebp esp eip 값
ebp의 값이 마지막 두 자리, 즉 1바이트만 다르다. 이렇게 된다면 problem_child의 변수인 buffer에 쉘코드의 주소를 집어넣고, problem_child의 SFP의 마지막 한 바이트만 변조하여 buffer의 주소로 main의 ebp를 가리키게 하면 main의 ret이 수행되면서 쉘코드가 실행될 것이다.
인자에 A를 41개 집어넣고 buffer의 주소를 알아보자.
problem_child의 printf함수를 실행하는 부분에 브레이크 포인트를 걸어주고,
[그림12] printf를 call하는 부분에 브레이크 포인트를 걸어주는 모습
인자에 A를 41개 집어넣고 프로그램을 다시 실행한다.
[그림13] 인자에 A를 41개 집어넣고 프로그램을 다시 실행
여기서 esp의 값을 살펴보면
[그림14] esp의 값을 분석한 모습
0xbffffac4에서부터 buffer의 내용이 시작되는 것을 볼 수 있다. 그리고 buf앞에는 0xbffffac4, 즉 buffer의 주소를 가리키는 주소가 보인다. nop+shellcode를 buffer에 넣어주고, "\xbc"로 오버플로우 시키면 ebp는 0xbffffabc가 되고, main 함수의 leave, ret 명령에 의해 0xbffffabc, 0xbffffac0 순서로 움직이고 pop eip에 의해 eip에 0xbffffac0에 있는 값(0xbffffac4)가 저장된 후, 0xbffffac4로 점프할 것을 예상할 수 있다. 그러므로 공격코드는
[golem@localhost golem]$ ./darkknight `perl -e'print"\x90"x15,"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80","\xbc"'`
[그림15] 공격코드
이렇게 구성될 것이다.
공격해보자.
[그림16] 공격코드를 실행한 후 쉘이 작동한 장면
쉘이 작동하였다!
id 명령어를 통해 권한을 살펴보면
[그림17] id 명령어로 권한 조회
권한이 상승된 것을 볼 수 있다.
my-pass 명령어로 다음 단계의 비밀번호를 획득하자.
[그림18]다음 단계의 비밀번호
'정보보안 > Lord of BOF' 카테고리의 다른 글
[Lord of BOF] Level 14 (bugbear -> giant) (0) | 2015.02.10 |
---|---|
[Lord of BOF] Level 13 (darkknight -> bugbear) (0) | 2015.02.10 |