write-ups/CTF

mma ctf 2nd 2016 greeting write up

2017. 12. 19. 18:30

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

0x08049934 여기에 있는 값 4 byte를 확인해보자. 


__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