Pwnable/FTZ

[FTZ] level 14 풀이 <BOF-그냥덮>

lvolzoo 2024. 1. 18. 10:36
반응형

ID : level14

PW : what that nigga want?


 

1.

 

어김없이 hint를 읽어줍시다. 이번에는 check의 값이 0xdeadbeef면 쉘을 띄우네요.

리턴값을 덮을 필요 없이 check의 값만 덮어 씌워주면 될 것 같습니다!

 

그런데 buf에 입력을 45바이트로 제한하네요.

 

 

fgets(buf, 45, stdin);

buf : 문자열이 저장될 포인터

  • 45 : 입력받을 문자열 길이
  • stdin : 입력받을 스트림 지정

fgets은 이렇게 이해하면 됩니다.

 

 


attackme를 디버깅하기 위해 디버깅 권한이 있는 tmp디렉토리로 복사하여 디버깅 해줍시다.

근데 tmp디렉토리로 복사하는 건 버퍼의 시작위치를 알기 위해서니까 환경변수로 하거나 지금처럼 값만 덮을때는 그냥 level디렉토리에서 디버깅 할 수 있음.

 

 

<main+3>을 보면 0x38만큼 공간이 배정됐네요. 0x38은 십진수로 56입니다.

(프롤로그 바로 밑의 sub만 신경 쓰십시오)

 

그런데 56안에 buf(20), check(4), crap(4)가 들어가는 건 알겠는데 dummy가 어디에, 얼마의 크기로 위치하는지 모르겠어서 구글링을 했습니다.

 

 


그 결과, intel로 설정해주고 디버깅 하면 출력이 다르다는 걸 깨달았습니다..!

gram노트북은 원래 intel기반인줄 알았는데 왤까요..?

 

buf[20] [ebp-56]

dummy[20]

check[4] [ebp-16]

crap[4]과 dummy[8]

SFP[4]

RET[4]

 

[ebp-xx] 부분을 집중해서 분석하면, 스택 구조가 이렇게 되는걸 알 수 있습니다.

사실 아직 잘 모르겠음. dummy가 언제 위치하는지, 프롤로그 밑의 숫자로만 구조를 어떻게 아는지. 추후 수정 예정

 


 

- <main+17>부분을 보면, buf 와 ebf 사이의 거리가 56임을 알 수 있다.

ret는 ebf보다 4바이트 위에 존재하므로(항상), buf와 ret 사이의 거리는 60이다.

 

<main+29>부분을 보면, check와 ebf 사이의 거리가 16임을 알 수 있다.

따라서 check와 ret 사이의 거리는 20이다.

 

그러므로, buf와 check 사이의 거리는 60-20=40 바이트 임을 알 수 있다.

- 버퍼와 체크 사이의 dummy가 20바이트임을 알게 됨.

- <main+3> 부분에서 ret와 sfp를 제외한 스택의 크기는 0x38=56임을 알 수 있으므로, 체크 아래에 있는 dummy의 크기는 8바이트임을 알게 됨.

 

 

 

 

2.

 

check에 0xdeadbeef만 넣어주면 쉘이 따지므로,


페이로드는

(python -c 'print "0x90"40 + "\xef\xbe\xad\xde"';cat)|./attackme

 

(페이로드 입력해도 아무것도 안뜨길래 쉘 안따진 줄 알았는데 따진거였다;; 사진은 삽질의 결과^^..)

 

 

결국, 스택 구조를 이해하는 게 관건이었음.

 

 

 

(2020.02에 작성한 글을 가져왔습니다.)

반응형