安洵杯SYCTF2023misc方向wp

转载请备注来源

sudoku_easy

简单的数独交互,几个小注意点,每次发送level之后sleep5秒才会返回题目

image-20230610185716309

  • 将形如

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

    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):
    msg = conn.recvuntil("Please input:").strip().decode("utf-8")
    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

image-20230610190212900

烦人的压缩包

爆破

image-20230610190304845

jpg文件尾压缩包

image-20230610190322841

提取出来直接解压提示crc报错

image-20230610193516762

观察后发现store算法却有着极高的压缩率明显不合理

image-20230610193550071

改一下压缩方式和解压方式为default(单单改解压方式也够了)

image-20230610193624253

解开后ook解密

image-20230610193746752

sudoku_speedrun

小小升级版数独,telnet交互

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)
Please input
> 1

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

image-20230610193910056

这次需要解出之后通过移动光标将数独还原

其实大差不差,这里主要几个点

  • 题目用了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)

welcome_msg = tn.read_until(b"Please input")
print(welcome_msg.decode("utf-8"))

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

msg = tn.read_until(b"hard(7)")
print(msg.decode("utf-8"))

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

msg = ''
for i in range(15):
    response = tn.read_until(b"\n")
    # 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()

image-20230610195935427

cancellation

浅恰了个三血还行

题目得到noise.mp4,意外的发现用windows media player播放可以读到一串sstv

image-20230610200317154

结合file用Matroska打包猜测应该是mkv文件

image-20230610200410070

用mkvtool发现确实有多个音频轨道

image-20230610200535476

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

image-20230610201638810

轨道3可以读到一张图

image-20230610200931537

轨道2可以读到一个模糊无法识别的二维码,仔细观察可以发现背景图似乎就是轨道3读到的图

image-20230610201035296

在测试过程中发现在一定位置挂上notch之后,可以读到很清晰的后半边的二维码,左半边变得更加模糊了,但却更加清晰的显示出背景图,明显就是轨道3的图

image-20230610201214671

再结合题目名,大胆猜测轨道2的sstv做了一个叠加处理,尝试几次后2*轨道2-轨道3可以扫描出正确的图像(这里放完整二维码图片会被csdnban掉)

import librosa
import soundfile as sf
import numpy as np

audio1, sr1 = librosa.load('2.wav', sr=None)
audio2, sr2 = librosa.load('3.wav', sr=None)

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

image-20230610215510870

扫描的结果解base64得到图片

image-20230610202014820

拿到flag

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2023蓝帽初赛misc下载是指在2023年举办的蓝帽网络安全竞赛中的一项miscellaneous(杂项)类题目的下载。在初赛中,参赛选手需要下载与miscellaneous相关的题目文件或资源,并进行分析和解决。 首先,参赛选手需要前往蓝帽竞赛官方网站或相关论坛查找与初赛misc下载相关的公告或指引。这些网站通常会提供下载链接或资源分享的方式,以方便选手获取题目所需的文件或资源。 其次,根据所提供的下载链接,选手可以点击链接进行下载,也可以使用迅雷、qq旋风等下载工具进行高速下载,以确保下载的文件完整和无误。 在完成下载后,选手需要对下载的文件进行验证。可使用md5校验工具对下载后的文件进行校验,以确保文件的完整性和正确性,防止下载过程中出现错误导致文件损坏。 之后,选手可以开始进行miscellaneous题目的解析和答题。首先,解压下载的文件,查看所提供的题目资源、源代码或二进制文件等。根据题目要求和提示,选手可以使用各种工具和技术,如逆向工程、数据分析、密码学等,进行问题的分析和解决,并找出相应的答案或flag。 最后,选手需要将自己的解题过程、思路和答案记录下来,并按照比赛规则的要求提交答案。可以是一个文本文件或截图,或是将解决问题的代码或脚本提交到竞赛平台或指定的邮箱中。 总之,2023蓝帽初赛misc下载是参赛选手在参加蓝帽网络安全竞赛中所需进行的一项任务。选手需要在蓝帽官方网站或相关论坛上获取下载链接并下载题目相关的文件或资源,然后对其进行验证、解析和解决,最后提交答案以完成竞赛的要求。这项任务对选手的网络安全技术、解题思维和团队合作能力都提出了较高的要求。

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值