notepad++怎么换行命令_命令注入新玩法:巧借环境攻击目标
在一次漏洞賞金活動中,挖掘到一個(gè)不標(biāo)準(zhǔn)的命令注入漏洞,我無法用命令分隔符、命令替換符注入新命令讓系統(tǒng)執(zhí)行,所以,從”型態(tài)”上講,它不算是命令注入漏洞;但我又可以借助目標(biāo)環(huán)境讓載荷到達(dá)系統(tǒng)命令行,實(shí)現(xiàn)讀寫文件、執(zhí)行新命令,所以,”神態(tài)”來看,它又像是命令注入。這類借助環(huán)境間接注入命令的利用手法,很少在常規(guī)討論命令注入的文章中看到,有必要落筆成文,與你分享。
0x00 酷趣 wargame
由于受賞金廠商保密協(xié)議所限,我無法公開原始漏洞詳情,但我更清楚 “talk is cheap, show me the code”,耗時(shí)費(fèi)神,找到一個(gè) wargame,相較賞金漏洞,不但體現(xiàn)了相同精髓,這個(gè) wargame 還多了些限制條件,所以,讓它變得更加有趣、更有挑戰(zhàn)。
我把 wargame 源碼寫入
?CMDi_lab/escaping_quotation/index.php,核心如下:
快速過下源碼。首先,用 GET 方法獲取 f1、f2 兩個(gè)參數(shù);然后,用相同的正則過濾 f1、f2,包括過濾引號防止利用環(huán)境寫 webshell,過濾常見命令分隔符(;)、命令替換符($())防止注入新命令,過濾常見命令(ls、cat)禁止基礎(chǔ)操作;接著,用引號再建一道防御工事,讓所有輸入均在引號內(nèi),讓命令行元字符失效;最后,以 f1、f2 為命令參數(shù)執(zhí)行系統(tǒng)命令 file。
怎么樣!看上去是很完善的防御體系。先正常訪問試試:
服務(wù)端執(zhí)行 file 命令,正確識別出目錄和文件的類型。嘗試提交命令分隔符(;)和命令替換符(``):
由于服務(wù)端正則表達(dá)式匹配上 ; 和 ``,導(dǎo)致提交的文件名被置為空,所以,file 提示無法找到相關(guān)文件。
經(jīng)驗(yàn)主義,我將從三個(gè)層面尋找突破口:攻擊正則、攻擊引號、攻擊命令行。那么,我就準(zhǔn)備開動了,各位。
0x01 成敗正則
在命令注入場景下審查正則表達(dá)式,我習(xí)慣關(guān)注四個(gè)方面:是否使用多行模式修飾符(/foo/m)、是否遺漏匹配對象末尾的換行符(/^\d+$/)、是否允許空白字符(\s)、是否誤寫反斜杠匹配模式(/\/)。
使用多行模式修飾符。把多行模式用于匹配希望允許的字符時(shí),就會存在邏輯問題。比如,如下代碼:
原本希望只允許 xx.xx.xx.xx 格式的 IP 地址,由于使用多行模式,只要輸入中某行滿足條件即可,那么,我可以用換行符輸入多行,第一行滿足要求 127.0.0.1、第二行任意內(nèi)容,這樣輕松繞過正則限制:
本 wargame 未使用多行模式,所以不存在這個(gè)問題。
遺漏匹配對象末尾的換行符。某些模式在匹配時(shí)會忽略字符串末的換行符,而換行符自身又是一個(gè)有效的目錄分隔符,將導(dǎo)致注入新命令。如下代碼:
原意是過濾掉輸入中非字母、數(shù)字外的其他所有字符,輸入換行符試試:
果然被過濾了。但,若把換行符放至字符串末尾,正則反而無法匹配上:
這可有趣了,又能愉快地注入新命令了:
本 wargame 未能成功過濾掉換行符,但不是因?yàn)樯厦娴脑颉?/p>
允許空白字符。空白字符包括空格、換行符、水平制表符、垂直制表符等四個(gè),命令注入的好朋友換行符也在其中。代碼:
本意只允許字母、數(shù)字、空格等字符,但遺漏了換行符,導(dǎo)致命令注入漏洞:
本 wargame 未能成功過濾掉換行符,但不是因?yàn)樯厦娴脑颉?/p>
誤寫反斜杠匹配模式。正則表達(dá)式自身是個(gè)字符串,并非直接傳遞給正則引擎,而是先由語言對字符串進(jìn)行處理后再傳遞給正則引擎。我希望匹配上反斜杠(\),逆向思考下這個(gè)過程,由于反斜杠在正則引擎是個(gè)特殊字符,所以 \ 才能讓正則引擎正確識別到反斜杠 \;正則引擎之前,\ 經(jīng)過語言的的字符串處理,由于反斜杠在字符串中也是特殊字符,所以,一個(gè) \ 就得用 \ 表示、兩個(gè) \ 就得用 \\ 表示。那么,但凡用正則表達(dá)式匹配斜杠,必須得用 \\。這是不具備原生字符串特性(r)的腳本語言的通病,是有一點(diǎn)繞。比如:
訪問看看:
記得 wargame 也過濾了反斜杠,回過頭看看,哇喔,的確誤用了:
OK,在正則部分,由于誤寫匹配模式,我找到了漏網(wǎng)之魚,反斜杠。如何利用?不知道,走一步看一步。
0x02 引號逃逸
接著我來琢磨下 25、26 行。這兩行目的很清晰,用引號包裹輸入字符串,預(yù)防可能因正則過濾不嚴(yán)傳遞一些個(gè)特殊字符到命令行環(huán)境,思路是對的,但效果就差強(qiáng)人意了。
載荷一旦進(jìn)入引號內(nèi),都將退化成普通字符串,好無殺傷力,唯一例外,命令替換符(`` 或 $()),遺憾的是,命令替換符被正則嚴(yán)防死守,無法到達(dá) 25、26 行。所以,下意識地想到,引號逃逸。
引號逃逸,目的是讓輸入跳脫至引號外,恢復(fù)特殊字符的身份,而不再被引號所束縛,僅僅是個(gè)普通字符。我常用兩種手法,一是閉合、二是轉(zhuǎn)義。
閉合手法逃逸引號。在輸入中添加一個(gè)引號,讓其與左引號結(jié)對,自然閉合,接著輸入中就能出現(xiàn)惡意字符,最后輸入中再添加一個(gè)引號,與右引號結(jié)對,或者,輸入注釋符以忽略右引號。比如:
我的所有輸入都只能留在引號內(nèi),導(dǎo)致命令分隔符無法被命令行正確識別:
我在輸入中增加兩個(gè)引號(②、③),這樣剛好與代碼中的引號閉合(① 和 ②、③ 和 ④),所以,我的其他輸入字符(;id;)就能出現(xiàn)在引號之外,成功逃逸引號:
轉(zhuǎn)義手法逃逸引號。引號自身也是個(gè)特殊字符,如果有辦法讓它變成普通字符,那么輸入的其他特殊字符就能讓命令行正確識別。反斜杠可以辦到!如下代碼:
含有惡意字符的輸入被限定在引號內(nèi):
假設(shè)服務(wù)端生成的命令模型為 file “foo” “;date”,這時(shí),我利用反斜杠將 ② 號引號轉(zhuǎn)義為普通字符,那么 ① 和 ③ 號引號將自然結(jié)合,接著利用注釋符將 ④ 號引號注釋掉,;date 對于命令行直接可見,邏輯上我能用 file “foo\” “;id #bar” 注入任意命令,再次逃逸到引號外:
注,注釋符 # 需要 URL 編碼為 %23。
好了,還記得前面我找到正則漏洞無法過濾反斜杠么,wargame 中的引號已經(jīng)無法束縛我,雖然當(dāng)下無法直接利用,但至少又讓我向前邁出一步。
0x03 選項(xiàng)注入
繼續(xù)看 29、30 兩行的命令執(zhí)行代碼。顯然這與命令注入漏洞多少有些關(guān)系。命令注入常見三種手法:利用命令分隔符注入命令、利用命令替換符注入命令、利用命令選項(xiàng)注入命令。
命令分隔符注入命令。命令分隔符包括換行符(\n)、分號(;)、邏輯與(&&、&)、邏輯或(||、|),若在 win 批處理腳本中還能用 %1A。比如:
命令替換符注入命令。shell 優(yōu)先執(zhí)行命令替換符內(nèi)的命令,目的是便于運(yùn)維人員將前個(gè)命令的輸出作為后個(gè)命令的輸入。命令替換符包括 $(…)、反引號?...。比如:
命令選項(xiàng)注入命令。命令選項(xiàng)(option)和命令參數(shù)(argument)是兩個(gè)概念,國內(nèi)外很多文獻(xiàn)都將他倆混淆。比如:
其中,-d 是命令選項(xiàng)、/tmp/ 是命令參數(shù)。很多時(shí)候,藍(lán)隊(duì)過濾掉所有命令分隔符、命令替換符,雖然我無法直接注入命令,但我可以注入其他命令選項(xiàng),這就給我很大想像空間,某些選項(xiàng)可以讀取文件、有些又能寫入文件、甚至執(zhí)行其他命令。比如,有個(gè)頁面,可以將 web 目錄打包為你指定的歸檔文件,輸入為歸檔文件名 $archive 參數(shù),服務(wù)端過濾所有命令注入相關(guān)字符,調(diào)用 system(“tar -cf” . $archive . “*”) 執(zhí)行命令:
但我通過注入 tar 命令的 —checkpoint、—checkpoint-action=exec 兩個(gè)選項(xiàng),成功執(zhí)行命令 id:
wargame 中執(zhí)行的是 file 命令,查看下它有哪些用得上的選項(xiàng),比如,是否有選項(xiàng)可以讀文件,man 中搜索 read,找到 -f 選項(xiàng):
仔細(xì)看下,該參數(shù)并不能讀取顯示文件內(nèi)容,只是從該文件中獲取文件列表,沒意思(。?_?。)。等等,報(bào)錯信息中有啥提示:
哇噢,歷害啦,通過注入命令選項(xiàng) -f,讓我可以讀取 wargame 的文件內(nèi)容。
0x04 全面瓦解
管它金城湯池還是銅墻鐵壁,一顆松滑螺釘,它將全面瓦解。
將多個(gè)獨(dú)立漏洞組合成漏洞鏈,完成目標(biāo)攻擊,絕對是我的 G 點(diǎn)。回顧前面的成果,由于誤寫正則表達(dá)式,導(dǎo)致無法過濾反斜杠;通過反斜杠,可以逃逸引號;通過引號逃逸,創(chuàng)造出命令選項(xiàng)注入的條件;通過注入 -f 選項(xiàng),實(shí)現(xiàn) flag 文件讀取。過濾反斜杠的正則,就是那顆松滑的螺釘。
現(xiàn)在,攻擊目標(biāo)前,還剩一個(gè)問題,我并不清楚 flag 文件路徑及文件名。首先想到的是暴破。土!的確很土氣,用常見的 flag、FLAG、f14g 等等常見 flag 名暴了一遍,毫無收獲。換個(gè)手法,通配符模式匹配。這下洋氣了吧。
通配符模式匹配(globbing patterns),也叫路徑名擴(kuò)展(pathname expansion),簡單來說,在表示文件名/目錄名或路徑時(shí),你可以用 ? 代表任一可見字符、用 * 代表零或多個(gè)可見字符、用 [a-z] 代表字符范圍,唯一例外,以 . 開頭的文件或目錄、以 / 分隔的路徑必須顯式寫明,否則無法被模式匹配。
比如,我并不還知道 /tmp/ 目錄下有個(gè)名為 FindMe 的文件,但,借助通配符多次測試,不但刺探出該文件的存在,還成功查看到文件內(nèi)容:
好,現(xiàn)在一切就緒,攻擊 CMDi_lab/escaping_quotation。有了前面的分析,我構(gòu)造了載荷 f1=foo\&f2=-f ? bar #,將 file “foo” “bar” 轉(zhuǎn)換為 file “foo\” “-f ? bar #”,猜解文件名只有一個(gè)字符的文件:
顯然,沒找到這樣的文件,相同思路,借助 burp 自動查找文件名長度在 [1, 16] 的所有文件:
跑完還是沒有找到任何文件。這就奇怪了,前面說過,通配符無法匹配 .,莫非是隱藏文件,調(diào)整下載荷, f1=foo\&f2=-f .? bar #,再次暴破:
找到名為 .f1a9?的目錄,繼續(xù)調(diào)整載荷 f1=foo\&f2=-f .f1a9/.? bar #,暴破:
找到名為 .f1a9_/.flag_15_here.txt 的文件,帶上準(zhǔn)確路徑訪問:
WTF!不應(yīng)該啊,邏輯上說不通。別急,捋一捋,莫非載荷中新增部分有被過濾的字符?回到前面的正則源碼處,的確過濾了 flag 關(guān)鍵字,我用通配符替換,載荷變成 f1=foo\&f2=-f .f1a9/.fl?g_15_here.txt bar #,另外,命令選項(xiàng) -f 前應(yīng)該得加個(gè)空格,最終載荷為 f1=foo\&f2= -f .f1a9/.fl?g_15_here.txt bar #,來一發(fā):
多么愉悅的攻擊體驗(yàn)!
0x05 非預(yù)期解法
絲滑般的思緒,真實(shí)而自然!思緒自然?!正則未正確過濾反斜杠、利用反斜杠逃逸引號、通配符模式猜解路徑、注入命令選項(xiàng)讀取文件,做作、別扭!以上是我為了湊字?jǐn)?shù)、增篇幅寫的,真實(shí)的攻擊手法并非如此。
仔細(xì)審計(jì)正則過濾的代碼。用 \ 而非 \\ 表述反斜杠,不僅無法正確過濾反斜杠,還會引發(fā)連鎖反應(yīng)。你看,緊隨 \ 其后的是 |\n:
前面提過,\ 結(jié)果字符串轉(zhuǎn)義后到達(dá)正則引擎變成 \,它與 |\n 結(jié)合變成 |\n,正則引擎誤解成匹配豎線與換行符的組合。當(dāng)我輸入豎線與換行符的組合,確認(rèn)被過濾:
換言之,服務(wù)端只過濾 |\n 而放行 \n。有換行符,我可以直接注入新命令,比如,執(zhí)行命令 id:
既然能注入命令了,查看 flag 易如反掌!命令 grep -r . . 可以查看當(dāng)前目錄下所有文件內(nèi)容,服務(wù)端過濾了 grep,我用內(nèi)部空變量輕松繞過(g$1rep -r . .),或者,無效轉(zhuǎn)義繞過(g\rep -r . .),或者,通配符繞過(/bin/gr?p -r . . 或 /bin/gr[d-f]p -r . .),我有 1024 種方式吊打目標(biāo)。
OK,清晰,爭取一次搞定,構(gòu)造載荷 ?f1=foo\&f2=%0a/bin/gr[d-f]p+-r+.+.+%23,頁面顯示:
0x06 故事尾聲
最后聊聊你關(guān)心的賞金漏洞。大致業(yè)務(wù)場景,服務(wù)端執(zhí)行打包命令壓縮幾個(gè)固定目錄,允許用戶輸入歸檔文件名,多次刺探確認(rèn)使用的 zip 命令,類似:
其中,歸檔文件名 archive.tar 可控。服務(wù)端正則過濾所有命令分隔符、命令替換符、其他元字符,同時(shí),禁止出口流量,顯然無法直接注入命令。
一番嘗試,發(fā)現(xiàn)允許橫線(-),這就告訴我可以注入命令選項(xiàng)。我開始分析環(huán)境 zip 自身有哪些選項(xiàng)可以為我所用。先查找關(guān)鍵字 execute,一無所獲;接著搜索關(guān)鍵字 command,找選項(xiàng) —unzip-command(簡寫 -TT) 和 —test(簡寫 -T),允許用戶指定第三方程序來校驗(yàn)歸檔文件的完整性:
換言之,選項(xiàng) -T 和 —unzip-command 可以注入新命令 id:
成功拿到賞金。
命令注入攻擊,除了常規(guī)的命令分隔符、命令替換符之外,利用環(huán)境自身也能實(shí)現(xiàn)。
注一,wargame 的原型來自 Kaibro 所寫的 wargame,見?http://final.kaibro.tw:10002/;
注二,escaping_quotation 源碼,以及更多命令注入相關(guān) wargame 見?https://github.com/yangyangwithgnu/CMDi_lab
*本文作者:yangyangwithgnu,本文屬 FreeBuf 原創(chuàng)獎勵計(jì)劃,未經(jīng)許可禁止轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的notepad++怎么换行命令_命令注入新玩法:巧借环境攻击目标的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: capsule 安装_CAPSULE S
- 下一篇: 拾取物品怎么实现_Dynamo如何实现图