在CTF比赛中,PHP、JavaScript、python 三类语言最为常见,其中PHP占据了80%以上。因此部分CTF题中,考察了 PHP语言特性的一些内容,本文中针对PHP语言特性的 CTF 考点进行讲解和总计。
- 弱类型
PHP语言中,有两个比较是否相等的符号,分别是 “==”和“===”。其中,“==”在判断两个值是否相等前,将自动将两个变量类型转化为同一数据类型,然后进行比较。“===”先比较两个变量的数据类型,如果数据类型不一致,将返回 false。
例如,看一个例子,
if($input == 1){
// 敏感操作
}
在上面的代码中,如果输入的变量 input 如果为 1sss ,则输入内容满足条件,执行敏感操作。
看一道例题,
if($_GET['x']!=$_GET['y'])&&md5($_GET['x'])==md5($_GET['y'])){
echo $flag
}
通过查看发现,上面例题中,要求输入的 x,y 不相等,但是他们的 md5 值相等(注意判断相等符号!)。
在PHP语言“==”做比较时,若字符以0e开头,按科学计数法来识别,先将字符转化为数字0。因此,我们只需要找到两个 字符串,只要他们的MD5值 是以 0e开头便可。
字符串 MD5值
QNKCDZO => 0e830400451993494058024219903391
s878926199a => 0e545993274517709034328855841020
s155964671a => 0e342768416822451524974117254469
让字符 x 和 y 等于上面三个当中的任意两个字符串时,就可以输出flag。
码字收集资料不易,大家不要光顾着收藏哦,记得点赞!
码字收集资料不易,大家不要光顾着收藏哦,记得点赞!
码字收集资料不易,大家不要光顾着收藏哦,记得点赞
- 反序列化漏洞
序列化是PHP语言提供的一种将任意数据类型转换成string类型的机制。反序列化是指 从string类型的变量中恢复原来的数据类型。 PHP提供的 serialize 和 unserialize函数分别实现序列化和反序列化功能。
反序列化漏洞是 由反序列化函数 unserialize 的输入参数被控制造成的。通常,unserialize函数参数不太容易被控制,需要借助 PHP语言的魔术函魔术方法来实现。
__construct(), _destruct(), call(), callStatic(), get(), set(), isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo() 等方法在PHP中被称之为魔术方法。
魔术方法使用举一个例子说明,
<?php
class test{
public $name = 'Xiguatou';
function __construct(){
echo "__construct()";
echo "<br><br>";
}
function __destruct(){
echo "__destruct()";
echo "<br><br>";
}
function __wakeup(){
echo "__wakeup()";
echo "<br><br>";
}
function __toString(){
return "__toString()"."<br><br>";
}
function __sleep(){
echo "__sleep()";
echo "<br><br>";
return array("name");
}
}
$test1 = new test();
$test2 = serialize($test1);
$test3 = unserialize($test2);
print($test3);
?>
上面PHP代码运行后,可以输出以下内容。
__construct()
__sleep()
__wakeup()
__toString()
__destruct()
__destruct()
可以看到,魔术方法特定时刻自动调用,无需干预。
如果服务器端代码中,在某一类的魔术方法中出现了我们可以利用的危险函数,我们在输入的反序列化中对其对象属性的操控来实现对这些函数的操控,从而达到攻击的目的。
说的有点绕,看个例题吧。
<?php
class safeclasee
{
private $test;
public $K0rz3n = "i am safeclasee";
function __construct()
{
$this->test = new L();
}
function __destruct()
{
$this->test->action();
}
}
class xxx
{
function action()
{
echo "i am in xxx";
}
}
class Evil
{
var $test2;
function action()
{
eval($this->test2);
}
}
unserialize($_GET['test']);
?>
今儿给大家留个悬念,这道题的答案不简单。大家评论一下,我更新讲解内容。
别跑!点个赞同撒,还会更新的!
下一篇将介绍 PHP的 截断、伪协议、变量覆盖。 记得收藏哈。
- 参考文献
- 关于魔术方法可以查看 PHP 官方文档,链接:魔术方法官方说明