오래 못 할 짓 하지 않기
[ 컴퓨터 보안 ] 6. Race Condition 본문
- Race Condition ( 경쟁 상태 )
: 여러 개의 프로세스가 하나의 자원에 동시에 접근할 때
접근 순서에 따라 결과가(값이나 상태) 달라지는 것
OS에서는 자원에 대해서만 했었는데, 더 다양하게 쓰이는 예시들이 많다.
이건 많이 봤던 예시일 거다.
이런 함수가 있다고 할 때 Mutex나 세마포어 없이 실행한다고 해보자.
1000원이 있는 상태에서 두 개의 Requests가 들어왔다.
900원 인출 / 500원 인출
✚ 정말 이상적인 case :
1. 900원 인출 끝
➡️ 500원 인출 시도 중에 조건문에 걸려 else문으로 넘어감
✚ Race condition 으로 인한 case :
1. 900원 요청에서 if문 통과
2. 500원으로 Contxt switch, 500원 요청에 대한 if문 통과
(900,500 둘 다 통과)
3. 1000 - 900을 하고, 그 값에서 500을 뺴고
( 둘 다 실행해도 또 1000이란 값을 가져오는 순서에 따라 100이나 500이 잔금이 될 수도 있다.)
... 900원 500원 둘 다 요청이 수락됨
이젠 권한 확인에 대한 Race Condition을 확인해보자
access( { 파일 이름 } , 어떤 권한 )
= 현재 파일을 실행하는 유저가 해당 파일 이름에 대한 권한 유무 체크
그럼 위 if문에 대하여, {파일 이름}에 권한이 있는 유저만 통과할 수 있다고 해보자.
여기에서 Race Condition을 쓰면 어떨까?
if 조건을 판단할 때만, 내가 권한을 가지고 있는 파일로 검사를 받고
그 뒤에는 다시 root만 다룰 수 있는 파일에 접근한다.
위와 같이 공격을 하려면 순서가 안 맞을 수도 있으니
- Vulnerable program 을 loop로 돌리고
- Attacker program 을 끼워넣는 방식으로 간다.
이렇게 계속 반복하다보면 우리가 원하는대로 순서가 한 번은 맞지 않을까 하는 아이디어에서 시작한다.
그냥 if문 통과할 때만 잠깐 파일 주인인 척 가면쓰고
통과하면 다시 가면 벗는 거
위 예제에서는 그 가면을 Symbolic Link한 파일로 함.
코드 분석
/tmp/XYZ 에 권한이 없는 유저 상태라고 해보자.
그럼 vulp.c를 반복시키면 이건 No permission이 계속 나올 것이다.
그 사이에 이 코드를 실행시킨다고 생각해보자.
~~~ / myfile 은 내가 만든 파일임으로 본인에게 모든 권한이 있다.
vulp.c 에 있는 access if 문을 이걸로 통과할 수 있지 않을까?
1. 조건문 통과를 위한 link
/tmp/XYZ 파일의 링크를 myfile로 해보자.
난 myfile에 대한 권한이 있으므로 access 조건에 통과한다.
2. 침투하려는 파일에 link
통과한 이후에 다시 링크를 /etc/passwd 로 바꾼다.
(유저 계정을 다루는 곳으로, 원래 root만 접근 가능)
하지만 if는 이미 통과했기 때문에 그냥 파일에 바로 쓸 수 있음.
3. 침투한 파일을 조작하기
미리 적어둔 파일의 내용을 조작하려고 했던 파일에 넣는다.
제대로 값이 들어갔는지 확인하는 쉘 함수
시작하기 전에 old라는 변수에 " ls -l /etc/passwd " 의 결과를 담아둔다.
그리고 계속 실행할 때마다 new라는 변수에 해당 명령어의 결과를 새로 담는다.
그걸 비교해서 같으면 다시 반복하고
다르면 종료한다.
결과
Counter 치는 법
- Atomic Operation : 조건 검사 ➡️ 조건에 따른 행동 사이에 걸리는 시간을 줄인다.
- Repating Check and User : 다른 프로세스가 중간에 치고들어오지 못하게 한다.
- Sticky Symlink Protection : Symbolic Links 가 만들어지지 못하게 한다
- Principles of Least Privilege : 뭘하든지 필요한 만큼만 권한을 준다.
📌Atomic Operation
파일을 열면서 권한 검사까지 하는 Flag를 추가한다.
실제로 이런 기능은 없고 그냥 idea 로만 생각하면 된다.
➡️ 해당 파일에 대해서 Real User ID가 권한이 있는지 확인하면서 연다.
📌Repeating Check and Use
- fd 3개를 만들고, 3번 다 같은 파일에 Access한다.
➡️ 파일에 데이터를 쓰기 전에, 3개의 fd가 가리키는 node를 비교한다.
➡️ 가리키는 node가 같으면 파일에 작성한다.
> 아쉬운 점
: 모든 fd가 다 침투에 성공한 파일을 가리킨다?
➡️ 별 수 없음 그냥 축하해줘야 함
📌Repeating Check and Use
Symbolic Link로 들어온 유저에게는 권한 검사를 한다.
if ( Link된 원본 파일 주인의 ID 이나 EUID == 지금 SymLink로 Access하는 사람 ID )
if ( ( '심볼릭 링크의 소유자' OR '심볼릭 링크가 위치한 디렉토리의 소유자' )
== 지금 SymLink로 Access하는 사람의 EUID )
ex) A가 hello.txt파일을 만들었고, B가 그에 대한 SymLink 파일을 만들어서 접근을 한다.
➡️ if ( 심볼릭 링크가 위치한 디렉토리의 소유자 == 지금 SymLink로 Access하는 사람의 ID )
= if ( A == B ) 를 검사한다.
2번 거절당한 걸 보면, Symlink Owner 는 root인데
파일(혹은 dir)주인은 seed라서 안 됨
📌 Principle of Least Privilege
시작할 때 EUID,RUID 를 저장해두고
- 권한에 제약을 두고 해야할 땐 RUID를 사용
- EUID 권한이 필요할 땐 권한 부여
Dirty COW
여기에서 COW는 Copy On Write이다.
Child Proccess가 원본을 가져와 Copy On Write를 통해 파일을 만들고
그 파일 가리키고있는 VM의 Pointer를 , Write() 하기 직전에 원본으로 바꾼다.
이렇게 복사본에 들어가야 할 내용들이
Copy의 원본에 들어가는 경우를 말한다.
쓰려고 하는 Thread1 + 메모리에서 copy를 없애는(=원본 파일을 가리키게 하는) Thread2
우리는 Root권한 계정에 대한 데이터를 하나 만들고
COW를 통해 원본 파일에 집어넣을 예정
일반적인 COW는 다음과 같다.
1. 복제본을 만들어 메모리에 매핑시킨다.
2. 페이지 테이블이 업데이트되면서 VM이 새로 만들어진 Memory 를 가리킨다.
3. 가리키는 곳, 해당 메모리에 쓴다.
하지만 공격을 하는 경우에는 아래와 같이 한다.
1. 복제본을 만들어 메모리에 매핑시킨다.
2. 페이지 테이블이 업데이트되면서 VM이 새로 만들어진 Memory 를 가리킨다.
( ‼️ 공격 ‼️) 페이지 테이블을 바꿔서 현재 가리키는 메모리를 원본으로 돌린다. ( ‼️ 공격 ‼️)
3. 가리키는 곳, 해당 메모리에 쓴다.
예제
- 루트가 아니었던 나를 루트로
1001 , 즉 일반 유저 권한만 갖고 있던 나를
0000 루트 권한으로 업그레이드 시키려고 한다.
- /etc/passwd 파일을 공격할 예정이다.
- fstat를 사용해서 크기를 가져와서 Mapping을 함.
대신 읽기 전용이지만, write를 할 경우 매핑된 곳에서 새로 COW를 할 예정이다.
- 그렇게 읽은 파일에서 testcow:x:1001가 있는 위치를 strstr로 찾는다.
- Thread2개를 부른다.
1) COW 메모리 가리키는 걸 없애는 Thread
- MADV : Memory 사용 관련 advise받기
-DONTNEED : 현재 지정한 MEM 영역이 더 이상 필요하지 않다
= 이에 맞게 Memory를 다시 재정비해주라
2) 입력 받은 데이터를 메모리가 가리키는 주소에서부터 적는 Thread
전체 코드
따라서 순서는
1. Thread Write : While에 들어감
2. Thread Madv : 메모리 재정비
3. Thread Write : 재정비된 메모리에서 본인은 복제본에 쓴 줄 알고있지만, 2로 인해서 원본에 쓱쓱
결과
➡️ DIRTY COW 기법 = Race Condition + Memory Mapping 문제
(출처)
한동대학교 고윤민교수님 - 컴퓨터보안
'3학년 2학기 > 컴퓨터 보안(Computer Security)' 카테고리의 다른 글
[ 컴퓨터 보안 ] 8. Cryptography 대칭키 ( + 비대칭키 ) (0) | 2024.10.15 |
---|---|
[ 컴퓨터 보안 ] 7. Cryptography - 치환 / 재배열 / 암.복호화 (0) | 2024.10.15 |
[ 컴퓨터 보안 ] 5. Buffer Overflow (0) | 2024.10.05 |
[ 컴퓨터 보안 ] 4. Capability Leaking / Environment Variable (0) | 2024.09.10 |
[ 컴퓨터 보안 ] 3. Authentication (인증) + Set-UID 특수권한 (0) | 2024.09.06 |