2017. 5. 23. 14:05ㆍSystemHacking/FTZ
level6문제 풀이에 앞서 알아야할 개념부터 설명하겠습니다
[1]
시스템은 신호와 메시지로 정보를 교환합니다
메시지는 Protocol정보규약에 따라서 정의되어 사용되고 리눅스에서 신호는 미리 약속되어있는 signal을 제공합니다
#kill -l signal 명령어를 통해서 신호의 이름과 고유번호를 알 수 있습니다 ㅡ 그림 6.1
#kill -[Signal] [PID] 해당 PID에 해당하는 프로세스에게 신호를 전달합니다
ex) #kill -SGIKILL 100 or #kill -9 100
-> PID가 100번인 프로세스를 종료시키는 신호를 보냄으로써 종료시킨다
각 신호들은 번호가 있고 신호의 이름대신 번호를 사용해서 신호를 보낼 수 있다
< 그림 6.1 >
[2]
추가로 키보드의 입력을 통해서 시그널을 발생시킬 수 있다
1> Ctrl + c = SIGINT(2) 해당 프로세스를 stop시키는 신호
2> Ctrl + z = SIGTSTP(20) 해당 프로세스를 백그라운드로 보낸다
3> Ctrl + \ = SIGQUIT(3) 해당 프로세스를 종료시킨다
[3]
명령어와 키보드로 시그널을 보내는 방법 뿐아니라 소스코드 상에서 시그널을 전달할 수 있다
signal()함수를 알아보자 signal함수는 세가지의 형태로 작동한다
1> signal( 시그널 번호 , SIG_DFL ) (default)
신호를 받은 프로세스는 해당 시그널의 기본 실행동작을 수행한다
signal( SIGINT, SIG_DFL ) => SIGINT 시그널 실행 : 해당 프로세스 중지됨
2> signal( 시그널 번호, SIG_IGN ) (ignore)
신호를 받은 프로세스는 해당 시그널의 신호가 와도 무시하여 아무런 동작을 하지 않는다
signal( SIGINT, SIG_IGN ) => SIGINT 시그널 무시 : 아무런 반응없음
3> signal( 시그널 번호, handler함수 )
신호를 받은 프로세스는 해당 시그널 신호가 오면 handler함수에 지정한 함수를 실행시킨다
signal( SIGINT , handler) => SIGINT가 입력되면 handler함수 실행한다
* 첫입력시 신호에 함수 적용 , 두번째 신호 입력시함수의 내용을 실행 즉, 신호를 두번 보내야 handler함수가 실행된다
문제풀이 시작하겠습니다
< 그림 6.2 >
1을 입력해도 .. 2를 입력해도 .. 아무런 결과가 출력되지 않고 접속이 끊겨버립니다
< 그림 6.3 >
ctrl + \ 신호를 주면 해당 프로세스는 종료되고 다른 신호를 보내면 아무 반응도 일어나지 않습니다
ctrl + c (SIGINT) 신호를 보내주면 " Can't use ctrl+c " 가 출력됩니다
SIGINT신호에 대해서 handler 함수를 지정해주었고 신호가 오면 handler함수가 실행됨을 알 수 있다
< 그림 6.4 >
level6의 시작지점에서 ctrl+c 를입력해서 중단시켯더니 level6의 쉘이 떨어졌습니다 !
무슨 파일들이 있는지 확인해 보면 " tn " 실행파일과 " password " 파일이 있습니다
"password" 파일을 통해 level7계정의 비밀번호를 확인할 수 있고 "tn" 실행파일은 우리를 혼란스럽게 했던 프로그램입니다 !
문제의 해답은 쉽게 알았지만 어떻게 이렇게 동작하는지 " tn " 실행파일을 분석해봅시다
분석량이 좀 많지만 천천히 읽으면 쉽게 이해할 수 있습니다
< 그림 6.5 >
gdb를 실행하고 " tn " 파일을 읽어들인다
< 그림 6.6 >
[1] <main+14>: call <system>
system("cat hint"); => "hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다" 출력
[2] <main+22>: call <getchar>
getchar(); =>문자 하나를 입력받는다
[3] <main+35>: call <system>
system("clear") => clear 명령어 실행
[4]<main+46> ... <main+110>: call <printf>
그림 6.6 오른쪽화면에 보이는 문자열들을 화면에 출력한다
< 그림 6.7 >
[5]<main+126> ~ <main+174>: call <printf>
printf("\n접속하고 싶은 bbs를 선택하세요 : ");
[6]<main+197>:call <signal>
push $0x80484e0 sig_func의 주소
push $0x2 2
=> signal( 2 , sig_func ) => 2번신호는 SIGINT , SIGINT신호가 들어오면 sig_func 함수를 실행해라
[7]<main+233>: call <scanf>
scanf( "%s", &input ) => 사용자에게 문자열 하나를 입력 받는다
< 그림 6.8 >
[8] 빨간 상자 부분
<main+241>: cmpl $0x1,0xfffffffc(%ebp)
입력한 값과 1을 비교합니다
< 그림 6.9 >
첫 시작 주소가 0x080484e0 입니다 main함수 gdb분석 시 signal함수에서 push한 그 주소입니다
sig_func 분석결과 printf()함수를 호출하고 함수는 종료됩니다
gdb분석을 통해 소스코드의 흐름을 알 수 있었고 복원된 소스코드를 확인해봅시다
< 복원된 소스코드 >
#include<stdio.h>
#include<signal.h>
void sig_func(int signo){
printf("Can't use ctrl+c\n");
}
int main(){
char input;
int select , i ;
system("cat hint");
input = getchar(); // 문자하나를 입력받는다
system("clear");
printf("###########################\n");
printf("## ##\n");
printf("## 텔넷 접속 서비스 ##\n");
printf("## ##\n");
printf("## ##\n");
printf("## 1. 하이텔 2. 나우누리 ##\n");
printf("## 3. 천리안 ##\n");
printf("## ##\n");
printf("###########################\n");
for( i=1 ; i<32 ; i++){ // 시그널 신호는 1번부터 31번에 대한 설정
if( i== SIGINT ) {
signal( i , sig_func ); // SIGINT 시그널 신호가 오면 sig_func실행
} else{
signal(i , SIG_IGN); // 다른 신호가 오면 무시 ( ignore )
} // 왜 gdb에는 else 부분이 없는지 의심할 수 있다
} // 왜인지는.. 저도 모르겟습니다..
printf("\n 접속하고 싶은 bbs를 선택하세요 : ");
scanf("%s",&input);
switch ( input ){
case 1 :
system("telnet 203.245.15.76");
break;
case 2 :
system("telnet 203.238.129.97");
break;
case 3 :
system("telnet 201.120.128.180);
break;
default :
if( input != 1 && input != 2 && input != 3 ){
printf(" 잘못 입력하셨습니다. 접속을 종료합니다. \n");
}
}
문제풀이와 gdb분석 모두 완료했습니다
추가로 보안할 점이나 이상한 부분이 있다면 댓글 남겨주시길 바랍니다
'SystemHacking > FTZ' 카테고리의 다른 글
FTZ level8 리눅스 패스워드 파일 크랙 (0) | 2017.05.23 |
---|---|
FTZ level7 암호화 (0) | 2017.05.23 |
FTZ level5 레이스 컨디션 ( Race Condition ) (0) | 2017.05.23 |
FTZ level4 xinetd백도어 (0) | 2017.05.23 |
FTZ level3 system함수의 위험성 (0) | 2017.05.23 |