ID : level15
PW : guess what
1.
level15로 로그인 해준 후 hint파일을 읽어주자. 14번 문제와 동일한 코드에서 check변수를 포인터로 변경했다.
포인터 변수는 메모리의 주소 값을 저장하는 변수이다. 따라서 check에 들어가는 값은 메모리의 주소 값으로 저장되며,
check 포인터변수에 있는 값이 가리키는 메모리 주소에 0xdeadbeef를 넣어줘야 쉘을 딸 수 있을 것이다.
(포인터변수는 메모리의 주소값을 저장하니까, 0xdeadbeef값이 들어있는 주소값을 check포인터변수에 넣어줘야 한다는 뜻)
fgets(buf,45,stdin); //45바이트만큼의 입력을 buf변수에 받음
그럼 우리가 해야할 일은?
- buf[20]에서 부터 *check까지의 거리 구하기
- 디버깅을 통해 0xdeadbeef 주소 알아오기
- *check 포인터변수에 존재하는 메모리 주소에 0xdeadbeef 덮어 씌우는 페이로드 작성하기
2.
buf[20]에서 부터 *check까지의 거리를 구해보자!
attackme파일을 디버깅 해줬다. <main+17>부분으로 buf에서 ebp까지의 거리가 56임을 알 수 있다.
<main+29>부분은 조건문에서 *check포인터와 0xdeadbeef 값을 비교하는 부분임으로, *check에서 ebf까지의 거리가 16임을 알 수 있다.
따라서, buf[20]에서 *check까지의 거리 = (buf에서 ebf까지의 거리) - (*check에서 ebp까지의 거리) = 56 - 16 = 40이다.
스택은 buf(20) + dummy(20) + *check(4) + dummy(8)와 crap(4) + SFP(4) + RET(4) 이겠네.
이제 메모리 상에서 0xdeadbeef가 존재하는 위치를 알아보자!
위에서 디버깅 내용을 보면, <main+32>은 0xdeadbeef와 *check를 비교하는 부분임을 알 수 있다.
x/x 0x080484b0 명령어로 해당 주소를 출력시켜서 0xdeadbeef가 존재하는 주소를 찾아보자!
숫자를 1씩 높여서 확인 해본결과, 0xdeadbeef값이 존재하는 주소가 0x80484b2라는 것을 알아냈다.
이제 페이로드를 작성해보자.
(python -c 'print "\x90"40 + "\xb2\x84\x04\x08"';cat)|./attackme
버퍼(20)와 더미(20)을 NOP 40개로 덮어주고, 바로 다음에 위치한 check포인터 변수를 0xdeadbeef값이 있는 주소로 덮어줬다!
이로써 레벨15를 클리어했다.
(2020.02에 작성한 글을 가져왔습니다.)
'Pwnable > FTZ' 카테고리의 다른 글
[FTZ] level 17 풀이 <BOF-env> (0) | 2024.01.18 |
---|---|
[FTZ] level 16 풀이 <BOF-함수 덮기> (0) | 2024.01.18 |
[FTZ] level 14 풀이 <BOF-그냥덮> (0) | 2024.01.18 |
[FTZ] level 13 풀이 <BOF-strcpy+i> (0) | 2024.01.18 |
[FTZ] level 12 풀이 <BOF-gets> (0) | 2024.01.18 |