Writeup 4 CSS CTF Semester 2 2026 - Lamp Drill Writeup 4 CSS CTF Semester 2 2026 - Lamp Drill题目信息题目名称Lamp Drill分值15难度Beginner类型Hardware / Reverse Engineering题目描述Warm-up. No spaces.Flag Format: CSSCTF{…}These artists may help (Cost: 5 points)OffonoffLogical (Cost: 15 points)A black filled lamp is 1. An empty circle is 0.附件lampDrill.svg解题思路1. 分析提示题目给了两个提示提示 15 分OffonoffOffonoff 是一个韩国音乐组合但在这里它是个双关Off 关 逻辑 0On 开 逻辑 1“Off on off” 0 1 0这暗示我们要关注逻辑电平0 和 1。提示 215 分LogicalA black filled lamp is 1. An empty circle is 0.这直接告诉我们编码方式黑色实心圆 1白色空心圆 02. 分析 SVG 电路图打开lampDrill.svg可以看到一张逻辑电路图顶部逻辑门真值表输入 A输入 B输出1 (黑)1 (黑)1 (黑)1 (黑)0 (白)0 (白)0 (白)1 (黑)0 (白)0 (白)0 (白)0 (白)这完全符合AND 门的真值表只有两个输入都为 1 时输出才为 1。下方3 行电路每行有8 个盒子每个盒子里有2 个圆输入盒子之间用箭头连接。每个盒子是一个独立的AND 门。3. 提取数据用脚本从 SVG 中提取所有圆形节点的坐标和填充色importrefromcollectionsimportdefaultdictwithopen(lampDrill.svg,r)asf:contentf.read()circles[]patternrpath dM ([\d.]) ([\d.])\s*C[^]*\s*clip-path[^]*\s*stylefill: (#[0-9a-f]); stroke: #[0-9a-f]; stroke-width: 1.6forminre.finditer(pattern,content):xfloat(m.group(1))yfloat(m.group(2))fillm.group(3)val1iffill#1c1915else0circles.append((x,y,val))rowsdefaultdict(list)forx,y,valincircles:rows[round(y)].append((x,val))forrow_keyinsorted(rows.keys()):ifrow_key200:continuerowsorted(rows[row_key],keylambdat:t[0])values[vforx,vinrow]print(fy{row_key}:{values})输出y281: [1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1] y385: [0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1] y489: [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1]4. 计算 AND 输出每行 16 个输入每 2 个一组送入 AND 门得到 8 位输出。第 1 行y281输入对AND 输出1, 001, 111, 110, 100, 001, 001, 111, 11输出0 1 1 0 0 0 1 1011000110x63 ‘c’第 2 行y385输入对AND 输出0, 101, 111, 111, 111, 000, 101, 111, 11输出0 1 1 1 0 0 1 1011100110x73 ‘s’第 3 行y489输入对AND 输出0, 001, 111, 111, 111, 000, 101, 111, 11输出0 1 1 1 0 0 1 1011100110x73 ‘s’5. 拼接结果三行输出对应的 ASCII 字符c s s css6. 最终 FlagCSSCTF{css}解题脚本importrefromcollectionsimportdefaultdictwithopen(lampDrill.svg,r)asf:contentf.read()circles[]patternrpath dM ([\d.]) ([\d.])\s*C[^]*\s*clip-path[^]*\s*stylefill: (#[0-9a-f]); stroke: #[0-9a-f]; stroke-width: 1.6forminre.finditer(pattern,content):xfloat(m.group(1))yfloat(m.group(2))fillm.group(3)val1iffill#1c1915else0circles.append((x,y,val))rowsdefaultdict(list)forx,y,valincircles:rows[round(y)].append((x,val))resultforrow_keyinsorted(rows.keys()):ifrow_key200:continuerowsorted(rows[row_key],keylambdat:t[0])values[vforx,vinrow]outputs[]foriinrange(0,len(values),2):ifi1len(values):outputs.append(values[i]values[i1])iflen(outputs)8:byteint(.join(map(str,outputs)),2)resultchr(byte)print(fy{row_key}:{outputs}-{chr(byte)})print(fFlag: CSSCTF{{{result}}})输出C:\Users\Administrator\AppData\Local\Programs\Python\Python314\python.exe exp.py y281: [0, 1, 1, 0, 0, 0, 1, 1] - c y385: [0, 1, 1, 1, 0, 0, 1, 1] - s y489: [0, 1, 1, 1, 0, 0, 1, 1] - s Flag: CSSCTF{css} 进程已结束退出代码为 0关键点总结编码黑圆 1白圆 0提示 2逻辑门顶部示例确认是AND 门只有 1,1 输出 1数据提取从 SVG 中按 y 坐标分组提取圆形节点计算每行 16 个输入 → 8 个 AND 输出 → 1 字节 ASCII结果3 行得到c、s、s→css最终 FlagCSSCTF{css}Rambo2026年国庆节