mma ctf 2nd 2016 greeting write up
1일 1폰 스터디를 진행하면서 해당 문제를 풀어보게 되었다.
Binary Analyse
해당 문제를 아이다로 헥스레이해보면 위의 결과를 얻을 수 있다. 취약점은 바로 찾을 수 있다. printf()에서 FSB 취약점이 발생한다.
사용자에게서 이름을 받고, sprintf() 함수를 이용해서 변수에 넣고, 이것을 printf()로 바로 출력한다.
시나리오
해당 바이너리에 FSB가 있는 것을 확인했다. BBBB 자리에 다른 주소값을 넣고 맨 마지막 %08x를 %n 로 바꿔서 해당 주소값에 다른 값을 넣을 수 있다.
system@plt 가 있다. 처음에는 그냥 printf@got 를 system@got 값으로 바꿔서 쉘을 따려고 했으나, 이게 안되는 것을 알았다.
FSB로 printf@got 를 system@got로 바꿔도 printf((const char *)&string_to_print); 뒤에 오는 printf() 함수가 없기 때문에 공략 불가능하다.
근데 여기서 개쩌는게 .fini_array를 덮어쓰는 거다.
.fini_array는 객체지향으로 따지면, destructor (종료자 혹은 소멸자) 같은 역할을 하는 것이다.
.fini_array가 가르키는 값을 소멸자의 주소값이다. GDB로 확인했다.
(readelf -S 로 나온 값)
[20] .fini_array FINI_ARRAY 08049934 000934 000004 00 WA 0 0 4__do_global_dtors_aux에 대한 정보는 다음 링크를 확인하자.
그럼 우리는 .fini_array 값을 main의 주소로 덮게 되면
FSB 취약점이 있는 printf() 함수를 여러번 호출할 수 있게 되고,
그리고 마지막엔 system() 함수를 통해 쉘을 딸 수 있는 것이다.
.fini_array에 main의 주소를 덮게 되면 약간 다음의 형태로 코드가 바뀐다.
while (1)
main()
처음 돌때는 .fini_array에 main 값을 덮어쓴다.
두 번째 돌때는 getnline()을 이용해서 원하는 커맨드를 .bss 영역에 저장한 다음,
system() 함수를 실행시키자.
'write-ups > CTF' 카테고리의 다른 글
christmas CTF PICTUBE Write up (0) | 2017.12.27 |
---|---|
2017 ROOT CTF write up (0) | 2017.12.26 |
codegate 2017 babypwn write up (1) | 2017.12.18 |
plaid ctf 2013 ropasaurusrex write up (0) | 2017.12.14 |
codegate 2017 EasyMISC write up (0) | 2017.12.13 |