pwnable.kr 사이트의 bof 문제를 보면 다음과 같다.
download URL이 제공된다. 일단 다운로드를 받자.
c코드는 다음과 같다.
코드를 분석해보자.
1. main 함수 내에서 func 함수를 호출한다.
2. func 함수를 호출하면서 인자로 0xdeadbeef 를 전달한다.
3. func 함수는 인자로 int 형 변수 하나를 받는다.
4. func 함수 내에서 char형 배열 overflowme를 선언한다.
5. 변수명이 굉장히 노골적이다.
6. gets 함수를 호출해 overflowme 변수에 입력값을 저장한다.
7. 인자로 받은 값과 0xcafebabe를 비교한다.
8. 같으면 bash 실행
9. 다르면 Nah.. 출력
코드 분석을 통해 알아낸 것은 func 함수의 인자인 key 값을 변조해야 한다는 것이다.
그렇다면 어떻게 key 값을 변조할 수 있을까??
해답은 gets 함수에 있다.
gets 함수는 인자로 받은 변수에 데이터를 쓰는 함수인데, 사용자가 입력한 값을 문자열로 저장을 한다. 이 때, 변수의 크기를 넘겨서 쓸 수 있다. 즉, BOF가 발생한다.
payload를 어떻게 만들 수 있을까?
payload를 만들기 위해서는 우선 해당 프로그램을 disassemble 해야 한다.
필자는 ubunt에서 gdb 툴을 이용해 disassemble을 했다.
우선, bof 파일을 다운로드를 받은 뒤 gdb명령을 사용한다.
gdb -q bof
-q 옵션은 gdb 버전 정보 등을 출력하지 않는 옵션이라고 생각하면 된다.
set disassembly-flavor intel
이 명령어는 gdb 명령어로 intel 문법을 이용하도록 설정한다. gdb는 기본 문법이 AT&T이다.
다음 명령어로 main 함수를 디스어셈블 해보자.
disas main
main 함수를 디스어셈블해 보여준다.
main 함수의 스택을 표현하면 다음과 같다.
|
0xdeadeef |
<-ESP |
|
|
|
|
|
|
|
|
|
EBP-> |
SFP |
|
|
ret |
|
func 함수를 호출할 때의 스택의 모습이다.
다음 명령으로 func 함수를 디스어셈블하면 다음과 같다.
disas func
func 함수를 디스어셈블해 보여준다.
이 함수에서 보아야 할 부분은 <+29>부터 <+35> 까지이다.
<+29>
overflowme 변수의 시작 위치와 크기를 알 수 있다.
<+32>
overflowme 변수를 esp에 저장하므로써 gets 함수 호출을 준비한다. 즉, 매개변수 설정
<+35>
gets 함수 호출
양이 조금 많아 보이지만 실제로는 작은 조각에 불과하다. 겁먹지 말고 일단 스택을 표현해보자.
|
overflowme 변수의 주소 |
<- ESP |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
overflowme 변수 메모리( 44바이트 ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EBP -> |
SFP |
|
|
ret |
|
func 함수의 매개변수 Key값 |
func+35 부분까지 진행 하면 위와 같이 스택을 표현할 수 있다.
ESP에 oveflowme 변수의 주소를 저장하고 gets 함수를 호출한다.
gets 함수가 반환이 되면 overflowme 변수에 입력된 값을 저장한다.
여기서 44바이트를 초과해서 입력을 해주면 아래 SFP, ret 그리고 func 함수의 매개변수인 key의 값까지도 변조가 가능하다.
key값을 변조하기 위해서 얼마나 입력해야 할까?
overflowme 변수는 44바이트 크기를 받았다. 여기에 더해 SFP, ret 까지 덮으면 그 다음이 key 값이다. 즉, 8바이트를 더한 52바이트를 입력한 후 다음 4바이트가 key값이 되는 것이다.
필자는 python을 이용해 payload를 작성했다.
payload는 다음과 같다.
(python -c 'print "A"*52 + "\xbe\xba\xfe\xca"'; cat) | nc pwnable.kr 9000
그 결과 bash/sh 이 실행이 됨을 볼 수 있다.
flag 를 읽어보자
'Wargame > pwnable' 카테고리의 다른 글
[pwnable.kr] collision (0) | 2017.06.25 |
---|---|
[pwnable.kr] fd (0) | 2017.06.18 |