이번 문제는 fgets 함수를 사용하는 코드에 오버플로우를 일으키는 문제다.
fgets함수는 버퍼의 개수를 지정해주기 때문에 상대적으로 안전하지만 여기서는 지정된 버퍼보다 많은 바이트를 fgets함수로 저장할 수 있다.
우선 GDB로 열어봤다.
변수에 56바이트가 할당되었다.
각 변수들의 위치를 구해보면 buf에서 ebp까지의 거리가 56이고
*check에서 ebp까지의 거리는 16이다.
그러면 자연스럽게 buf와 *check의 거리는 40인것을 알 수 있다.
즉 버퍼에서 40바이트를 넘기면 오버플로우가 일어난다는 것이다.
그리고 fgets함수에 의해 0x2D 즉 45바이트를 넣을 수 있으니 5바이트는 더 넘길 수 있다는 의미다.
하지만 *check는 포인터변수이기 때문에 deadbeef라는 문자열이 있는 곳의 주소를 넣어줘야 한다.
내가 찾은 방법은 두 가지 방법이 있다.
첫번째 방법은 임시버퍼를 이용한 방법이다
두번째는 deadbeef라는 문자열이 있는 곳을 gdb로 잘 보면 친절하게 보여주고 있다. 그 주소를 넣어주면 된다.
먼저 첫번째 방법이다.
임시버퍼
임시버퍼를 이용하면 익스플로잇이 가능하다.
임시버퍼에는 상당히 많은 바이트를 넣어주면 저장이 된다. 그리고 주소가 변경이 되지 않고 고정이 되어 있어서 유용하게 페이로드를 넣고 사용할 수 있다.
일단 버퍼에 Nop sled를 200바이트를 주었다.
임시버퍼를 확인해보니 Nop 바이트가 정확히 들어가 있다.
페이로드는 일단 40바이트로 buf를 채우고 뒤에 4바이트를 0xdeadbeef가 있는 주소를 넣어주면 된다.
gdb로 정확한 주소를 찾기 위해 일단 0xdeadbeef가 있는 주소가 있어야 할 자리에 AAAA를 넣고 Nop sled를 200바이트를 주고 0xdeadbeef가 있어야 할 자리에 BBBB를 넣고 확인했다.
BBBB가 있는 주소는 0x400170f4다 즉 AAAA위치에 0x400170f4를 넣고 BBBB에 0xdeadbeef를 넣으면 된다.
페이로드를 입력하니 문제가 풀렸다.
0xdeadbeef
gdb를 열어보면 0xedeadbeef랑 변수의 값과 비교하는 곳이 있다.
굳이 임시버퍼에 0xdeadbeef를 입력하지 않고 이 곳의 주소를 이용해 문제를 쉽게 풀 수 있다.
0xdeadbeef가 0x80484b2에 있다.
이제 buf에 40바이트를 넣고 추가적으로 4바이트에 0x80484b2를 넣으면 문제가 풀릴 것이다.
아주 간단하게 문제가 풀렸다.
'Wargame > FTZ' 카테고리의 다른 글
[FTZ] level17@ftz (0) | 2017.11.25 |
---|---|
[FTZ] level16@ftz (0) | 2017.11.25 |
[FTZ] level14@ftz (0) | 2017.11.21 |
[FTZ] level13@ftz (0) | 2017.11.21 |
[FTZ] level12@ftz (0) | 2017.11.10 |