System&Write up/Pwnable.kr

[pwnable.kr] Toddler's Bottle - passcode

Jubil 2017. 11. 24. 20:16
반응형

[pwnable.kr] Toddler’s Bottle – passcode

 


 


 

내용을 보아하니 there was some compiler warning. 컴파일러에서 경고가 나는 듯 합니다.

 

ssh로 접속해서 code를 열어봅니다.



 

warning을 확인해보기 위해 code를 가져와서 직접 컴파일 해봤습니다.

 


 

login 함수에서 scanf 함수를 호출할 때, 취약한 부분이 있는 것 같습니다.

 

원래 scanf 함수에서는 &var, 변수의 주소를 받아 참조해서 값을 저장합니다. 하지만 저기 변수의 주소가 아닌 변수 자체를 넣었기 때문에, 변수에 들어있는 값을 주소로 참조하여 %d로 받아서 저장합니다.

 

, 저 변수에 원하는 주소가 들어있다면, 그 주소의 값을 덮어쓸 수 있습니다.

 


welcome 함수가 끝나고, 스택이 정리된 후 바로 login 함수가 호출됩니다. , welcomeebploginebp는 같은 값을 가질 것입니다.

 


 

welcome 함수에서는 0x88(136)만큼 공간을 확보하고, scanf 함수의 두 번째 인자인 name의 시작 주소가 ebp-0x70(112)라는 걸 알 수 있습니다.

그러면 name의 공간은 ebp-0x70(112) ~ ebp-0xc(12)일 것입니다.

 


 

login 함수에서는 0x28(40)만큼 공간을 확보하고 첫 번째 scanf의 두 번째 인자인 passcode1의 공간은 ebp-0x10(16) ~ ebp-0xc(12)입니다.

 

여기서 passcode1에는 초기화 없이 선언만 했기 때문에, 쓰레기 값이 들어가게 됩니다.

하지만, name이 사용했던 공간을 passcode1이 재사용하게 됩니다.

 

nameebp-0x70(112) ~ ebp-0xc(12), passcode1ebp-0x10(16) ~ ebp-0xc(12)이기 때문에, name의 마지막 4byte를 이용해서 passcode1을 변조할 수 있고, 그럼 passcode의 값이 가리키고 있는 주소의 값도 변조할 수 있게 되는 것입니다.

 

여기서는 GOTPLT를 알아야하는데, 위에 사용자 정의 함수가 아닌 라이브러리 함수는 뒤에 @plt라고 써있는 걸 볼 수 있다. , 라이브러리 함수를 호출하면 PLT가 호출되고, GOT로 점프합니다.

 

첫 번째 호출의 경우, GOT에 함수의 주소가 저장되어 있지 않아서 다시 PLT+6으로 돌아가서 dl_resolve를 통해서 함수의 주소를 GOT에 저장하고 함수로 점프합니다. 하지만 그 후로는 이미 함수의 주소가 GOT에 저장되어 있어서 PLT -> GOT -> 함수 이렇게 바로 점프하게 됩니다.

 

그런데 GOT에 다른 주소가 쓰여 있다면, 함수를 실행했을 때, 다른 곳으로 점프하게 됩니다. 저는 fflush 함수의 GOT를 밑에 system(“/bin/cat flag”); 의 주소로 Overwrite해서 문제를 풀겠습니다.

 

첫 번째로, passcode1의 주소인 name의 마지막 4byte부분은 다시 말해서 name의 처음 주소 + 96byte이라고 할 수 있습니다.

 

두 번째로, fflush 함수의 GOT를 덮어쓸 것이기 때문에 찾아줍시다.


0x0804a004입니다.

 

세 번째로, system(“/bin/cat flag”)의 주소를 찾아줍시다.


0x080485e3입니다.

 

필요한 부분을 다 찾았으니 payload를 구상해보면,

 payload : 96byte 더미 + fflush 함수의 GOT 주소 + system(“/bin/cat flag”)의 주소(%d이기 때문에 10진수로 넣어줘야 함)


 

payload : (python –c ‘print “A”*96 + “\x04\xa0\x04\x08” + “134514147”’; cat) | ./passcode

 


flag가 출력됩니다.

반응형