다양한 기록

Set-UID Privileged Program 본문

운영체제보안

Set-UID Privileged Program

라구넹 2024. 10. 19. 20:59

Password Dilemma

/etc/shadow         ... 

=> -rw-r-----  root shadow

루트 권한이 있어야만 쓰기가 가능

하지만 일반 유저도 비밀번호를 바꾸고 싶을 수 있음

 

Two-Tier Approach

운영체제에서 파인-그레인드 액세스 컨트롤 구현 시 과도하게 복잡해짐

OS는 세분화된 접근 제어를 위해 확장에 의존

권한이 있는 프로그램이 그러한 확장: set-uid 프로그램, 데몬

 

타입

- Deamon in Linux (Services in MS Windows)

- Set-Programs


Set-UID Concept

- 유저가 프로그램을 오너 권한으로 실행하도록 허가

 

RUID (Real) : 프로세스의 실제 오너 아이디

EUID (Effective) : 권한을 나타내는 아이디

 

RUID는 su 명령 사용 시 바뀜

EUID는 Set-UID 프로그램 사용 시 바뀜

 

영구적으로 상승되면 안됨

실행 끝나면 권한 반납

 

sudo chmod 4755 mycat

=> mycat 권한이 -rwsr-xr-x 가 됨


/*
- rwx r-x r-x 1 user_a user_a ….. a.exe
- rw- r- - r- - 1 user_a user_a ….. file2
- rws r-x r-x 1 user_b user_b ….. program
- rw- r- - r- - 1 user_b user_b …. file1
*/
// user_a ruid 25
// user_b ruid 17

// a.exe에서 program exec
...;
// read/write file1
...;
i = getruid();
setuid(i);
...;
// read/write file2
''';

a.exe에서 exec => set-uid 프로그램이니 user_b의 권한으로 program 실행됨

file1을 읽는 시점: euid가 17

file2를 읽는 시점: euid가 ruid인 25로 바뀌어 있음

=> I/O 다 됨

 

다른 예시

컴퓨터를 처음 켰을 때의 프로세스?

init

이건 커널이 다 만들어 주고, 이후의 프로세스는 init에서 포크 및 이그젝을 통해 생성

init -fe> gettty -e> login -~~setgid, setid .., exec> shell

 

* 포크 특징: 호출은 하나지만 리턴은 두개 .. 새 pid가 생성됨

exec은 차일드가 함

 

* Set-UID라고 다 루트가 되는게 아니라 오너가 루트여야 함


왜 Set-UID가 sudo보다 안전한가

Set-UID 프로그램은 일반 유저의 권한을 상승시키는데,

sudo가 직접적으로 권한을 상승시키는 거랑은 다름

할 일이 정해진 애한테 그 일만 시킬 수 있음

 

근데 /bin/sh나 vi을 set-uid 프로그램으로 만들면 위험함


안전하다고 해봐야 공격은 계속 일어남

슈퍼맨의 예시

북쪽으로 가서 왼쪽으로 가라 => 지구의 반대편에서 명령을 받으면?

북쪽으로 가서 서쪽으로 가라 => 얼마나 가라고 안했고 나침반이 고장나 있을 수도 있음

 

 

Set-UID 프로그램에 대한 공격은 4가지

1. User Inputs => 버퍼 오버플로우

2. System Inputs that can be controlled by users => 레이스 컨디션

3. Environment Variables => 환경 변수

4. Non-privileged Process Controlled by User => 권한 누수

 


Attacks via User Inputs

버퍼 오버플로우 (scanf ..)

포맷 스트링 취약점 (printf 인자에 %n..)

 

chsh .. 디폴트 쉘 바꾸는 커맨드

공격자가 이상한 입력을 주면?

chsh -s "/user/bin/zsh\n myroot:???:0:0:Backdoor:/home:/bin/bash"

이런 명령을 넣어버리면 디폴트 쉘을 바꾸고 새 줄을 추가하는데 uid가 0임 => 루트 탈취


Attacks via System Inputs

레이스 컨디션

권한이 없는 파일의 권한이 있는 파일로의 심볼릭 링크, 

world writable folder에 쓰기 (sticky bit)


Attacks via Environmental Variable

 

printenv, env 명령으로 환경 변수 볼 수 있는데

PATH가 존재함

커맨드 실행 시 명령어를 패스에 써진 순서대로 찾음

다른 폴더에 심어진 악성코드 실행의 가능성 존재

system("bin/sh"); 가 system("ls")같은 명령보다 더 안전 (절대 경로)


Capability Leaking

권한을 낮췄는데 권한이 누수될 수도 있음

fd = open("/etc/zzz", O_RDWR | O_APPEND);
if( fd == -1 ) {
    printf("Can not open /etc/zzz\n");
    exit(0);
}

printf("fd is %d\n", fd);

setuid(getuid());

v[0] = "/bin/sh"; v[1] = 0;
execve(v[0], v, 0);

여기 있는 문제점: fd close 안했음

 

실행하면 fd는 기본적으론 3이 될 거고(표준 입/출/에러 이후) 이후 쉘이 실행됨

exec으로 실행되면 fd까지 상속받는데, 해당 fd를 통해 파일에 값을 쓰는게 가능함

해당 파일에 액세스가 제한되어 있어도 가능

=> Capability Leaking

 

해결법: exec 전에 close 해라


User Identity

getuid => ruid

geteuid => euid

 

setuid => euid


int main(int argc, char* argv[])
{
    char* cat = "/bin/cat";
    
    if( argc < 2 ) {
        printf("Please type a file name.\n");
        return 1;
    }
    
    char* command = malloc(strlen(cat) + strlen(argv[1]) + 2);
    sprintf(command, "%s %s", cat, argv[1]);
    
    system(command);
    
    return 0;
}

 

gcc -o catall catall.c
sudo chown root catall
sudo chmod 4755 catall

catall "aa;/bin/sh"
/bin/cat: aa: No such file or directory
#
#
....
root shell!

command가 위에 처럼 되면?

system이 /bin/sh를 실행해버림

그런데 Set-UID 프로그램이라 루트 권한으로 쉘이 켜짐

=> 루트 쉘 탈취

 

방어법

1. 쉘을 dash 쉘 남기고 다 제거 .. euid ruid 비교해서 다르면 ruid 기반으로 쉘을 띄움

2. 아니면 execve 쓰기

 

execve를 쓰면 코드와 데이터가 명백히 분리함

코드와 데이터가 명백하게 분리되는게 안전함

 

* execlp, execv, execvp는 시스템 콜 아님

...

Principle of Isolation (격리의 원칙)

: Don't mix code and data

 

* Attacks due to violation od this principle

system()

XSS

SQL injection

Buffer Overflow attacks

 

Principle of Least Privilege (최소 권한의 원칙)

Set-UID 프로그램을 최소한으로 해야 함

꼭 필요한 경우에만 권한을 높여주고 끝나면 내리기 .. setuid( getuid() )

 

권한이 있는 프로그램은 어쩔 수 없이 필요함 (패스워드 변경 같이)

어쨌든 권한은 필요

1. setuid

2. sudo

3. capability

'운영체제보안' 카테고리의 다른 글

Buffer Overflow Attack  (0) 2024.10.22
Kernel / user mode, kernel mode  (0) 2024.10.14
리눅스 매뉴얼, 커맨드  (0) 2024.10.14
User Authentication  (0) 2024.10.14
Running Command with Privilege  (0) 2024.10.12