Round1
[Round 1] xor
kail upx脱壳,一眼顶针,xor
v5 = [0x45, 0x50, 0x5f, 0x48, 0x5a, 0x67, 0x7f, 0x2d, 0x2b, 0x7e, 0x24, 0x78, 0x2c, 0x24, 0x31, 0x2c, 0x7e, 0x78, 0x24,0x31, 0x28, 0x2d, 0x7a, 0x7d, 0x31, 0x7e, 0x25, 0x79, 0x2b, 0x31, 0x29, 0x79, 0x2a, 0x2f, 0x2e, 0x2b, 0x2e, 0x2b,0x24, 0x2e, 0x24, 0x2d, 0x61, 0x1c,
]# 解密过程
decrypted = [byte ^ 0x1C for byte in v5]# 转换为字符
flag = ''.join(chr(byte) for byte in decrypted if 0x20 <= byte <= 0x7E) # 只保留可打印字符print("Decrypted flag:", flag)
#Decrypted flag: YLCTF{c17b8d08-0bd8-41fa-b9e7-5e6327278281}
[Round 1] xorplus
异或之后rc4解密,逆向解密
A=[0x91,0x86,0x1b,0x2d,0x9e,0x6f,0x59,0x26,0x44,0xec,0xa3,0x9f,0xcf,0x43,0x22,0x66,0x8e,0xee,0x5d,0x2d,0x80,0x5b,0x4a,0x1d,0x6c,0x4e,0x83,0x47,0x83,0x26,0xb6,0xeb,0x84,0x79,0x5c,0xd0,0xbc,0x4f,0x58,0xc7,0xc,0x88,0xa6]
def rc4( data):out=[]S=[0x8B, 0x03, 0x5A, 0x05, 0x64, 0xC2, 0x89, 0x18, 0x24, 0x4C, 0xE9, 0x3C, 0xD0, 0x7A, 0x23, 0x47,0xB7, 0x2E, 0x27, 0x17, 0x46, 0x09, 0x5D, 0xB5, 0x72, 0x58, 0xD9, 0x21, 0xE3, 0x9E, 0x49, 0x54,0xC8, 0x51, 0xB6, 0x91, 0x10, 0x2C, 0x96, 0xEB, 0xFD, 0x74, 0xF3, 0x97, 0x5C, 0xE7, 0x84, 0xE5,0x3A, 0xAE, 0x99, 0xDF, 0xD3, 0x7F, 0x3D, 0x40, 0x93, 0xBC, 0xCF, 0xB2, 0x78, 0xC6, 0xF8, 0x48,0xF2, 0xC0, 0x6B, 0x52, 0x30, 0xB0, 0x4F, 0x0B, 0x13, 0x53, 0x79, 0x35, 0x00, 0x70, 0x02, 0xF4,0xA1, 0x69, 0x6F, 0xA5, 0x7D, 0x04, 0x5E, 0xE2, 0xBD, 0x2B, 0x6A, 0x32, 0x43, 0x7C, 0x4B, 0x06,0x71, 0xF0, 0x86, 0x8C, 0x12, 0x6C, 0x80, 0x34, 0xAF, 0x8D, 0xC9, 0xF6, 0xC4, 0x36, 0x6E, 0x0F,0x5B, 0x4D, 0xA7, 0x1A, 0x44, 0xC7, 0xDE, 0x8E, 0x07, 0x76, 0x1F, 0xFF, 0x9D, 0x8F, 0x16, 0xEC,0xAA, 0xCC, 0xA8, 0x26, 0xDC, 0x22, 0xBF, 0x62, 0x61, 0x41, 0x85, 0xB1, 0xD7, 0x1B, 0xA4, 0x94,0x90, 0x28, 0x98, 0xEE, 0xE8, 0xA3, 0x60, 0x6D, 0xB8, 0xCB, 0x0E, 0x55, 0xAD, 0xA2, 0xC3, 0x3B,0xFC, 0xB4, 0xD5, 0xFE, 0xDD, 0x14, 0xD8, 0xBB, 0x66, 0x92, 0xC5, 0xFA, 0xED, 0xBA, 0x42, 0xBE,0x4E, 0x39, 0xA0, 0x59, 0xD4, 0x19, 0xE0, 0x95, 0x2F, 0x56, 0x8A, 0xC1, 0x1C, 0x37, 0xCA, 0x77,0xAC, 0x88, 0x0A, 0xAB, 0x0D, 0xDB, 0xF7, 0x7E, 0x4A, 0xE4, 0x11, 0x5F, 0x15, 0x1E, 0xD6, 0xDA,0x20, 0xA6, 0x33, 0x29, 0x0C, 0xEF, 0x3E, 0x81, 0x31, 0x87, 0x45, 0xD2, 0xE6, 0x9F, 0xE1, 0x57,0xCD, 0xB9, 0x2A, 0x75, 0x08, 0x3F, 0xA9, 0xCE, 0x38, 0x9C, 0xF9, 0x25, 0x9A, 0x83, 0xF5, 0xFB,0x67, 0xEA, 0x50, 0xB3, 0x7B, 0x01, 0x82, 0x73, 0x68, 0x1D, 0x2D, 0xF1, 0x63, 0x9B, 0x65, 0xD1]i = j = 0for t in data:i = (i + 1) % 256j = (j + S[i]) % 256S[i], S[j] = S[j], S[i]out.append(((t-20)^ S[(S[i] + S[j]) % 256])%256)return outkey=[ord(i) for i in "welcometoylctf"]
flag=rc4(A)
print(bytes(flag))
#YLCTF{49f6203c-be03-4df8-9a5a-5eb1d48c3d9d}
[Round 1] math
数独,写脚本解密,之后直接交互得到flag
a=[1,0,0, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 8, 0,0, 9, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 5, 0, 0, 6, 7, 0, 0,8, 0, 0, 9, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 4, 0, 0, 5, 0, 0, 6, 0,0, 0, 7, 0, 0, 8, 0, 0, 9, 0, 0]
#9x9输出
# for i in range(9):
# for j in range(9):
# print(a[i*9+j],end=',')
# print()B=[1,5,6,2,4,9,3,7,8,8,4,9,3,5,7,1,6,2,2,3,7,1,6,8,4,5,9,6,1,5,9,2,4,8,3,7,9,8,4,7,3,5,2,1,6,7,2,3,8,1,6,9,4,5,5,6,1,4,9,2,7,8,3,4,9,8,5,7,3,6,2,1,3,7,2,6,8,1,5,9,4]
#diff a and b
for i in range(9):for j in range(9):if a[i*9+j]!=B[i*9+j]:print(B[i*9+j],end='')# 5 6 4 9 7 8 8 9 3 7 1 2 2 3 1 6 4 5 6 5 9 4 8 7 9 8 7 3 2 1 2 3 1 6 4 5 5 6 4 9 7 8 9 8 7 3 2 1 3 2 6 1 5 4
[Round 1] ezgo
go逆向,xor解密
enc=[108, 122, 116, 108, 127, 65, 89, 10, 9, 15,
15, 38, 115, 112, 110, 117, 114, 115, 115, 101,
125, 47, 114, 47, 96, 47, 124, 101, 99, 127,
49, 100, 96, 110, 51, 61, 59, 104, 57, 57,
60, 111, 34]
for i in range(len(enc)):print(chr(enc[i] ^ (i + 0x35)), end='')#YLCTF{b6410f22-1754-4e9c-a352-b058deb2bea1}
[Round 1] calc
给的混淆进行还原后是这个
class Stack:def __init__(self):self.items = []def push(self, item):self.items.append(item)def pop(self):if not self.items:raise IndexError("pop from empty stack")return self.items.pop()def main():stack = Stack()print("Input data, end of '#'")ch = input().strip() # Read first characterwhile ch != '#':num = ''while ch.isdigit(): # Collect digitsnum += chch = input().strip() # Read next characterif num: # Convert to float and push to stack if num is not emptyd = float(num)stack.push(d)# Perform operation if a valid operator is foundif ch in '+-*/':d = stack.pop() # Pop the top two elements for the operatione = stack.pop()if ch == '+':stack.push(e + d)elif ch == '-':stack.push(e - d)elif ch == '*':stack.push(e * d)elif ch == '/':if d != 0:stack.push(e / d)else:print("Error: Division by zero")ch = input().strip() # Read next character# Final resultd = stack.pop()if d == 125:print("Flag:", os.getenv("GZCTF_FLAG"))if __name__ == "__main__":import osmain()
然后对应计算得到125就能出flag
#include <stdio.h>
#include <stdlib.h>
typedef struct Stack
{double *top;double *low;int size;
} stack;
void init(stack *s)
{s->low = (double *)malloc((sizeof(double))) ;s->top = s->low;s->size = 100;
}
void push(stack *s, double e)
{*(s->top) = e;s->top++;
}
void pop(stack *s, double *e) { *e = *--(s->top); }
int main()
{setbuf(stdin, 0);setbuf(stdout, 0);stack s;char ch;double d, e ;char num[100];int i = 0;init(&s);puts("input data , end of '#'");scanf("%s", &ch);while (ch != '#'){while (ch >= '0' && ch <= '9'){num[i] = ch;scanf("%c", &ch);if (ch == ' '){d = atof(num);push(&s, d);i = 0;break;}}switch (ch){case '+':pop(&s, &d);pop(&s, &e);push(&s, e + d);break;case '-':pop(&s, &d);pop(&s, &e);push(&s, e - d);break;case '*':pop(&s, &d);pop(&s, &e);push(&s, e * d);break;case '/':pop(&s, &d);pop(&s, &e);push(&s, e / d);break;}scanf("%c", &ch);}pop(&s, &d);printf("%f\n", d);if (d == 125){printf("GZCTF_FLAG");}
}
交互得到flag
5 5 5 * *
#
Round2
ezwasm
ghidra装wasm插件看逻辑
然后爆破
tmp=[ord(i) for i in ""]
enc=[0]*len(tmp)
flag=[0]*len(tmp)
#可见字符
table="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{}-"
for i in range(len(enc)):for char in table:if 'A' <= char <= 'Z':# 如果字符是大写字母,则进行处理# *(char *)(enc + i) = *(char *)(enc + i) + ' ';enc[i] = chr(ord(char) + 0x20)#*(char *)(enc + i) = (char)((*(char *)(enc + i) + -0x5a) % 0x1a) + 'a';enc[i] = chr((ord(enc[i]) - 0x5a) % 0x1a + ord('a'))elif 'a' <= char <= 'z':# 如果字符是小写字母,则进行处理enc[i] = chr(ord(char) - 0x20) # 转换为大写enc[i] = chr((ord(enc[i]) - 0x3a) % 0x1a + ord('A'))else:# 不做任何处理passif enc[i] == chr(tmp[i]):flag[i]=char
for i in range(len(flag)):if flag[i] == 0:print(chr(tmp[i]),end="")else:print(flag[i],end="")
三点几啦饮茶先
xtea模板题
#include <stdio.h>
#include <stdint.h>//解密函数
void decrypt(uint32_t* v, uint32_t* k) {uint32_t v0 = v[0], v1 = v[1], sum = 0x114514B9*0x28, i;uint32_t delta = 0x114514B9;uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];for (i = 0; i<0x28; i++) {v1 -= (((v0 *16 ) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]);// v0 += (((v1 >> 3) ^ (4 * v1)) + v1) ^ (*(4LL * (sum & 3) + key) + sum);sum -= delta;// (((v0 >> 5) ^ (16 * v0)) + v0) ^ (*(4LL * ((sum >> 11) & 3) + key) + sum)v0 -= (((v1 * 4) ^ (v1 >> 3)) + v1) ^ (sum + k[sum & 3]);}v[0] = v0; v[1] = v1;
}int main()
{uint32_t v[2] = {};uint32_t k[4] = { 0x1001,0x2002,0x3003,0x4004 };decrypt(v, k);printf("%d %d\n",v[0],v[1]);printf("\n");return 0;
}
ezapk
这题的check逻辑简直是一坨
先写z3拿key
from z3 import *
s=Solver()
#BitVecs定义
key = [BitVec('key[%d]' % i, 31) for i in range(16)]
s.add ((key[0] * 41) - (key[1] * 16) + (key[2] * 84) + (key[3] * 35) - (key[4] * 74) + (key[5] * 33) + (key[6] * 58) + (key[7] * 70) - (key[8] * 83) - (key[9] * 48) + (key[10] * 68) + (key[11] * 82) + (key[12] * 90) - (key[13] * 37) - (key[14] * 60) + (key[15] * 23) == 22064)
s.add ((-key[0] * 63) - (key[1] * 76) - (key[2] * 79) - (key[3] * 34) + (key[4] * 64) - (key[5] * 93) - (key[6] * 16) - (key[7] * 69) - (key[8] * 34) + (key[9] * 19) + (key[10] * 17) + (key[11] * 66) + (key[12] * 93) - (key[13] * 57) + (key[14] * 77) + (key[15] * 45) == -9131 )
s.add (((-key[0]) * 28) + (key[1] * 79) - (key[2] * 43) + (key[3] * 19) + (key[4] * 58) + (key[5] * 82) - (key[6] * 20) + (key[7] * 15) - (key[8] * 15) - (key[9] * 65) + (key[10] * 92) + (key[11] * 71) + (key[12] * 34) + (key[13] * 71) - (key[14] * 26) + (key[15] * 37) == 30351 )
s.add ((key[0] * 60) + (key[1] * 38) - (key[2] * 24) + (key[3] * 24) + (key[4] * 36) + (key[5] * 50) - (key[6] * 56) - (key[7] * 25) - (key[8] * 88) - (key[9] * 14) - (key[10] * 77) + (key[11] * 77) + (key[12] * 80) - (key[13] * 41) - (key[14] * 42) + (key[15] * 90) == 9755 )
s.add ((key[0] * 13) - (key[1] * 21) - (key[2] * 96) + (key[3] * 82) + (key[4] * 63) + (key[5] * 87) - (key[6] * 71) - (key[7] * 77) + (key[8] * 34) + (key[9] * 95) - (key[10] * 21) + (key[11] * 51) + (key[12] * 54) + (key[13] * 81) - (key[14] * 70) + (key[15] * 86) == 25623 )
s.add ((key[0] * 18) + (key[1] * 70) - (key[2] * 82) + (key[3] * 69) + (key[4] * 77) + (key[5] * 44) + (key[6] * 41) - (key[7] * 43) - (key[8] * 76) + (key[9] * 67) + (key[10] * 36) + (key[11] * 32) - (key[12] * 19) - (key[13] * 41) - (key[14] * 69) + (key[15] * 39) == 18410 )
s.add ((key[0] * 59) - (key[1] * 83) - (key[2] * 34) - (key[3] * 55) - (key[4] * 42) - (key[5] * 86) + (key[6] * 93) + (key[7] * 97) - (key[8] * 88) - (key[9] * 90) - (key[10] * 63) - (key[11] * 76) - (key[12] * 84) - (key[13] * 84) + (key[14] * 96) - (key[15] * 76) == -39929 )
s.add ((-key[0] * 72) + (key[1] * 81) - (key[2] * 10) - (key[3] * 58) - (key[4] * 55) - (key[5] * 94) - (key[6] * 48) + (key[7] * 79) - (key[8] * 81) - (key[9] * 83) - (key[10] * 32) - (key[11] * 77) + (key[12] * 17) + (key[13] * 78) + (key[14] * 97) + (key[15] * 97) == -11909 )
s.add ((key[0] * 81) + (key[1] * 45) - (key[2] * 37) + (key[3] * 69) + (key[4] * 48) - (key[5] * 22) - (key[6] * 61) - (key[7] * 44) - (key[8] * 26) - (key[9] * 30) + (key[10] * 21) + (key[11] * 41) + (key[12] * 33) - (key[13] * 49) - (key[14] * 98) + (key[15] * 94) == 11780 )
s.add ((key[0] * 72) - (key[1] * 94) + (key[2] * 77) - (key[3] * 70) + (key[4] * 10) - (key[5] * 33) + (key[6] * 58) - (key[7] * 48) + (key[8] * 65) + (key[9] * 21) + (key[10] * 33) - (key[11] * 35) - (key[12] * 90) + (key[13] * 69) - (key[14] * 10) - (key[15] * 20) == -6077 )
s.add ((key[0] * 11) + (key[1] * 28) + (key[2] * 13) + (key[3] * 92) + (key[4] * 24) - (key[5] * 35) + (key[6] * 80) + (key[7] * 51) + (key[8] * 41) + (key[9] * 42) - (key[10] * 19) - (key[11] * 78) + (key[12] * 32) + (key[13] * 33) + (key[14] * 27) + (key[15] * 40) == 22889 )
s.add ((key[0] * 62) + (key[1] * 33) + (key[2] * 67) + (key[3] * 13) + (key[4] * 24) - (key[5] * 96) + (key[6] * 46) - (key[7] * 94) - (key[8] * 91) + (key[9] * 25) - (key[10] * 37) + (key[11] * 17) + (key[12] * 39) + (key[13] * 80) - (key[14] * 94) - (key[15] * 22) == -8594 )
s.add ((key[0] * 57) - (key[1] * 83) - (key[2] * 82) + (key[3] * 78) - (key[4] * 37) - (key[5] * 76) + (key[6] * 84) + (key[7] * 63) + (key[8] * 33) + (key[9] * 50) - (key[10] * 96) - (key[11] * 12) + (key[12] * 96) + (key[13] * 19) + (key[14] * 62) + (key[15] * 51) == 7626 )
s.add ((-key[0] * 67) - (key[1] * 85) + (key[2] * 13) + (key[3] * 11) - (key[4] * 53) + (key[5] * 40) + (key[6] * 52) - (key[7] * 43) - (key[8] * 63) + (key[9] * 61) - (key[10] * 18) + (key[11] * 14) - (key[12] * 92) + (key[13] * 77) - (key[14] * 91) + (key[15] * 42) == -7984 )
s.add ((key[0] * 53) + (key[1] * 69) - (key[2] * 57) + (key[3] * 40) + (key[4] * 48) - (key[5] * 50) - (key[6] * 40) - (key[7] * 90) + (key[8] * 69) + (key[9] * 84) + (key[10] * 65) - (key[11] * 56) + (key[12] * 90) + (key[13] * 56) - (key[14] * 50) + (key[15] * 97) == 23771 )
s.add ((key[0] * 85) + (key[1] * 86) + (key[2] * 19) - (key[3] * 47) + (key[4] * 16) - (key[5] * 17) - (key[6] * 77) + (key[7] * 54) + (key[8] * 59) - (key[9] * 19) - (key[10] * 53) + (key[11] * 52) - (key[12] * 64) + (key[13] * 95) - (key[14] * 66) - (key[15] * 61) == -6025)
for i in range(16):s.add(key[i] >= 32)s.add(key[i] <= 126)if s.check() == sat:m = s.model()flag = ''for i in range(16):flag += chr(m[key[i]].as_long())print(flag)
hook 拿iv
// 必须写在 Java 虚拟机中
Java.perform(function() {let Myjni = Java.use("com.example.myapplication.Myjni");
Myjni["encode"].implementation = function (str) {console.log(`Myjni.encode is called: str=${str}`);let result = this["encode"](str);console.log(`Myjni.encode result=${result}`);return result;
};})
最后SM4解密
Round3
[Round 3] ezmaze
maze,迷宫题
def create_maze(maze_str, rows, cols):maze = []for i in range(rows):row = list(maze_str[i * cols:(i + 1) * cols])maze.append(row)return mazedef is_valid_move(x, y, maze, visited):return (0 <= x < len(maze) and0 <= y < len(maze[0]) andmaze[x][y] != '*' andnot visited[x][y])def dfs(maze, x, y, path, visited):if maze[x][y] == 'F':return Truevisited[x][y] = True# Define the possible movements: down (S), up (W), right (D), left (A)moves = [(1, 0, 's'), (-1, 0, 'w'), (0, 1, 'd'), (0, -1, 'a')]for move in moves:new_x, new_y, direction = x + move[0], y + move[1], move[2]if is_valid_move(new_x, new_y, maze, visited):path.append(direction) # Record the directionif dfs(maze, new_x, new_y, path, visited):return Truepath.pop() # Backtrack if not successfulvisited[x][y] = Falsereturn Falsedef solve_maze(maze_str, start_pos):rows, cols = 11,10maze = create_maze(maze_str, rows, cols)visited = [[False for _ in range(cols)] for _ in range(rows)]path = []start_x, start_y = start_posif dfs(maze, start_x, start_y, path, visited):return pathelse:return None# 迷宫字符串和起始位置
maze_str = "*****++*********+******+*++******+++*****F*+*******+*+++*****+***++****+***+*****+***+*+***+++++++************"
for i in range(11):print(maze_str[i*10:(i+1)*10])
start_pos = (0, 5)# 求解迷宫
solution = solve_maze(maze_str, start_pos)# 输出结果
if solution:print("Path to F:", ''.join(solution))
else:print("No path found.")
跑出来之后md5加密