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

所有者をrootに変更し、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()これは、ファイルが呼び出されるたびにファイルが開かれたときに権限を確認するためです。

権限のないシェルがファイルに書き込めない場合は、書き込みアクセス権でファイルを開く理由はありません。

おすすめ記事