IMyoungho 2019. 4. 30. 19:29

이번 문제는 g++ pwn이다. 살짝 어렵다고 생각할 수 있는 문제이다.





Mitigation은 NX만 걸려있었다. ( 스택, 힙, 데이터 영역에 실행권한이 없음 )

Partial RELRO이기 때문에 got overwrite도 가능하다 .




문제를 실행시켜보았다.

실행을 시키면 사용자로부터 입력을 받고 있다.

입력을 하고나면 "So," 다음에 사용자가 입력한 값을 출력해준다.




이번에는 IDA를 이용하여 코드를 보도록 하자.



< main >

main에서는 딱히 별다른 것이 없었고 vuln이라는 함수를 호출하고 있었다.

이름이 vuln인 것을 보니 여기가 바로 취약점이 존재하는 곳인 것 같다.




< vuln >

입력은 fgets로 받고있었는데 길이제한이 있으므로 단순 BOF는

아닐 것 같았다. 그래도 혹시모르니 확인을 해보았다.




음.. 역시 ret까지 0x3c + sfp(4)로 총 64개를 입력할 수 있어야 하는데

fgets는 32개만을 받을 수 있으므로 ret를 덮는 것은 불가능했다.


그렇다면 fgets는 취약한 것이 아니다. 다음의 코드를 찬찬히 보는데

replace함수가 신경쓰였다. 오... 코드를 보니 "I"를 "you"로 replace해주는 것

같았다. 그래서 한 번 내 생각이 맞는지 확인해보았다.




오오오~~ 역시 "I"를 5개 입력하였더니 "you" 5개가 출력됨을 확인했다.

그렇다면 vuln 함수에서 취약한 함수는 바로 맨 아래에 있는

strcpy가 취약한 함수라는 것을 알 수 있었다.


왜냐하면 우리가 버퍼 s 에 입력해서 덮을 수 있는 값은 32개지만

"I"를 입력하게되면 "you"로 대체되기 때문에 만약 "I"를 20개 입력한다면

총 60개("you" 20개)의 값이 버퍼 s 에 복사 될 것이기 때문이다. 그러므로

"I" 20개와 sfp(4)를 덮을 "a" 4개를 입력하게되면 총 64개로 ret 직전까지

덮을 수 있게 되고 그렇게 덮어도 우리는 8개의 값을 더 입력할 수 있으므로

충분히 ret에 어떠한 주소값을 덮어서 공격을 진행할 수 있게된다.



남은 ret는 뭘로 덮을까 하고 보니 get_flag라는 함수가 존재했다.





< get_flag >

그러므로 ret는 get_flag 함수 주소로 덮어주면~~ FLAG를 볼 수 있을 것이다.






gdb로 내가 생각한대로 흘러가는지 확인해보았다.

"aaaa"과 "I" 20개 그리고 ret를 덮을 get_flag함수를 입력하였다.



replace함수가 실행되어서 "I"들이 "you"로 replace되었다~



우리가 원하는대로 ret가 잘 덮인 것을 볼 수 있었다.




< Payload >

위에서 설명한 내용대로 Payload를 구성하여 실행시켰다~





짜잔~ FLAG를 볼 수 있었다~~

반응형