[어설픈] 해커스쿨 FTZ Level 19 문제풀이(late upload)

2019. 4. 18. 17:51System Hacking/FTZ

안녕하세요!

오늘도 까먹고 늦게 올린

FTZ 문제 19번을 풀어보도록 할게요!


문제는 아래와 같이 

더럽게 simple 합니다!


main에 

buf[20] 만큼 선언하고!

gets함수로 overflow가 일어나게끔 해놓죠!


저도 맨 처음에 신나서 문제 풀었습니다! 

근데...


문제를 풀어도 권한 상승이 일어나지 않고

계속 level19의 권한이길래

이상했습니다!


그리고 왜 이러지..?

생각을 하고 다른 문제와 비교해보니!

하나가 빠져있었습니다!


직전 문제에서 shellout( )함수 코드를 봐도

setreuid(3099,3099)가 있었죠?


setreuid( id 숫자 , id 숫자)함수를 이용하여

 다음레벨로 권한상승을 시킨 후에

쉘을 시켜야 저희가 원하는 문제가 풀리는 겁니다! 


처음에 저는 그래서

execve 함수를 이용해서 

권한 상승을 시키려고 했습니다!


execve("/bin/sh", ["/bin/sh",0] , 0)


이렇게 하면 권한 상승이 되고!

이후에 system("/bin/sh")를 실행시키면 될 것 같았습니다!


근데 아래를 보니 execve 주소에

\x0a가 들어가 있는 걸 봤습니다!


\x0a가 들어가면 제 input을 제대로 인식을 하지 못하기에

결국 다른 방법으로 풀려고 마음을 고쳐먹었습니다!



그래서 그냥 

이때까지 계속 있던

setreuid( , ) 이 함수를 쓰기로 결심했습니다!


일단 라이브러리 의존성을 확인하기 위해

ldd명령어를 통해 attackme를 확인해봤습니다!


/lib/tls/libc.so.6을 사용하네요! 

주소는 0x42000000이구요!



이 library에서

 setreuid 함수를 찾기위해서 

nm 명령어를 아래와 같이 사용하고 

grep도 사용했습니다!


그랬더니 0x420d7920에 있네요!



그리고 계속 제가 setreuid( , ) 할때

함수 인자들을 비워놨었는데!


그 인자에 들어갈 녀석을 아래와 같이 구했습니다!

setreuid(3100,3100) 으로하면

id값이 3100으로 바뀌기에 (=level20의 아이디)

level 20이 됩니다!




그리고 저희가 이제 구해야 할 인자들을

마저 구하겠습니다!


/bin/sh 문자열을 strings명령어로 아래와 같이 구했구요!


system함수의 주소도 setreuid 함수 주소 구하는거와 동일하게

구했습니다!




그리고 여기서는 

pop pop ret gadget을 사용할 겁니다!


조금 생소할 수 있는데요!

기존의 스택 구조를 보면


ebp

ret addr (setreuid 함수 주소)

ret addr 2 ( setreuid가 끝나고 ret 할 주소) -> system함수 주소

setreuid 1번째 인자 (3100)

setreuid 2번째 인자 (3100)

`````

``````



만약 저렇게 넣으면 system함수에 넣을 /bin/sh인자는 

어떻게 넣으시게요?

setreuid 2번째 인자가 system 함수의 인자로 들어갈 텐데요!


그래서 setreuid 1,2를 모두 스택에서 내보내야해요!

그럴려면! pop을  하면됩니다!


걸리적 거리는 놈들을 

stack에서 pop(뽑아서)해서 

우리가 원하는 곳에서 return 하고

우리가 원하는 인자를 줄 수 있습니다!


그렇게 하려면 

pop pop return 하는 gadget(도구)를 찾아야해요!

 objdump -d ./(파일명)을 통해서 찾을 수 있어요!




쭉쭉 내리다 보면 

아래와 같이 


pop 

pop 

ret


보이시죠?


32bit 환경이라 여기서

pop을 ebx로 하든

pop을 ebp로 하든 

상관없습니다!


걸리적 거리는 놈들을 뽑는게 중요해요!

뒤에 return 을 적는 이유는

앞에 놈들을 뽑고! 

저희가 원하는 위치에서 return 하려구요!


일단 0x0804849d 위치 메모해 두고요!


final payload를 작성하기 전에!

아래와 같이 정리해 보았습니다!


(1) gdb로 까보니 실제 할당된 크기는 40이여서

40 + ebp (4byte)해서 = 44byte 더미


(2) ret_address는 권한 상승을 위해서 setreuid 호출!


(3)그리고 setreuid 인자에는 

3100이 두 개 들어가야 하는데요!

근데 메모리는 hex값으로 이걸 저장하니

3100을 계산기로 hex 변환했습니다!


그랬더니 c1c가 나왔는데!

4byte 크기에 맞게 아래와 같이

00000c1c로 인자세팅 하구요!


(4) setreuid 끝나고 실행될 ret에는

pop pop ret 가젯 주소 적었습니다!


그래야 더 이상 필요 없는 놈들 치우고

저희가 원하는 대로 ret, 인자 세팅 할 수 있으니까요!


(5) pop pop ret에서 ret에 들어가는

자리에 system 함수 주소를 넣습니다!


ret을 system함수로 하라는 뜻이죠?


(6) 더미 aaaa를 넣었는데

이건 system 함수가 끝나고 실행될 ret_address!


(7) 그리고 system 함수의 인자로 들어갈 

/bin/sh 문자열!


그래서 아래와 같이 최종 payload를 완성하면 

쉘이 따지고


권한상승이 된 것도 확인 할 수 있습니다!

고생하셨습니다!