Misc
数学天才
Challenge
森莫?要爆零了!那来签个到吧。
hint:试炼一和试练二两个一起看解压葵花宝典
Solution
数学天才.txt给出的提示如下:
小伙子,我看你骨骼清奇,必是旷世奇才,那就考验一下你的悟性吧!
试炼一:斜下对角线的数字,是打开葵花宝典的密钥。
试炼二:为师不想要死,为师喜欢$。
试炼三:你是第60位前来考核的人员,想想该怎么读懂葵花宝典呢?

题目给的图片是一个杀手数独(Killer Sudoku),要求实现:
- 标准数独的规则(行、列和3×3方块不能重复)
- Killer Sudoku特有的笼子(cage)约束
- 使用回溯算法寻找解决方案
python
# 初始化问题N = 9sudoku = [[0,0,0,0,0,3,0,8,0], [3,0,0,1,0,0,0,0,0], [6,0,0,0,0,0,3,0,0], [0,0,0,0,6,0,7,0,0], [0,0,0,9,0,0,0,0,4], [0,6,0,0,0,5,0,0,0], [0,0,8,0,0,0,4,0,9], [0,7,0,3,0,0,0,0,0], [0,0,4,0,9,0,0,0,0]] cages = [ (6,[(0,0),(0,1)]), (6,[(0,2),(0,3)]), (25,[(0,4),(0,5),(1,5),(2,5)]), (23,[(0,6),(0,7),(1,6),(1,7)]), (11,[(0,8),(1,8)]), (24,[(1,0),(2,0),(3,0),(4,0)]), (17,[(1,1),(2,1)]), (10,[(1,2),(1,3),(2,3)]), (12,[(1,4),(2,4)]), (14,[(2,6),(2,7),(3,6),(3,7)]), (9,[(2,8),(3,8)]), (14,[(2,2),(3,2)]), (6,[(3,1),(4,1)]), (16,[(3,3),(4,2),(4,3)]), (19,[(3,4),(3,5),(4,4),(5,3),(5,4)]), (19,[(4,5),(4,6),(5,5)]), (14,[(4,7),(5,7)]), (22,[(4,8),(5,8),(6,8),(7,8)]), (9,[(5,0),(6,0)]), (19,[(5,1),(5,2),(6,1),(6,2)]), (5,[(5,6),(6,6)]), (26,[(6,3),(7,3),(8,3),(8,4)]), (6,[(6,4),(7,4)]), (14,[(6,5),(7,5),(7,6)]), (9,[(6,7),(7,7)]), (10,[(7,0),(8,0)]), (19,[(7,1),(7,2),(8,1),(8,2)]), (12,[(8,5),(8,6)]), (9,[(8,7),(8,8)]),] # 创建cage_map,将每个单元格映射到它的笼子cage_map = {}for cage_sum, cells in cages: for cell in cells: cage_map[cell] = (cage_sum, cells) def print_sudoku(board): """打印数独""" for i in range(N): if i % 3 == 0 and i != 0: print("-" * 22) for j in range(N): if j % 3 == 0 and j != 0: print(" |", end="") print(f"{board[i][j]:2d}", end="") print() print() def is_valid(board, row, col, num): """检查在指定位置放置数字是否合法""" # 检查行 for x in range(N): if board[row][x] == num: return False # 检查列 for x in range(N): if board[x][col] == num: return False # 检查3x3方块 start_row, start_col = 3 * (row // 3), 3 * (col // 3) for i in range(3): for j in range(3): if board[start_row + i][start_col + j] == num: return False # 检查笼子约束 cage_sum, cage_cells = cage_map[(row, col)] current_sum = num # 计算当前笼子中已经填充的数字之和 for cell_row, cell_col in cage_cells: if board[cell_row][cell_col] != 0: current_sum += board[cell_row][cell_col] # 如果已填充的数字之和超过了笼子的和,则不合法 if current_sum > cage_sum: return False # 如果这是最后一个未填充的单元格,检查总和是否正好等于笼子的和 remaining_cells = sum(1 for r, c in cage_cells if board[r][c] == 0) if remaining_cells == 1 and current_sum != cage_sum: return False return True def find_smallest_empty_cage(board, cage_map): """找到具有最小可能值的空单元格(用于优化)""" for i in range(N): for j in range(N): if board[i][j] == 0: return (i, j) return None def solve_killer_sudoku(board, cage_map): """使用回溯法解决killer数独""" # 找到一个空位置 empty_pos = find_smallest_empty_cage(board, cage_map) if not empty_pos: return True # 没有空位置,问题已解决 row, col = empty_pos # 尝试填入1-9之间的数字 for num in range(1, N+1): if is_valid(board, row, col, num): # 如果当前位置有效,则尝试填入 board[row][col] = num # 递归尝试解决剩余部分 if solve_killer_sudoku(board, cage_map): return True # 如果当前数字导致后面无解,回溯 board[row][col] = 0 # 尝试了1-9都不行,返回False return False # 解决 Killer Sudokusolution = [row[:] for row in sudoku]if solve_killer_sudoku(solution, cage_map): print_sudoku(solution)else: print("无解")运行即可得到输出
text
2 4 1 | 5 7 3 | 9 8 6 3 9 7 | 1 8 6 | 2 4 5 6 8 5 | 2 4 9 | 3 1 7---------------------- 8 5 9 | 4 6 1 | 7 3 2 7 1 3 | 9 2 8 | 6 5 4 4 6 2 | 7 3 5 | 1 9 8---------------------- 5 3 8 | 6 1 2 | 4 7 9 9 7 6 | 3 5 4 | 8 2 1 1 2 4 | 8 9 7 | 5 6 3提取出主对角线上的数字295425423,根据试练二给出的提示用“
解压得到的葵花宝典.txt内容如下:
text
DJ?ELtbo`0+o8F0Eb2G9dPNRot47->Rot13解码得到flag:

flag
flag{R3@1_M@th_g3niu5!}small_challenge
Challenge
看了半天,没有收获?其实亦有收获。
Solution
解压得到

binwalk提取得到一个压缩包,里面包含压缩包flag.zip和下面这张图片

用StegSolver的Image Combiner将两张图XOR处理,得到下面这个DataMatrix条码

在线阅读Data Matrix条码扫码得到:
text
<E:8E?W^Z<=tEZ)=lP6n>;.Tg>q@+!/6=B)/6_%hLg*.rH<gLNbase85解码得到:
text
UV!W_X_YZ,U,Y∈[0,9], V,W,X,Z∈[A,z]这就是压缩包密码的范围
先用John the Ripper提出哈希
text
zip2john flag.zip > hash.txttext
flag.zip/flag.txt:$pkzip2$1*1*2*0*26*1c*405453ef*0*26*8*26*4054*5c53*c8ca4c0435c8b2f6eeb7fe58830b8956e16b669b8c970b8086fea94f45902d111e440e655857*$/pkzip2$:flag.txt:flag.zip::flag.zip前后删一下把它修改成hashcat能识别的格式
text
$pkzip2$1*1*2*0*26*1c*405453ef*0*26*8*26*4054*5c53*c8ca4c0435c8b2f6eeb7fe58830b8956e16b669b8c970b8086fea94f45902d111e440e655857然后用hashcat进行掩码攻击
text
hashcat -a 3 -m 17200 --custom-charset1=?d --custom-charset2=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "hash.txt" ?1?2!?2_?2_?1?2不到1分钟就解出来了
text
$pkzip2$1*1*2*0*26*1c*405453ef*0*26*8*26*4054*5c53*c8ca4c0435c8b2f6eeb7fe58830b8956e16b669b8c970b8086fea94f45902d111e440e655857*$/pkzip2$:9h!Y_a_8D因此解压密码就是9h!Y_a_8D,解压得到flag
flag
flag{It3_s0_3@syIlIlIIlIllI}