# 安洵杯SYCTF2023misc方向wp

### sudoku_easy

• 将形如

---------------------

800103720

023840650

410006008

300001062

000052407

072060090

160000375

205019846

000030000

---------------------

​ 转换成二维数组进行解数独，并将返回结果重新转换成多行字符串形式

def parse_input(input_list):
board = []

for row in input_list:
nums = list(map(int, row))
board.append(nums)

return board

def format_output(board):
formatted = ""
for row in board:
formatted += "".join(map(str, row)) + "\n"
return formatted.strip()

• 一开始以为每次获得5分，要拿到120分，range了24次，一直出问题，后来发现获得分数是递增的，同时调试了一下发现拿到120分会返回一个getshell，因此修改一下range7次

最终脚本:

def find_empty(board):
for row in range(9):
for col in range(9):
if board[row][col] == 0:
return row, col
return None

def is_valid(board, num, pos):
row, col = pos
for i in range(9):
if board[row][i] == num and col != i:
return False
if board[i][col] == num and row != i:
return False

box_row = row // 3
box_col = col // 3

for i in range(box_row * 3, box_row * 3 + 3):
for j in range(box_col * 3, box_col * 3 + 3):
if board[i][j] == num and (i, j) != pos:
return False

return True

def solve(board):
find = find_empty(board)
if not find:
return True
else:
row, col = find

for i in range(1, 10):
if is_valid(board, i, (row, col)):
board[row][col] = i

if solve(board):
return True

board[row][col] = 0

return False

def parse_input(input_list):
board = []

for row in input_list:
nums = list(map(int, row))
board.append(nums)

return board

def format_output(board):
formatted = ""
for row in board:
formatted += "".join(map(str, row)) + "\n"
return formatted.strip()

# input_string = '''---------------------
# 800103720
# 023840650
# 410006008
# 300001062
# 000052407
# 072060090
# 160000375
# 205019846
# 000030000
# ---------------------
# now give me you solve:'''

# lists=input_string.split('\n')[1:10]
# board = parse_input(lists)
# print(board)
# solve(board)
# print(board)

from pwn import *

# 创建连接
conn = remote('47.108.165.60',27539)

# 接收欢迎信息
for i in range(7):
print(msg)
# 发送选择
conn.sendline('1'.encode())

# 接收下一步提示
msg = conn.recvuntil("Please select the level:").strip().decode("utf-8")
print(msg)

conn.sendline('5'.encode())

msg = conn.recvuntil("clock start").strip().decode("utf-8")
print(msg)
time.sleep(5)

msg = conn.recvuntil("now give me you solve:").strip().decode("utf-8")
print(msg)
lists = msg.split('\n')[1:10]
board = parse_input(lists)
solve(board)
solved = format_output(board)
conn.sendline(solved.encode())

conn.interactive()


getflag

jpg文件尾压缩包

### sudoku_speedrun

kali :: ~ 127 » telnet 47.108.165.60 37569
Trying 47.108.165.60...
Connected to 47.108.165.60.
Escape character is '^]'.

Ubuntu 22.04.2 LTS
Welcome to Play Sudoku Game!
Play(1)
Exit(2)
> 1

Tips:
R to replay
Q to exit
WASD to move
You have 10000ms to solve it :)
easy(5)
normal(6)
hard(7)
>5



• 题目用了ANSI转义码，读取数据时会有大量的乱码，需要replace掉

response=response.replace(b'\x1b[7;32m',b'').replace(b'\x1b[0m',b'').replace(b'\x1b[1;32m',b'').replace(b'\x1b[H\x1b[2J',b'')

• 这里我为方便采用了在每一行右移填补到最后之后，往下再重新左移到最左边，再开始下一行的右移填补，而不是用左移填补导致需要倒着索引，略微增加了时间复杂度

def solve(input_string):
original_board = parse_input(input_string)# 创建原始数组的副本
board_copy = [row[:] for row in original_board]

solution = solve_sudoku(original_board)
# print(board_copy)
# print(solution)
lists=[]
for i in range(9):
for j in range(9):
if board_copy[i][j] == 0:
lists.append(str(solution[i][j]))
if j != 8:
lists.append('d')
lists.extend('saaaaaaaa')
# print(f"索引为 ({i}, {j}) 的位置，填入数字 {solution[i][j]}")
return lists

• 读取到形如

‘’’

-------------------------

| 4 3 0 | 0 0 6 | 2 0 0 |

| 8 0 0 | 0 7 0 | 0 0 3 |

| 2 0 7 | 0 5 0 | 1 4 6 |

-------------------------

| 0 0 0 | 0 0 0 | 0 7 5 |

| 7 5 0 | 8 0 0 | 6 2 0 |

| 0 2 9 | 7 3 5 | 0 1 0 |

-------------------------

| 5 6 0 | 4 0 3 | 0 9 0 |

| 0 0 2 | 5 0 0 | 8 0 0 |

| 3 0 1 | 0 8 2 | 0 6 4 |

-------------------------’’’

转二维数组

def parse_input(input_string):
rows = input_string.strip().split('\n')
board = []

for row in rows:
row = row.replace('-', '').replace('|', '').split()
nums = [int(num) if num != '0' else 0 for num in row]
if nums!=[]:
board.append(nums)

return board

• 经过尝试后发现只要发送数组服务器便会执行移动与填充操作，例如发送[‘d’,‘d’,‘1’]光标会右移两个单位并填入1

最终脚本:

import telnetlib
def solve_sudoku(board):
if is_complete(board):
return board

row, col = find_empty_cell(board)
for num in range(1, 10):
if is_valid(board, row, col, num):
board[row][col] = num
if solve_sudoku(board):
return board
board[row][col] = 0

return None

def is_complete(board):
for row in board:
if 0 in row:
return False
return True

def find_empty_cell(board):
for i in range(9):
for j in range(9):
if board[i][j] == 0:
return i, j
return None, None

def is_valid(board, row, col, num):
# Check row
if num in board[row]:
return False

# Check column
for i in range(9):
if board[i][col] == num:
return False

# Check 3x3 box
box_row = (row // 3) * 3
box_col = (col // 3) * 3
for i in range(box_row, box_row + 3):
for j in range(box_col, box_col + 3):
if board[i][j] == num:
return False

return True

def parse_input(input_string):
rows = input_string.strip().split('\n')
board = []

for row in rows:
row = row.replace('-', '').replace('|', '').split()
nums = [int(num) if num != '0' else 0 for num in row]
if nums!=[]:
board.append(nums)

return board

def solve(input_string):
original_board = parse_input(input_string)# 创建原始数组的副本
board_copy = [row[:] for row in original_board]

solution = solve_sudoku(original_board)
# print(board_copy)
# print(solution)
lists = []
for i in range(9):
for j in range(9):
if board_copy[i][j] == 0:
lists.append(str(solution[i][j]))
if j != 8:
lists.append('d')
lists.extend('saaaaaaaa')
# print(f"索引为 ({i}, {j}) 的位置，填入数字 {solution[i][j]}")
return lists

tn = telnetlib.Telnet('47.108.165.60',36697)

print(welcome_msg.decode("utf-8"))

# 发送返回值到服务器
tn.write("1".encode("utf-8") + b"\n")

print(msg.decode("utf-8"))

tn.write("5".encode("utf-8") + b"\n")

msg = ''
for i in range(15):
# print((response))
response = response.replace(b'\x1b[7;32m',b'').replace(b'\x1b[0m',b'').replace(b'\x1b[1;32m',b'').replace(b'\x1b[H\x1b[2J',b'')
msg += response.decode().strip('> 5')
tn.write(str(solve(msg)).encode("utf-8") + b"\n")
tn.interact()


### cancellation

mkvextract.exe提取出来两个音频（轨道是从0开始的，mkvtool里的轨道编号从1开始的）

import librosa
import soundfile as sf
import numpy as np

result =  2*audio1-audio2
sf.write('result.wav', result, sr1)


• 4
点赞
• 3
收藏
觉得还不错? 一键收藏
• 0
评论
04-10
03-01 408
11-28 1026
06-14 234
02-02 1612
12-24 1607
02-10 1349
05-30 589
06-11 326
05-06
04-18 418
04-20 381

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。