FTZ Level 15

bin3635·2021년 8월 10일
0

hint는 다음과 같다.

이번에는 check 변수가 포인터로 선언되었다.
포인터가 가지는 값은 특정한 주소가 가리키는 값이기 때문에 0xdeadbeef를 직접 넣으면 0xdeadbeef가 가리키는 값을 찾아가게 된다. 이 문제에서는 포인터에 들어간 주소가 가리키는 값이 0xdeadbeef가 되게 만들어야 하기 때문에 0xdeadbeef가 있는 주소를 넣는 방식으로 공격해야 한다.

포인터처럼 정해진 값이 아닌 주소를 참조할 때는 실제 공격 시에 주소가 바뀔 수도 있기 때문에 attackme를 직접 gdb로 뜯자.

<main+3>에서 0x38(56바이트)만큼의 공간을 스택에 할당한다.

fgets 함수가 호출되는 <main+21>의 윗부분을 살펴 보자.
전달되는 인자는 buf, 45, stdin이고, <main+15>에서 0x2d(10진수로 45)를 push하기 때문에 <main+17>의 [ebp-56]이 buf가 위치한 지점이라는 것을 알 수 있다.

<main+32>에서는 [eax]와 0xdeadbeef를 비교하고 있는데, 바로 윗줄에서 [ebp-16]을 eax에 옮기고 있기 때문에 [ebp-16]이 check가 위치한 지점이라는 것도 알 수 있다.

따라서 [ebp-56]과 [ebp-16] 사이의 40바이트에 buf와 dummy가 위치할 것이다.
그리고 이번 문제에서도 check보다 위에 위치한 crap과 dummy는 아무런 쓸모가 없다.

이제 프로그램에서 0xdeadbeef가 위치한 주소가 어디인지 알아내야 한다.
<main+32>의 주소인 0x080484b0가 가리키는 값 근처에 존재할 것이기 때문에 examine으로 찾아 보자.

beef가 보인다. 값을 바꿔서 다시 해보자.

1바이트만큼 바꿔서 찾았더니 2글자 빼고 다 나왔다. 즉 0xdeadbeef가 위치한 주소는 0x080484b2라는 것을 알 수 있다.

공격 명령어는 다음과 같다.

(python -c 'print "A"*40+"\xb2\x84\x04\x08"'; cat) | ./attackme

Level 16의 쉘을 획득했다.

0개의 댓글