NSSCTF部分题目总结
NSSCTF部分题目总结

NSSCTF部分题目总结

迷宫问题脚本

重点是找到有关map的字符串或数字,再根据信息得出路径长度以及首坐标(map的值可能会直接给出,也可能需要动调后得出)。

str = ""(字符串或数字)

s = 0  # s用作索引访问str, 供下面tmp列表取值

# 分析题目后设置迷宫的行列
row = 16 # 设置二维迷宫行数
col =16  # 设置二维迷宫列数

maze = []
for i in range(row):
    tmp = []
    for j in range(col):
        tmp.append(str[s])
        s += 1
    maze.append(tmp)  # 凑一行添加一行到迷宫中
print(maze)
from collections import deque

# 设置二维四向迷宫, 如果题目是多个小迷宫问题, 拆分多次调用脚本获取路径即可
maze = 
path_len =   # 如果题目未给出终点坐标,则一定会指定路径的长度,在此处修改路径长度,否则请保留path_len的极大值


# 进行BFS寻找路径
def bfs(start, end, barrier):
    directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]  # 定义四个方向的移动
    for i in range(len(maze)):  # 获取起点和终点在列表中的索引
        for j in range(len(maze[i])):
            if (maze[i][j] == start):
                start = (i, j)
            if (maze[i][j] == end):
                end = (i, j)
    # 以下均是bfs算法套路
    queue = deque()
    queue.append((start, [start]))  # (当前位置, 路径)
    visited = set()
    visited.add(start)
    while queue:
        position, path = queue.popleft()
        if position == end:
            return path
        elif len(path) == path_len:
            return path
        for d in directions:
            next_position = (position[0] + d[0], position[1] + d[1])
            if 0 <= next_position[0] < len(maze) and 0 <= next_position[1] < len(maze[0]) and \
                    maze[next_position[0]][next_position[1]] != barrier and next_position not in visited:
                queue.append((next_position, path + [next_position]))
                visited.add(next_position)
    return None


# 执行BFS搜索并打印结果
if __name__ == '__main__':
    maze[15][1]='S'
    # maze[起点x坐标][起点y坐标] = 'S' #如果题目给了起点终点的坐标,在这里直接给起点和终点添加特征
    # maze[终点x坐标][终点y坐标] = 'E'

    path = bfs('S', 'E', 1)  # bfs函数传入参数代表起点、终点、障碍的特征(若题目给出的数据无特征, 手动添加特征即可, 通常障碍是1也有可能是0或其它字符如'#')
    print("移动路径坐标:", path)
    print("移动路径方位:{", end='')
    for i in range(1, len(path)):
        x1, y1, x2, y2 = path[i - 1][0], path[i - 1][1], path[i][0], path[i][1]
        if (x1 > x2):  # 上
            print("w", end='')
        elif (x1 < x2):  # 下
            print("s", end='')
        elif (y1 > y2):  # 左
            print("a", end='')
        elif (y1 < y2):  # 右
            print("d", end='')
    print('}')

md脚本

import hashlib
md=hashlib.md5()
md.update(''.encode('utf-8'))
print(md.hexdigest())

base64 换表操作脚本

def basechange(base):
  # 定义一个索引数组,用于置换字符的位置
  index = [0] * 65
  index[0] = 16
  index[1] = 34
  index[2] = 56
  index[3] = 7
  index[4] = 46
  index[5] = 2
  index[6] = 10
  index[7] = 44
  index[8] = 20
  index[9] = 41
  index[10] = 59
  index[11] = 31
  index[12] = 51
  index[13] = 60
  index[14] = 61
  index[15] = 26
  index[16] = 5
  index[17] = 40
  index[18] = 21
  index[19] = 38
  index[20] = 4
  index[21] = 54
  index[22] = 52
  index[23] = 47
  index[24] = 3
  index[25] = 11
  index[26] = 58
  index[27] = 48
  index[28] = 32
  index[29] = 15
  index[30] = 49
  index[31] = 14
  index[32] = 37

  index[34] = 55
  index[35] = 53
  index[36] = 24
  index[37] = 35
  index[38] = 18
  index[39] = 25
  index[40] = 33
  index[41] = 43
  index[42] = 50
  index[43] = 39
  index[44] = 12
  index[45] = 19
  index[46] = 13
  index[47] = 42
  index[48] = 9
  index[49] = 17
  index[50] = 28
  index[51] = 30
  index[52] = 23
  index[53] = 36
  index[54] = 1
  index[55] = 22
  index[56] = 57
  index[57] = 63
  index[58] = 8
  index[59] = 27
  index[60] = 6
  index[61] = 62
  index[62] = 45
  index[63] = 29
  # 将字符串转换为列表,方便修改
  base = list(base)
  # 进行48次置换
  for i in range(48):
    # 创建一个临时列表,用于存储置换后的字符
    temp = [0] * 64
    # 遍历索引数组,按照索引交换字符
    for j in range(64):
      temp[j] = base[index[j]]
    # 将临时列表赋值给原始列表
    base = temp
  # 将列表转换回字符串,并返回
  return "".join(base)

# 定义一个字符串,用于测试
table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
# 调用函数,对字符串进行置换
table = basechange(table)
# 打印置换后的字符串
print(table)

取模运算

[SWPUCTF 2021 新生赛]fakebase

根据题解对该运算方法有了一些初步理解

flag = 'xxxxxxxxxxxxxxxxxxx'

s_box = 'qwertyuiopasdfghjkzxcvb123456#$'
tmp = ''
for i in flag:
    tmp += str(bin(ord(i)))[2:].zfill(8)
b1 = int(tmp,2)
s = ''
while b1//31 != 0:
    s += s_box[b1%31]
    b1 = b1//31

print(s)

# s = u#k4ggia61egegzjuqz12jhfspfkay
  • ord(i) 获取字符的ASCII码。

  • bin(ord(i)) 将ASCII码转换为二进制字符串。

  • [2:] 去掉二进制字符串前缀 ‘0b’ 。

  • .zfill(8) 将二进制字符串填充为8位

假设c=a%b已知,c和b,那么a可以得到算式:a=k*b+c。其中k是需要爆破的。

回到题目本身我们我肯可以得到s的值,其中s的值都是s_box中取的,因此[b1%31]是可以得知的。

import libnum
s_box = 'qwertyuiopasdfghjkzxcvb123456#$'
s = 'u#k4ggia61egegzjuqz12jhfspfkay'
for k in range(5):
    b1=k
    for i in s[::-1]:
        b1 = b1*31+s_box.index(i)
    print(libnum.n2s(int(b1)))

Z3python脚本

from z3 import *

s=Solver()
v,w,x,y,z=Ints('v w x y z')
s.add()
s.add()
s.add()
s.add()
s.add()

s.check()
print(s.model())

有多少方程就写多少s.add(),在()中写入关系式

相关条目

  • base64
  • 花指令
  • Destination 逆向题解
  • BFS经典题目

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注