EASY7

Race Condition 경쟁조건 본문

보안 공부/취약점 실습

Race Condition 경쟁조건

E.asiest 2019. 9. 4. 21:30

Race Condition 경쟁조건

다중 프로세스 환경에서 두개 이상의 프로세스가 동시에 수행될 때 발생되는 비정상적인 상태를 의미한다.

임의의 공유자원을 여러개의 프로세스가 경쟁하기 때문에 발생한다.

 

일반계정의 프로세스와 관리자의 힘을 가진 프로세스가 경쟁해서 이기면 관리자 힘을 획득할 수 있는 현상.

대표적인 예로 심볼릭 링크를 이용하는 예이다.

 

 

 

 

 

1. fork 함수의 이해

(참고 : https://codetravel.tistory.com/23)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <unistd.h>
 
int main() {
    int x;
    x = 0;
     
    fork();
     
    x = 1;
    printf("PID : %ld,  x : %d\n",getpid(), x);
     
    return 0;
}
cs

 

fork는 자식 프로세스를 생성해주는 함수. unistd.h라이브러리에서 system call로 정의되어있다.

fork함수를 호출하는 프로세스가 부모 프로세스가 되고 새롭게 생성되는 프로세스가 자식 프로세스이다. 

함수 실행하면 자식 프로세스의 PID가 반환된다.

자식 프로세스는 부모 프로세스의 메모리를 그대로 복사하여 가지고 fork함수 호출 후 각자의 메모리를 사용해서 실행된다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <unistd.h>
 
int main() {
    int x;
    x = 0;
     
    fork();
     
    x = 1;
    printf("PID : %ld,  x : %d\n",getpid(), x);
     
    return 0;
}
cs

결과 : 2570 부모 프로세스/2571 자식프로세스

알 수 있는 것.

자식프로세스는 부모 프로세스의 메모리를 복사하기 때문에 x=1이라는 변수를 알고 있다.

두 프로세스가 각자 마이웨이로 실행된다.

 

 


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
 
int main() {
     
    pid_t pid;
     
    int x;
    x = 0;
     
    pid = fork();
     
    if(pid > 0) {  // 부모 코드
        x = 1;
        printf("부모 PID : %ld,  x : %d , pid : %d\n",(long)getpid(), x, pid);
    }
    else if(pid == 0){  // 자식 코드
        x = 2;
        printf("자식 PID : %ld,  x : %d\n",(long)getpid(), x);
    }
    else {  // fork 실패
        printf("fork Fail! \n");
        return -1;
    }
     
    return 0;
 
}
cs

알 수 있는 것.

fork하면 자식 프로세스의 PID가 반환되는데. 그 반환되기 전에 자식프로세스가 메모리를 복사하기 때문에

자식프로세스의 변수 pid는 여전히 0이다.

 

 

 

 

 

2. 경쟁 조건 해보기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
 
void main(void)
{
    int childpid;
    int a,b;
    
    
    if((childpid = fork()) >0) {
        for(a = 0; a < 100; a++){
            if(a % 2 == 0printf("O");
        }
        exit(0);
    }
    else{
        for(b = 0; b < 100; b++) {
             if(b % 2 == 1printf("X");
        }
        exit(0);
    }
}
 
cs

 

왜 경쟁조건이 되지 않을까?
반복문 1000번을 돌려봐도 동일...뭐야뭐야

블로그 주인장님께 질문을 드렸는데! 친절하게 답변을 받았습니다~

100번 정도는 스케쥴 한사이클에 끝낼 수 있는 양이라고 합니다!

해결책 1.

반복문을 백만번으로 늘려보자!

그래서 백만번으로 반복문을 돌렸더니 이렇게 O와 X가 번갈아가면서 나옵니다. 그동안의 삽질ㅠㅠ (감격의 눈물)

 

해결책 2.

sleep(1)을 넣어보라고 하시네요! 프로세스가 1초 쉬는 동안 프로세스 정책에 따라 다른 프로세스가 CPU를 점유할 수 있다!

 

1000000번을 돌리면 OX가 번갈아가며 나오는 것을 알 수 있다.

그런데.. 왜 출력물이 한꺼번에 나올까 해서 블로그 주인님께 여쭤봤는데!

stdout 버퍼에 쌓아놓고 flush로 한번에 출력하기 때문이라고 합니다! .. 그래서 개행문자(\n)을 추가했더니.. 100번을 돌렸는데 중간에 O사이에 X가 하나 나오네요????!!!!!! 비록 하나의 X지만.. 참 고맙네요 ㅠㅠㅠ 궁금증 해결!!

경쟁하고 있는 프로세스들!! 고놈 혼자 외롭게 튀어나왔네~

sleep(1)과 개행문자, 100번 반복! 으로 돌리니 이렇게 착하게 나옵니다!!

성공한 코드:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
 
void main(void)
{
    int childpid;
    int a,b;
    
    
    if((childpid = fork()) >0) {
        for(a = 0; a < 100; a++){
            if(a % 2 == 0printf("O \n");
            sleep(1);
    }
        exit(0);
    }
    else{
        for(b = 0; b < 100; b++) {
             if(b % 2 == 1printf("X \n");
             sleep(1);
    }
        exit(0);
    }
}
 
cs

 

 

 

 

 

3. 심볼릭 링크를 이용해서 경쟁조건 해보기

1) 백도어 만들기

UID, GID 모두 0(root계정)으로 설정하기

 

2) 임의의 사용자가 백도어 프로그램을 실행시킬 수 있도록 SETUID 설정하기

# chmod 4755 backdoor.c

3) 심볼릭 링크 생성

# ln -s backdoor.c racecondition.c

 

 

4) root 사용자가 백도어 파일을 삭제하여도 심볼릭 링크는 링크정보가 그대로 남아있다.

5) root 사용자가 backdoor.c라는 이름의 파일을 같은 디렉터리에 생성하면 다시 심볼릭 링크는 유효하게 된다.

6)하지만...!!! 심볼릭링크는 새로 생긴 파일의 권한을 따른다.

이럴꺼면 2번의 setUID는 왜 설정했는가! 그리고 이게 왜 경쟁조건일까?

참조 : https://blog.z3alous.xyz/73

 

 

race condition(경쟁 조건)attack

경쟁 조건이란? 두 프로세스간에 리소스(resource)를 사용하기 위해서 다투는 과정으로, 본래 해킹기법을 칭하는 것이 아니다. 알려진 코드를 통해 경쟁 조건의 원래 의미를 알아보자. 여기서 fork()라는 함수는..

blog.z3alous.xyz

...더보기

레이스 컨디션의 공격의 기본

 1. 취약 프로그램이 생성하는 임시 파일의 이름을 파악

 2. 생성될 임시 파일과 같은 이름의 파일을 생성

 3. 이에 대한 심볼릭 링크를 생성

 4. 원본 파일을 지운 채 취약 프로그램이 심볼릭 링크를 건 파일과 가은 파일을 생성할 때를 기다린다.

 5. 생성되었을 때, 심볼릭 링크를 이용해 파일 내용을 변경 -> 변경 안됨;;

 6. 시스템은 변경된 파일을 자신이 생성한 임시 파일로 생각하고 프로세스를 진행시킬 것이고,

    공격자는 관리자 권한으로 실행되는 프로그램에 끼어들어 무언가를 할 수있는 여지를 만든다.-> 이게 경쟁조건일까..



출처: https://blog.z3alous.xyz/73 [Lucete]

'보안 공부 > 취약점 실습' 카테고리의 다른 글

ghost(CVE-2015-0235)  (0) 2019.09.10
Routing Table, ARP Table, MAC Table  (0) 2019.09.04
세션 하이재킹 hunt 실습  (0) 2019.08.17
CVE-2019-0193  (0) 2019.08.13
FTP 2.3.4 command execution  (0) 2019.08.10
Comments