본문 바로가기

WARGAME/FTZ [system]

ftz level 20 [level20]

 

 

 

 

 

level20

 

 

 

 

이문제는 setreuid() 도 있고 간단해 보이지만, 

bleh 는 80 바이트, 그러나 입력으로 받는 크기는 79 바이트로 오버플로우가 가능하지 않아보인다.

 

 

 

 

 

그러나 잘 보면, printf() 에 형식 지정자가 없이 출력을 하는, 즉 포맷 스트링 버그를 발견할 수 있다.

 

*** 포맷 스트링 버그 (Format String bug,  FSB)

 : 버퍼 오버플로우 해킹 기법의 한종류로, 사용자의 입력에 의해서 프로그램의 흐름을 변경시킬수있는 취약점

 : 만일 입력하는 문자열에 서식 문자가 들어가게 되면, 스택의 다음 4바이트를 출력하는 오류가 발생한다.

 : ex. 입력한 서식 문자가 %x 라면 다음 4바이트를 16진수로 출력

 

 

 

 

 

 

따라서 만약 aaaa%x 등을 입력하면?

 

이렇게 일반 문자는 정상적으로 출력이 되지만, %x 부분에서 4f 와 같은 문자열이 출력된다.

 

 

 

 

 

잘 모르겠으니 스택을 대강 그려보면,

대강 이런 식이 될 것이다.

 

 

 

 

 

만약 여기서 빗금친 부분이 0 이라면, printf(bleh) 의 다음 4바이트가 바로 bleh[80] 가 되어

aaaa0x41414141 이 출력되어야 맞을 것이다. 

 

 

 

 

 

 

 

 

 

그러나 위에 입력한 결과와 같이 아니라는 것을 볼 수 있기 때문에

 

%x 를 여러개 입력해 가며 a 가 언제 출력되는지 확인해보다보면, 

%x를 4개 입력했을 시 61 이 뜨는 것을 볼 수 있다.

 

 

 

 

 

 

 

 

이때 여기에서 서식 문자 %n에 대해 살펴볼 필요가 있다.

 

***%n

 :  %n이 나오기 전에 출력된 자릿수를 계산하여 스택의 다음 4바이트에 있는 내용을 주소로 여긴다.

 

이 뜻은, 

만약 스택이 bleh[80] 다음에 바로 printf(bleh) 가 오는 형태라면,

 

aaaa%n 을 입력했다면 aaaa를 출력될 것이고, 지금까지 출력된 자릿수를 계산할 것이다.  

aaaa는 4자리이기 때문에 스택의 다음 4바이트의 내용을 확인, 바로 붙어 있기 때문에 aaaa, 즉 \x61616161 일 것이다.
그럼 이 0x61616161 주소값에 %n 이 나오기 전에 출력된 자릿수를 계산한 후 그 자릿수 4바이트를 입력하게 되는 것이다.

 

%n 은

%10000c%n이라고 표현해서  10000이라는 숫자를 넣을 수도 있다.  ret 주소에 쉘 코드의 주소를 넣을 수 있다는 뜻이 되는 것이다.


 

 

 

 

 

그럼 우리가 ret 주소에 원하는 주소를 넣을 수 있게 되었다는 걸 알았으니,

 

 

***.dtors

 : main 함수가 끝난 후 실행을 하는 명령이 존재 하는 곳

 : 소멸자

 

 : objdump -h 실행파일 | grep .dtors

 : 이 명령어를 이용해 .dtors 의 주소를 알아낼 수 있다. 

 

 

 

이 곳에 쉘코드를 덮어씌워 실행하는 페이로드를 작성하면 되는 것이다.

 

 

 

 

 

 

 

여기서 +4. 즉, 08049598을 하면 ret 이 되는 것이다.

 

0x8049598 에 쉘코드를 주소를 올려야 하는데 0xbffffc8d의 정수값이 x86시스템에서 지정할 수 없는 크기 때문에 %n을 이용해 반으로 나누어 덮어주자.

 

 

 

 

그럼 이제 환경변수를 등록하고, 주소를 보면,

이렇게 나오므로, 0x8049598 에는 \xfef5 (65269)를,

0x804959a 에는 \xbfff (49151) 를 넣어주면 된다.

 

 

 

 

 

 

그리고

aaaa\x98\x95\x04\x08AAAA\x9a\x95\x04\x08%x%x%x%x 에 대한 자릿수 40바이트를

0xfef5에서 빼면, 65269-40=65229 가 되고,

 

또 %n이 앞자릿수를 계산하므로 40+65229=65269을  0xbfff에서도 빼주어야 한다.

그러나 0xbfff(49151)에서 빼게되면 음수가 되기 때문에 0xbfff앞에 1을 붙인 0x1bfff에서 빼서 50034가 된다.

 

 

 

 

 

 

 

 

 

페이로드를 작성하면

"aaaa\x98\x95\x04\x08aaaa\x9a\x95\x04\x08%x%x%x%x%65229c%n%50034c%n" 이 된다.

 

 

 

 

푸는 중 ..

 

 

 

 

 

 

 

 

 

 

 



참고 https://kaspyx.tistory.com/74 

 https://geundi.tistory.com/133 

https://m-youngzzang-for20.tistory.com/78

'WARGAME > FTZ [system]' 카테고리의 다른 글

ftz level 19 [level19]  (0) 2020.05.01
ftz level 18 [level18]  (0) 2020.05.01
ftz level 17 [level17]  (0) 2020.05.01
ftz level 16 [level16]  (0) 2020.05.01
ftz level 15 [level15]  (0) 2020.05.01