sudoku
拿到程序之后 发现是一个顶着python图标的exe程序
capoo@DESKTOP-4JQA10R:/mnt/c/Users/15589/Desktop$ strings sudoku.exe | grep -i pyz | head
Installing PYZ: could not get sys.path object!
Failed to append PYZ entry to sys.path!
发现里面封装了pyz,直接用pyinstxtractor.py反编译
python pyinstxtractor.py sudoku.exe
反编译之后发现一个sudoku.pyc文件初步怀疑是真正的源码,直接交给网站逆向
得到下面的代码
# uncompyle6 version 3.9.2
# Python bytecode version base 3.8.0 (3413)
# Decompiled from: Python 3.6.12 (default, Feb 9 2021, 09:19:15)
# [GCC 8.3.0]
# Embedded file name: sudoku.py
import numpy as np
def check(lst):
check = [i for i in range(1, 17)]
return sorted(lst) == check
def check_line(input_array):
for i in range(16):
if not check(input_array[i]):
return return False
return True
def check_boxes(board):
for i in range(0, 16, 4):
for j in range(0, 16, 4):
nums = board[i][j[:j + 4]] + board[i + 1][j[:j + 4]] + board[i + 2][j[:j + 4]] + board[i + 3][j[:j + 4]]
not check(nums) return return False
else:
return True
def check_column(input_array):
array = np.transpose(input_array)
for i in range(16):
if not check(array[i]):
return return False
return True
def check_sudoku(input_array):
return check_line(input_array) and check_column(input_array) and check_boxes(input_array)
def fill(m, input_value):
k = 0
for i in range(16):
for j in range(16):
if m[i][j] == 0:
m[i][j] = int(input_value[k], 16) + 1
k = k + 1
else:
return True
sudoku = [
[
4, 6, 14, 1, 0, 16, 12, 5, 9, 8, 0, 2, 15, 3, 10, 0],
[
9, 8, 3, 12, 15, 4, 7, 10, 0, 13, 16, 6, 11, 14, 1, 2],
[
5, 15, 7, 2, 13, 1, 6, 14, 3, 0, 10, 12, 8, 9, 0, 4],
[
10, 11, 13, 16, 8, 3, 9, 2, 1, 15, 0, 4, 6, 12, 5, 7],
[
14, 10, 4, 3, 6, 5, 15, 16, 8, 0, 13, 7, 1, 2, 9, 11],
[
15, 13, 16, 11, 9, 2, 10, 8, 6, 14, 3, 1, 4, 7, 0, 5],
[
7, 9, 1, 8, 0, 14, 4, 3, 2, 5, 11, 10, 16, 13, 15, 6],
[
12, 2, 6, 5, 1, 0, 13, 7, 15, 9, 4, 0, 14, 8, 3, 10],
[
3, 14, 2, 9, 5, 0, 16, 13, 7, 0, 1, 15, 12, 4, 11, 8],
[
8, 1, 5, 15, 4, 6, 11, 9, 12, 3, 2, 14, 13, 10, 7, 0],
[
16, 12, 0, 7, 14, 8, 2, 15, 13, 4, 9, 11, 3, 5, 6, 1],
[
6, 4, 11, 13, 7, 12, 3, 0, 10, 16, 5, 8, 9, 15, 2, 0],
[
13, 5, 15, 10, 16, 7, 14, 12, 4, 1, 6, 9, 2, 11, 8, 3],
[
1, 3, 0, 6, 10, 15, 5, 4, 11, 2, 8, 13, 7, 16, 14, 9],
[
11, 7, 9, 14, 2, 13, 8, 6, 16, 10, 12, 3, 5, 1, 0, 15],
[
2, 16, 8, 4, 3, 9, 1, 0, 14, 7, 15, 5, 0, 6, 0, 12]]
input_value = input("Please input the value to fill the blank:\n")
fill(sudoku, input_value)
if check_sudoku(sudoku):
print("You done it!\nGive you!\nhgame{%s}" % input_value)
else:
print("You lose my game!")
发现是一个数独程序,其中flag就是我们输入用来填充数独的数字 用16进制表示
这里直接给出payload
from z3 import *
# 初始数独
sudoku = [
[4, 6, 14, 1, 0, 16, 12, 5, 9, 8, 0, 2, 15, 3, 10, 0],
[9, 8, 3, 12, 15, 4, 7, 10, 0, 13, 16, 6, 11, 14, 1, 2],
[5, 15, 7, 2, 13, 1, 6, 14, 3, 0, 10, 12, 8, 9, 0, 4],
[10, 11, 13, 16, 8, 3, 9, 2, 1, 15, 0, 4, 6, 12, 5, 7],
[14, 10, 4, 3, 6, 5, 15, 16, 8, 0, 13, 7, 1, 2, 9, 11],
[15, 13, 16, 11, 9, 2, 10, 8, 6, 14, 3, 1, 4, 7, 0, 5],
[7, 9, 1, 8, 0, 14, 4, 3, 2, 5, 11, 10, 16, 13, 15, 6],
[12, 2, 6, 5, 1, 0, 13, 7, 15, 9, 4, 0, 14, 8, 3, 10],
[3, 14, 2, 9, 5, 0, 16, 13, 7, 0, 1, 15, 12, 4, 11, 8],
[8, 1, 5, 15, 4, 6, 11, 9, 12, 3, 2, 14, 13, 10, 7, 0],
[16, 12, 0, 7, 14, 8, 2, 15, 13, 4, 9, 11, 3, 5, 6, 1],
[6, 4, 11, 13, 7, 12, 3, 0, 10, 16, 5, 8, 9, 15, 2, 0],
[13, 5, 15, 10, 16, 7, 14, 12, 4, 1, 6, 9, 2, 11, 8, 3],
[1, 3, 0, 6, 10, 15, 5, 4, 11, 2, 8, 13, 7, 16, 14, 9],
[11, 7, 9, 14, 2, 13, 8, 6, 16, 10, 12, 3, 5, 1, 0, 15],
[2, 16, 8, 4, 3, 9, 1, 0, 14, 7, 15, 5, 0, 6, 0, 12]]
# 创建 16x16 的整数变量网格
X = [[Int("x_%s_%s" % (i, j)) for j in range(16)] for i in range(16)]
# 创建求解器
s = Solver()
# 约束:每个单元格在 1 到 16 之间
s.add([And(X[i][j] >= 1, X[i][j] <= 16) for i in range(16) for j in range(16)])
# 约束:已知格子固定
for i in range(16):
for j in range(16):
if sudoku[i][j] != 0:
s.add(X[i][j] == sudoku[i][j])
# 约束:每行不同
for i in range(16):
s.add(Distinct(X[i]))
# 约束:每列不同
for j in range(16):
s.add(Distinct([X[i][j] for i in range(16)]))
# 约束:每个 4x4 宫不同
for i0 in range(0, 16, 4):
for j0 in range(0, 16, 4):
s.add(Distinct([X[i0 + di][j0 + dj] for di in range(4) for dj in range(4)]))
# 求解
if s.check() == sat:
m = s.model()
# 提取空白格的值(按顺序)
solution = [[m.evaluate(X[i][j]).as_long() for j in range(16)] for i in range(16)]
# 按原数独 0 的顺序收集
blank_values = []
for i in range(16):
for j in range(16):
if sudoku[i][j] == 0:
blank_values.append(solution[i][j])
# 转成十六进制字符(0~F)
hex_str = ''.join(hex(v - 1)[2:].upper() for v in blank_values)
print("Flag: hgame{" + hex_str + "}")
else:
print("No solution")
正文完