天天看點

技術交流|Dockerfile 中 RUN 後面的敏感資訊檢測

前言

之前學習過一些容器底層原理,再加上之前傾旋師傅提了一個小想法:拿到鏡像,是否可以最大程度還原Dockerfile的内容,因為這個裡面很可能有一些敏感資訊。于是《鏡像反查Dockerfile》文章就誕生了,實際上裡面的技術都是已經有人做好了,我無非是複現,細節補充罷了。

這個事情并沒有結束,秉承着實驗室内部研究必須落地的精神,我想把這個細節落地到工具上去:在雲場景的攻防中,當我們控下一個私有雲的倉庫的時候,通過運作某個自動化工具,将一些敏感資訊提取出來。

準備工作

1. 選擇工具二開還是直接開寫

如果在大學時期,我肯定選擇去直接開寫,鍛煉一些能力。但是後面工作了這麼久,才越來越感受到大道至簡,況且别人已經寫的很好了又無私奉獻。有些時候從0開始,不如從1開始。況且那個1還是一個很成熟,很棒的工具。

2. 選擇哪個工具

其實我首先想到的并不是問脈,而是CDK, 也看了部分的源碼,但是最後從定位來說,并不是很合适。CDK更多的是容器權限,叢集權限,你可以看到CDK中關于Docker漏洞利用方面更多的是逃逸,利用。(隻是定位不太合适,不妨礙CDK是一款優秀的,我也很喜歡的一款工具)

這個時候想起來了長亭的問脈 Veinmind ,Veinmind 有檢測敏感資訊和 history 的異常操作這塊,并且從大次元來說是支援鏡像和容器狀态的。再加上之前也經常用,相對來說很熟悉。那麼我會用到哪些子產品呢?

3. 分析工作

拉取 Veinmind 源碼,發現兩個子產品比較符合:

  1. Veinmind-sensitive(掃描鏡像中敏感資訊)?看起來很符合。
  2. Veinmind-history (掃描鏡像中的異常曆史指令)?從 rules 和介紹來看不是很符合,但是裡面有一些現成的比對docker history的邏輯,這意味着我可以少寫很多代碼。有趣的是 我發現了https://github.com/chaitin/veinmind-tools/pull/38這個 pr ,這位師傅像給問脈的docker history 加一些檢測的規則。
技術交流|Dockerfile 中 RUN 後面的敏感資訊檢測

最終我還是選擇 Veinmind-sensitive 子產品。這個子產品的定位很詳細,是掃描鏡像中的異常曆史指令,這個"異常"可以通過子產品的 rules 去确定他的定位。舉個例子:我在 Dockerfile 中 RUN 後面包含了某一串 token,或者寫一個 password ,你隻能說這麼寫會有敏感資訊,但是本身也沒挖礦操作,沒惡意指令,當然不能說我這個鏡像是有異常指令的。

技術交流|Dockerfile 中 RUN 後面的敏感資訊檢測

繼續分析 Veinmind-sensitive 子產品,發現該子產品主要的檢測邏輯依賴 rules.toml ,檢測内容已經很全面了:鏡像的 env 資訊 、敏感檔案及敏感檔案中的敏感内容。但我們知道,Dockerfile 的編寫中 RUN 後面是可以寫任何指令,包括指令參數都可以,此時這裡可能包含很多敏感資訊,而 Veinmind-sensitive 沒有檢測到。

技術交流|Dockerfile 中 RUN 後面的敏感資訊檢測

對于檢測工具來說,這塊的檢測次元必須覆寫到,這是向 Veinmind 提 pr 的好機會。很多時候我們需要把資訊經過正則列舉出來,并給出相關描述,有沒有用,敏感程度是使用者說了算。

開始Code

首先就是 pycharm 的遠端調試,然後我為自己确定了一個目标,也就是他應該輸出啥樣子的。之後就是看源碼了,其實懂鏡像原理的小夥伴是很好了解寫的邏輯的。

技術交流|Dockerfile 中 RUN 後面的敏感資訊檢測

在功能上,我為自己定了以下目标:

  1. 在敏感内容的檢測中加入docker hisroty
  2. 周遊每一行 docker history的指令,然後将其與正則比對rules去比對(都比對或者可選)
  3. 如果一行指令命中多個正則,需要在report中顯示

最終在不改動toml,不改動核心邏輯的情況下,增加了該功能,效果就是下方展示的 Dockerfile的内容

root@VM-4-5-ubuntu:/home/ubuntu/docker# cat Dockerfile 
FROM ubuntu:18.04

ENV PATH=${JAVA_HOME}/bin:${PATH} \
CS_PORT=9911 \
CS_PASSWORD=123456 \
CS_PUSH_TOKEN=111111dadsadsadsadsadsa 


RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list && apt-get clean && apt update \
&& apt install -y  redis-server  --fix-missing \
&& sed -i "s|bind 127.0.0.1 ::1|bind 127.0.0.1|" /etc/redis/redis.conf \
&& echo 'password=test123456' > config.ini


CMD bash

           

這裡不展示所有的結果,隻展示其中一行命中兩個正則規則的結果。為了營造這個條件,我修改了Veinmind-sensitive/rules.toml 中關于"Config File"的正則語句。(這裡隻是為了測試)

filepath = '''.*\/config\.ini$''' => filepath = ''.*config\.ini$'''

敏感資訊的内容是

/bin/sh -c sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list && apt-get clean && apt update && apt install -y redis-server --fix-missing && sed -i \"s|bind 127.0.0.1 ::1|bind 127.0.0.1|\" /etc/redis/redis.conf && echo 'password=test123456' > config.ini
           

理論上,這一條指令有password敏感字段和 config.ini 兩個敏感字眼,是會命中"Config File" 和"Password In Enviroment" 這兩個正則。

實作效果

技術交流|Dockerfile 中 RUN 後面的敏感資訊檢測
技術交流|Dockerfile 中 RUN 後面的敏感資訊檢測

寫在最後