Linux Capability探索實驗


Linux內核從2.1版本開始,就開始支持Capabilities的安全機制。Capabilities安全機制提出的目的在於實現系統特權操作的更加細粒度的訪問控制,使用戶能夠根據實際的安全需求來控制root進程擁有的權限范圍,從而取消root進程多余權限帶來的安全隱患。在Capabilities機制中,所有權限被分割成比較具體和細小的權限(並將分割出來的每種細小權限稱為權能),每種權能代表着root用戶進行某種特權操作的權限;系統中只有進程和可執行文件具有權能,系統根據一定的安全策略來賦予進程權能,並根據進程擁有的權能來進行特權操作的訪問控制。

第一步:環境搭建

Libcap庫能夠使用戶級別的程序與capability特性做交互,一些Linux發行版不包括這個庫,在環境中已經有、usr/include/sys/capability.h這個文件,為了避免老版本的影響,我們還是刪掉以前的,然后重新下載一個。代碼如下:

在實驗樓中運行如下:

實驗樓

實驗樓

編譯完成后將make生成的文件安裝到系統目錄中

實驗樓

第二步:登錄運行

安裝完成后,我們首先以普通用戶登錄並運行以下命令:

從上圖可以看出,ping命令成功運行。如果ping命令中包含漏洞,那么整個系統可能會被入侵,我們能否移除這些權限 ?
現在讓我們關閉程序的suid位:

顯示當前目錄下文件詳細信息:文件所有者具有讀取寫入執行的所有權限,同組用戶具有讀取執行的權限、其他用戶具有讀取執行的權限.
我們將其關閉后,我們現在再ping百度看會發生什么

它會提示你操作不被允許。這是因為ping命令需要打開RAW套接字,該操作需要root權限,這就是為什么ping是Set-UID程序了。現在我們分配cap_net_raw給ping:

發現此時又可以連接到baidu.com

接着我們進行修改密碼, seed 用戶的密碼是 dees

這步證明一開始無法修改密碼試了好幾次還以為做錯了

接着我們分配了cap之后就可以成功修改密碼

現在切換到 /home/shiyanlou/libcap-2.21/libcap目錄下,編輯 cap_proc.c文件,在該文件下加入下列代碼:

int cap_disable(cap_value_t capflag) 
{
    cap_t mycaps;

    mycaps = cap_get_proc();
    if (mycaps == NULL)
        return -1;
    if (cap_set_flag(mycaps, CAP_EFFECTIVE, 1, &capflag, CAP_CLEAR) != 0)
        return -1;
    if (cap_set_proc(mycaps) != 0)
        return -1;
    return 0;
}
/* Enalbe a cap on current process */
int cap_enable(cap_value_t capflag) 
{
    cap_t mycaps;

    mycaps = cap_get_proc();
    if (mycaps == NULL)
        return -1;
    if (cap_set_flag(mycaps, CAP_EFFECTIVE, 1, &capflag, CAP_SET) != 0)
        return -1;
    if (cap_set_proc(mycaps) != 0)
        return -1;
    return 0;
}
/* Drop a cap on current process */
int cap_drop(cap_value_t capflag)
{
    cap_t mycaps;

    mycaps = cap_get_proc();
    if (mycaps == NULL)
        return -1;
    if (cap_set_flag(mycaps, CAP_EFFECTIVE, 1, &capflag, CAP_CLEAR) != 0)
        return -1;
    if (cap_set_flag(mycaps, CAP_PERMITTED, 1, &capflag, CAP_CLEAR) != 0)
        return -1;
    if (cap_set_proc(mycaps) != 0)
        return -1;
    return 0;
}

運行以下命令編譯安裝libcap:

$ sudo make 
$ sudo make install


編譯安裝完成之后,我們在 /home/shiyanlou/libcap-2.21/libcap 目錄下新建一個 use_cap.c 文件,

在該文件下加入如下代碼:

#include <fcntl.h>
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <linux/capability.h>
#include <sys/capability.h>
int main( void )
{
    if ( open( "/etc/shadow", O_RDONLY ) < 0 )
        printf( "(a) Open failed\n" );

    if ( cap_disable( CAP_DAC_READ_SEARCH ) < 0 )
        return(-1);
    if ( open( "/etc/shadow", O_RDONLY ) < 0 )
        printf( "(b) Open failed\n" );

    if ( cap_enable( CAP_DAC_READ_SEARCH ) < 0 )
        return(-1);
    if ( open( "/etc/shadow", O_RDONLY ) < 0 )
        printf( "(c) Open failed\n" );

    if ( cap_drop( CAP_DAC_READ_SEARCH ) < 0 )
        return(-1);
    if ( open( "/etc/shadow", O_RDONLY ) < 0 )
        printf( "(d) Open failed\n" );

    if ( cap_enable( CAP_DAC_READ_SEARCH ) == 0 )
        return(-1);
    if ( open( "/etc/shadow", O_RDONLY ) < 0 )
        printf( "(e) Open failed\n" );

}

之后,使用以下命令編譯運行:

$ gcc -c use_cap.c
$ gcc -o use_cap use_cap.o -lcap
$ ./use_cap

結果如下:

整個程序運行完畢.

課后問題

問題一、當我們想動態調整基於ACL訪問控制權限的數量時,應該怎么做?與capabilities比較哪種更加便捷?
ACL訪問控制即通過查詢訪問控制列表來獲得訪問主體權限的訪問控制。當我們想動態調整基於ACL訪問控制權限的數量時,我們通過修改訪問控制列表中用戶的訪問權限來進行調整。ACL方式與capabilities相比,capabilities更便捷。Linux提供了直接修改進程權能的系統調用sys_capset(),進程可以通過sys_capset()調用來直接修改除init進程以外的任何進程的各權能集。而ACL需要調整訪問控制列表中文件的安全域和權限等進行權限調整。

問題二、當程序(以普通用戶運行)禁用cap A時,它遭到了緩沖區溢出攻擊。攻擊者成功注入惡意代碼並運行。他可以使用cap A么?如果線程刪除了cap A呢,可以使用cap A么?
當程序(以普通用戶運行)禁用cap A時,它遭到了緩沖區溢出攻擊。導致cap A沒有成功禁用,攻擊者成功注入惡意代碼並運行,可以使用capA。如果線程刪除了capA,則capA已經成功禁用,攻擊者不可以使用capA。

問題三、問題如上,改用競態條件攻擊。他可以使用cap A么?如果線程刪除了cap A呢,可以使用cap A么?
改用竟態條件攻擊,程序禁用cap A,竟態攻擊者搶占資源,可以獲得capA使用權限。如果線程刪除了capA,竟態攻擊者依然可以搶占資源,取得capA的使用權限。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM