Set-UID 기능 유출 공격

Set-UID 기능 유출 공격

set-uid에 대한 공격을 C보여주는 프로그램이 있습니다 .capability leak

// cap_leak.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

void main()
{  
    int fd;  char *v[2];  
    /* Assume that /etc/zzz is an important system file, and it is owned by root with permission 0644. Before running this program, you should create the file /etc/zzz first. */  

    fd = open("/etc/zzz", O_RDWR | O_APPEND);

    // Print out the file descriptor value  
    printf("fd is %d\n", fd);    
    if (fd == -1) 
    {     
        printf("Cannot open /etc/zzz\n");     
        exit(0);  
    }  
    // Permanently disable the privilege by making the  
    // effective uid the same as the real uid  
    setuid(getuid()); 
    printf("Real user id is %d\n", getuid());    
    printf("Effective user id is %d\n", geteuid());    

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

이는 다음과 같은 결과를 cat /etc/zzz제공합니다.

this is a very important file

이제 이 프로그램을 컴파일합니다.

gcc -o cap_leak cap_leak.c

소유자를 루트로 변경하고 setuid 비트를 활성화합니다.

sudo chown root cap_root
sudo chmod 4755 cap_root

이제 일반 사용자로부터 프로그램을 실행하면 쉘 프롬프트가 나타납니다.

fd is 3
Real user id is 1000
Effective user id is 1000
$whoami
$seed
$echo bbbbbb >&3
$cat /etc/zzz
$this is a very important file
 bbbbbb

fd = 3IE 에 대한 마지막 쓰기는 /etc/zzz성공적이었지만 setuid()파일을 연 후에 함수가 호출되어 기본적으로 실제, 유효 및 저장된 uid를 원래 uid로 설정합니다. 제 질문은 마지막 쓰기가 이후에 수행되었음에도 불구하고 왜 성공하는지입니다. setuid()이 경우 기능 누출을 방지하려면 setuid()어디에 배치해야 하며 그 이유는 무엇입니까?

답변1

파일을 다른 곳에 두어야 할 필요가 없으며 setuid()파일을 쓰기 위해 열어두어서도 안 됩니다.

write()그 이유는 파일 이 호출될 때마다가 아니라 파일을 열 때 권한을 확인하기 때문입니다 .

권한이 없는 쉘이 파일에 쓸 수 없는 경우 쓰기 액세스 권한으로 파일을 열어 둘 이유가 없습니다.

관련 정보