escape
类似于D3CTFxAntCTF的Escape Plan,网上找到payload,但是多过滤了list,然后用迷你上标和下标去绕过过滤即可。用dnslog进行外带即可。
babycms
主要是这一段存在文件上传漏洞
if (!empty($_FILES['ufile'])) {
if (!in_array($_FILES['ufile']['type'], ['image/jpeg', 'image/png', 'image/gif'])) {
echo "nnnnnnnnnnnnxxxxxxnnnn";
} else {
$file = empty($_POST['filename']) ? $_FILES['ufile']['name'] : $_POST['filename'];
echo $file;
if (!is_array($file)) {
$file = explode('.', strtolower($file));
}
$ext = end($file);
if (!in_array($ext, ['jpg', 'png', 'gif'])) {
die('???????what??');
}
$new_file_name = $random_digit . ".jpg";
$tmp_name = $_FILES["ufile"]["tmp_name"];
$uploads_dir = 'uploads/services';
$filename = reset($file) . '.' . $file[count($file) - 1];
$tmp_name = $_FILES["ufile"]["tmp_name"];
while (!preg_match('/[a-zA-Z]$/', $filename)) {
$filename = substr($filename, 0, -1);
}
echo $filename;
// basename() may prevent filesystem traversal attacks;
// further validation/sanitation of the filename may be appropriate
move_uploaded_file($tmp_name, "$uploads_dir/$filename");
// move_uploaded_file($tmp_name, "$uploads_dir/$new_file_name");
}
}
而导致文件上传漏洞的原因是php的array,先看下面这一段代码
<?php
$file[1]='php';
$file[0]='jpg';
var_dump($file);
?>
输出结果如下:
array(2) {
[1] =>
string(3) "php"
[0] =>
string(3) "jpg"
}
我们可以看到1在0的前面,而不是按照从小到大的,array内部元素的顺序是根据输入的先后顺序决定的。其实php的array的key不像c语言一样只能是数字,这也就意味着php的array其实是一种key-value的map,所以没有根据key的大小进行排序,毕竟key可以是数字也可以是字符串。但其实数字会被当成字符串进行处理
<?php
$file[1]='php';
$file['1']='jpg';
var_dump($file);
?>
输出结果如下:
array(1) {
[1] =>
string(3) "jpg"
}
1和'1'在array看来都是一样的key,所以'php'就覆盖了。
另外php的array的计数不是根据key的最大值来的,而是有多少个key-value对。
<?php
$file[1]='php';
$file[100]='jpg';
?>
上面的输出结果不是101而是2,其实也正常,毕竟php的array其实是map,当然不是说key有多大,map有多大
所以这里有两种方法来绕过白名单
方法一:
$file[1]='php';
$file[0]='jpg';
这样end指向的后缀名就是jpg
但是我们filename的后缀名$file[count($file) - 1]则是$file[1],即php
方法二:
$file[0]='1.php';
$file[2]='jpg';
end指向的还是jpg,$file[count($file) - 1]是$file[1],但是$file[1]不存在,返回NULL,所以文件名变成1.php.,然后后面的while循环会把.去除,就变成了1.php
上传了木马,但是还要提权
这里是用sudo提权,首先sudo -l发现(root) NOPASSWD: /usr/bin/apt-get
然后参考这篇文章进行提权:https://blog.csdn.net/Bossfrank/article/details/131941306
babyjs
有三个api接口,其中/connect和/hello:name都限制为只有本地ip才可访问,在/proxy,我们可以通过url参数让服务器替我们向指定的网站发起get请求,那么/connect和/hello:name即可在/proxy进行ssrf来访问,毕竟发起请求的就是服务器本身,所以肯定是本地ip,然后在app.js下我们可以知道服务是运行在3000端口,并且还在6379端口有redis服务,密码已经给了。在/connect下我们也可以进行ssrf,再次访问本地的6379端口,之所以在/connect访问6379是因为/proxy路径只有url一个参数,而/connect还有headers,我们可以控制我们访问6379端口时的请求头,然后才可以进行crlf。