2024-源鲁杯 [Round2]
[Round 2] 三点几啦饮茶先
flag: YLCTF{84ec2ee8-403e-42ae-9d52-76de28c8d13c}
简单魔改tea
from ctypes import *
enc = [0x72093D7C, 0xB60BF47D]
key = [0x1001, 0x2002, 0x3003, 0x4004]
for i in range(1):
prev = c_uint32(enc[2*i])
next = c_uint32(enc[2*i+1])
sum = c_uint32(0x114514B9 * 40)
for j in range(40):
next.value -= (((prev.value >> 5) ^ (16 * prev.value)) + prev.value) ^ (key[((sum.value >> 11) & 3)] + sum.value)
sum.value -= 0x114514B9
prev.value -= (((next.value >> 3) ^ (4 * next.value)) + next.value) ^ (key[sum.value & 3] + sum.value)
print(hex(prev.value))
print(hex(next.value))
[Round 2] ezapk
flag: YLCTF{b30762d0-d6c9-4065-b80b-c1e235726f06}
首先java层有一个对key的检验
然后对data进行一个sm4加密
直接用z3求解
from z3 import*
for i in range(9):
s = Solver()
key = [BitVec(f'key{j}', 8) for j 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] * 0x30 + key[10] * 68 + key[11] * 82 + key[12] * 90 - key[13] * 37 - key[14] * 60 + key[15] * 23 == 0x5630)
s.add(-key[0] * 0x3F - key[1] * 76 - key[2] * 0x4F - key[3] * 34 + key[4] * 0x40 - 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] * 0x4F - 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 == 0x768F)
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] * 0x60 + key[3] * 82 + key[4] * 0x3F + key[5] * 87 - key[6] * 71 - key[7] * 77 + key[8] * 34 + key[9] * 0x5F - key[10] * 21 + key[11] * 51 + key[12] * 54 + key[13] * 81 - key[14] * 70 + key[15] * 86 == 0x6417)
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] * 0x20 - 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] * 0x3F - key[11] * 76 - key[12] * 84 - key[13] * 84 + key[14] * 0x60 - key[15] * 76 == 0xFFFF6407)
s.add(-key[0] * 72 + key[1] * 81 - key[2] * 10 - key[3] * 58 - key[4] * 55 - key[5] * 94 - key[6] * 0x30 + key[7] * 0x4F - key[8] * 81 - key[9] * 83 - key[10] * 0x20 - 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] * 0x30 - 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 == 0x2E04)
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] * 0x30 + 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] * 0x20 + key[13] * 33 + key[14] * 27 + key[15] * 40 == 0x5969)
s.add(key[0] * 62 + key[1] * 33 + key[2] * 67 + key[3] * 13 + key[4] * 24 - key[5] * 0x60 + 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] * 0x3F + key[8] * 33 + key[9] * 50 - key[10] * 0x60 - key[11] * 12 + key[12] * 0x60 + 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] * 0x3F + key[9] * 61 - key[10] * 18 + key[11] * 14 - key[12] * 92 + key[13] * 77 - key[14] * 91 + key[15] * 42 == 0xFFFFE0D0)
s.add(key[0] * 53 + key[1] * 69 - key[2] * 57 + key[3] * 40 + key[4] * 0x30 - 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 == 0x5CDB)
s.add(key[0] * 85 + key[1] * 86 + key[2] * 19 - key[3] * 0x2F + 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] * 0x40 + key[13] * 0x5F - key[14] * 66 - key[15] * 61 == -6025)
if s.check() == sat:
model = s.model()
solution = [model.eval(key[i]) for i in range(16)]
print("解为:", solution)
else:
print("无解")
得到解为073c8c07-4f57-4b
sm4加密的向量由hello库获取
这里直接调试获得iv
再cyberchef求解即可
[Round 2] ezwasm
flag: YLCTF{243cae43-7f92-426f-8106-e13ff5cbd654}
用了wasm2c再编译成.o文件也没分析出来什么
GZCTF_FLAG都没有被引用
直接连靶机,给了一个数组0x66,0x73,0x6a,0x61,0x6d,0x7b,0x32,0x34,0x33,0x4a,0x48,0x4c,0x34,0x33,0x2d,0x37,0x4d,0x39,0x32,0x2d,0x34,0x32,0x36,0x4d,0x2d,0x38,0x31,0x30,0x36,0x2d,0x4c,0x31,0x33,0x4d,0x4d,0x35,0x4a,0x49,0x4b,0x36,0x35,0x34,0x7d
转成字符串就是fsjam{243JHL43-7M92-426M-8106-L13MM5JIK654}
这肯定是凯撒密码
再把大小写转换一下就行
enc = b"ylctf{243CAE43-7F92-426F-8106-E13FF5CBD654}"
flag = ""
for i in range(len(enc)):
if 122 >= enc[i] >= 97:
tmp = enc[i] -32
elif 65 <= enc[i] <= 90:
tmp = enc[i] +32
else:
tmp = enc[i]
flag +=chr(tmp)
print(flag)
后来发现可以使用鸡爪来反编译wasm,需要下载一个插件->https://github.com/nneonneo/ghidra-wasm-plugin/
undefined4 unnamed_function_7(void)
{
int local_20 [4];
int local_10;
int local_c;
int local_8;
undefined4 local_4;
local_4 = 0;
local_8 = unnamed_function_14(s_GZCTF_FLAG_ram_00000429);
local_c = unnamed_function_20(local_8);
if ((local_c != 0) && (*(char *)(local_8 + local_c + -1) == '\n')) {
*(undefined *)(local_8 + local_c + -1) = 0;
}
for (local_10 = 0; *(char *)(local_8 + local_10) != '\0'; local_10 = local_10 + 1) {
if ((*(char *)(local_8 + local_10) < 'A') || ('Z' < *(char *)(local_8 + local_10))) {
if ((*(char *)(local_8 + local_10) < 'a') || ('z' < *(char *)(local_8 + local_10))) {
*(undefined *)(local_8 + local_10) = *(undefined *)(local_8 + local_10);
}
else {
*(char *)(local_8 + local_10) = *(char *)(local_8 + local_10) + -0x20;
*(char *)(local_8 + local_10) = (char)((*(char *)(local_8 + local_10) + -0x3a) % 0x1a) + ' A'
;
}
}
else {
*(char *)(local_8 + local_10) = *(char *)(local_8 + local_10) + ' ';
*(char *)(local_8 + local_10) = (char)((*(char *)(local_8 + local_10) + -0x5a) % 0x1a) + 'a' ;
}
}
for (local_10 = 0; *(char *)(local_8 + local_10) != '\0'; local_10 = local_10 + 1) {
local_20[0] = (int)*(char *)(local_8 + local_10);
unnamed_function_15(0x43a,local_20);
}
return 0;
}
虽然很丑,但代码逻辑很简单,大小写置换且凯撒偏移7位.
2024-源鲁杯 [Round3]
[Round 3] ezmaze
Flag:YLCTF{efac19a75e413ad6680adec92504b654}
先提取迷宫
地图11行10列
++
*+
+++*
+++
F+**
++++**
+++
++
++*+
+++++++*
需要注意不是一次走一个,而是往一个方向走直到碰壁
把输入md5加密就得到flag
CASE
Flag:YLCTF{835515af-3042-4735-85ed-b56e34080cc6}
以时间戳为种子产生随机数
将密文先rot13再用随机数进行加密
脚本爆破时间戳就行,注意linux和windows下产生的随机数不同
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int enc[] = {0xd5,0x6f,0x36,0x2c,0x4f,0xe2,0x89,0x97,0xbb,0x1b,0xd4,0x4f,0x7f,0x21,0x1d,0xa9,0xd4,0xc5,0xdc,0x3e,0x12,0x7c,0xd5,0x7b,0xd1,0x8,0xa1,0x92,0x23,0xf9,0x23,0x5e,0xbd,0xc0,0xe5,0x13,0x7c,0x31,0xfb,0x2b,0x47,0x87,0xa8};
int seed;
int main(){
int i;
int tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
for(i = 1726539345;; i++){
srand(i);
tmp1 = enc[0] ^ (rand() % 255);
tmp2 = enc[1] ^ (rand() % 255);
tmp3 = enc[2] ^ (rand() % 255);
if(tmp1 == 0x4C) if (tmp2 == 0x59) if(tmp3 == 0x50){
printf("%d", i);
seed = i;
break;}
}
srand(seed);
for(int j = 0; j < 43; j++) printf("%x,", enc[j] ^ (rand() % 255));
}