在p牛博客最近更新的文章,傳送門,感覺很有意思,自己在自己本地測試了一下
0x01 正則表達式中的 ‘$’
apache這次解析漏洞的根本原因就是這個 $,正則表達式中,我們都知道$用來匹配字符串結尾位置,我們來看看菜鳥教程中對正則表達符$的解釋:
匹配輸入字符串的結尾位置。如果設置了 RegExp 對象的 Multiline 屬性,則 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,請使用 \$。
那么就明白了,在設置了 RegExp 對象的 Multiline 屬性的條件下,$還會匹配到字符串結尾的換行符
0x02 Linux環境
這里本地是debian系的kali linux,apache配置文件路徑在/etc/apache2/下,apache2.conf是apache核心配置文件,由於我本地php作為apache的mod方式運行的,所以需要在mods-enabled目錄下找到關於apache-php模塊的配置:
可以看見php7.0.conf是mods-available/php7.0.conf的軟鏈接,配置如下:
<FilesMatch ".+\.ph(p[3457]?|t|tml)$">
SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch ".+\.phps$">
SetHandler application/x-httpd-php-source
# Deny access to raw php sources by default
# To re-enable it's recommended to enable access to the files
# only in specific virtual host or directory
Require all denied
</FilesMatch>
# Deny access to files without filename (e.g. '.php')
<FilesMatch "^\.ph(p[3457]?|t|tml|ps)$">
Require all denied
</FilesMatch>
# Running PHP scripts in user directories is disabled by default
#
# To re-enable PHP in user directories comment the following lines
# (from <IfModule ...> to </IfModule>.) Do NOT set it to On as it
# prevents .htaccess files from disabling it.
<IfModule mod_userdir.c>
<Directory /home/*/public_html>
php_admin_flag engine Off
</Directory>
</IfModule>
第一行就告訴了我們apache會將哪些后綴的文件當做php解析:
<FilesMatch ".+\.ph(p[3457]?|t|tml)$">
以如下方式結尾的文件會被apache當做php解析:
php php3 php4 php5 php7 pht phtml
如果我們再結合我們上面提到的關於$的使用,很容易想到,如果后綴名是上面這些后綴名以換行符結尾,那么也是可以解析的,本地構造文件:
文件構造好了,從瀏覽器打開試試看看能不能解析:
可以看見是能解析的,那么在文件上傳黑名單就可以通過這種思路來繞過了。
0x02 Windows環境
關於windows環境,p牛博客下面有一些人說測試失敗,我也進行了測試,虛擬機環境 win7+phpstudy : Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.4.45
配置文件(${Apache_path}/conf/extra/httpd-php.conf)如下:
LoadFile "C:/Users/admin/Desktop/phpstudy/php/php-5.4.45/php5ts.dll"
LoadModule php5_module "C:/Users/admin/Desktop/phpstudy/php/php-5.4.45/php5apache2_4.dll"
<IfModule php5_module>
PHPIniDir "C:/Users/admin/Desktop/phpstudy/php/php-5.4.45/"
</IfModule>
LoadFile "C:/Users/admin/Desktop/phpstudy/php/php-5.4.45/libssh2.dll"
<FilesMatch "\.php$">
SetHandler application/x-httpd-php
</FilesMatch>
用p牛的代碼測試:
<html>
<body>
<form action="test.php" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="text" name="name" />
<input type="submit" value="上傳文件" />
</form>
</body>
</html>
<?php
if(isset($_FILES['file'])) {
$name = basename($_POST['name']);
$ext = pathinfo($name,PATHINFO_EXTENSION);
if(in_array($ext, ['php', 'php3', 'php4', 'php5', 'phtml', 'pht'])) {
exit('bad file');
}
move_uploaded_file($_FILES['file']['tmp_name'], './' . $name);
}
?>
抓包修改文件名,上傳:
可以看見,這里出現了兩個warning,其實並非測試不成功,可以看見其實是繞過了我們代碼里的黑名單的,已經執行到了move_uploaded_file了,說明程序並沒有因為沒有繞過黑名單而exit,但是因為涉及到文件讀寫,而windows操作系統不允許后綴以換行符結尾的文件命名方式,所以這里會文件會創建失敗,就出現了這兩個warning了





