Featured image of post *CTF 2023

*CTF 2023

UKFC 2023 *CTF Writeup

Crypto

ezCrypto

  • 差评
  • 先把 map 爆破出来
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import random
import string
map="8K#Ttr@&5=q;s!^:6?W`-{Ao)ZmyVkPjGJ\\2OfFnI]Uwui4(}|a<$vg0Xb+lzMeQpx,3Y1>CS~7E[_cLdRBD.h%H*\'/9\"N"
characters = string.printable[:-6]
for i in range(0,1000):
    rseed = i
    random.seed(rseed * 2)
    random_sequence = random.sample(characters, len(characters))
    map_string2 = ''.join(random_sequence)
    if map_string2 == map:
        print(i)
        characters = string.printable[:-6]
        random.seed(rseed)
        random_sequence = random.sample(characters, len(characters))
        map_string1 = ''.join(random_sequence)
        random.seed(rseed * 3)
        random_sequence = random.sample(characters, len(characters))
        map_string3 = ''.join(random_sequence)
        print('map_string3=',map_string3)
        print('map_string2=',map_string2)
        print('map_string1=',map_string1)
  • 随便逆逻辑就行了

  • 随便逆出

    • flaglist1 = ‘0)&3F~’
    • flaglist2 = ‘1Dn1F 23m0s 4nl5OtP 7Rc’
  • flag 即为:sixstars{XXX_F1nD_s0m3_XXX_ln_cR7PtO}"

  • 暴力破解,寻找张得好看的:

    • sixstars{TrY_F1nD_s0m3_F4n_ln_cR7PtO}

Web

jwt2struts

  • 一把梭 + 伪造 jwt

  • struct2 一把梭

Misc

MWM

  • AI 模型
  • 提取训练数据
1
2
3
4
5
6
7
8
9
import torch
import pprint
torch.set_printoptions(threshold=torch.inf)
pthfile = r'resnet_mwm_new.pth'
net = torch.load(pthfile,map_location=torch.device('cpu')) 

shu_ju=net.state_dict()
with open('model_state_dict.txt', 'w') as f:
    pprint.pprint(shu_ju, stream=f)
  • 计算 flag 开头的值

  • 定位数据

  • 得到 flag
1
2
3
4
l = [3.8672e-01,4.3359e-01,4.3750e-01,4.7266e-01,3.7109e-01,4.4531e-01,4.1016e-01,4.0234e-01,4.0625e-01,4.5312e-01,3.7109e-01,3.7891e-01,4.5312e-01,3.7109e-01,2.8906e-01,3.2031e-01,4.4531e-01,3.1250e-01,2.6172e-01,2.2266e-01,1.9141e-01,2.8516e-01,2.5391e-01,2.7734e-01,3.7109e-01,1.9531e-01,1.8750e-01,1.9531e-01,1.9531e-01,3.7109e-01,1.9531e-01,1.8750e-01,1.9531e-01,1.9922e-01,3.7109e-01,3.7891e-01,4.2188e-01,4.2188e-01,3.7109e-01,4.4531e-01,4.1016e-01,4.0234e-01,4.0625e-01,4.5312e-01,4.4922e-01,3.7109e-01,4.4531e-01,3.9453e-01,4.4922e-01,3.9453e-01,4.4531e-01,4.6094e-01,3.9453e-01,3.9062e-01]
for i in l:
    print(chr(round(i * 256)),end='')
## copy_right_at_JRrPC91IAG_2022_2023_all_rights_reserved

snippingTools

old language

  • 龙语:

https://zh.wikipedia.org/zh-hans/%E5%A4%9A%E7%93%A6%E7%A5%96%E7%88%BE%E8%AA%9E

dead game

  • 通关即可

Reverse

ez_code

  • powshell 脚本,第一眼我还以为 dos 呢
  • ise 把明文代码搞出来,要不看不懂

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
class chiper():
    def __init__(self):
        self.d = 0x87654321
        k0 = 0x67452301
        k1 = 0xefcdab89
        k2 = 0x98badcfe
        k3 = 0x10325476
        self.k = [k0, k1, k2, k3]

    def e(self, n, v):
        from ctypes import c_uint32

        def MX(z, y, total, key, p, e):
            temp1 = (z.value >> 6 ^ y.value << 4) + (y.value >> 2 ^ z.value << 5)
            temp2 = (total.value ^ y.value) + (key[(p & 3) ^ e.value] ^ z.value)
            return c_uint32(temp1 ^ temp2)
        key = self.k
        delta = self.d
        rounds = 6 + 52//n
        total = c_uint32(0)
        z = c_uint32(v[n-1])
        e = c_uint32(0)

        while rounds > 0:
            total.value += delta
            e.value = (total.value >> 2) & 3
            for p in range(n-1):
                y = c_uint32(v[p+1])
                v[p] = c_uint32(v[p] + MX(z, y, total, key, p, e).value).value
                z.value = v[p]
            y = c_uint32(v[0])
            v[n-1] = c_uint32(v[n-1] + MX(z, y, total,key, n-1, e).value).value
            z.value = v[n-1]
            rounds -= 1
        return v

    def bytes2ints(self,cs:bytes)->list:
        new_length=len(cs)+(8-len(cs)%8)%8
        barray=cs.ljust(new_length,b'\x00')
        i=0
        v=[]
        while i < new_length:
            v0 = int.from_bytes(barray[i:i+4], 'little')
            v1 = int.from_bytes(barray[i+4:i+8], 'little')
            v.append(v0)
            v.append(v1)
            i += 8
        return v

def check(instr:str,checklist:list)->int:
    length=len(instr)
    if length%8:
        print("Incorrect format.")
        exit(1)
    c=chiper()
    v = c.bytes2ints(instr.encode())
    output=list(c.e(len(v),v))
    i=0
    while(i<len(checklist)):
        if i<len(output) and output[i]==checklist[i]:
            i+=1
        else:
            break
    if i==len(checklist):
        return 1
    return 0

if __name__=="__main__":
    ans=[1374278842, 2136006540, 4191056815, 3248881376]
    ## generateRes()
    flag=input('Please input flag:')
    res=check(flag,ans)
    if res:
        print("Congratulations, you've got the flag!")
        print("Flag is *ctf{your_input}!")
        exit(0)
    else:
        print('Nope,try again!')
  • xxtea
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
impyport struct
from ctypes import c_uint32

DELTA = 0x87654321

def decrypt(v, n, k):
    rounds = 6 + int(52 / n)
    sum = c_uint32(rounds * DELTA)
    y = v[0].value
    while rounds > 0:
        e = (sum.value >> 2) & 3
        p = n - 1
        while p > 0:
            z = v[p - 1].value
            v[p].value -= (((z >> 6 ^ y << 4) + (y >> 2 ^ z << 5)) ^ ((sum.value ^ y) + (k[(p & 3) ^ e] ^ z)))
            y = v[p].value
            p -= 1
        z = v[n - 1].value
        v[0].value -= (((z >> 6 ^ y << 4) + (y >> 2 ^ z << 5)) ^ ((sum.value ^ y) + (k[(p & 3) ^ e] ^ z)))
        y = v[0].value
        sum.value -= DELTA
        rounds -= 1


def test1():
    k0 = 0x67452301
    k1 = 0xefcdab89
    k2 = 0x98badcfe
    k3 = 0x10325476
    k = [k0, k1, k2, k3]
    v = [c_uint32(1374278842),c_uint32(2136006540),c_uint32(4191056815),c_uint32(3248881376)]
    decrypt(v, len(v), k)
    print('%X %X %X %X' % (v[0].value, v[1].value,v[2].value,v[3].value))

test1()

s = [0x61,0x55,0x4F,0x79,0x30,0x67,0x33,0x72,0x74,0x40,0x44,0x6F,0x48,0x35,0x77,0x50]
for i in range(0,len(s),4):
    print(chr(s[i+3]),end='')
    print(chr(s[i+2]),end='')
    print(chr(s[i+1]),end='')
    print(chr(s[i]),end='')

flagfile

010 打开,观察到 flag 格式以及匹配的大概规则

https://blog.csdn.net/qq_35677314/article/details/120687202?spm=1001.2014.3001.5501

用每一模块 leshort 两个字节异或,可以得到一串数字和一串字符串,按照数字重新排列字符串

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
char aa[] = "f_o_a__lhy_s_y^^hete_ug___goo_t_";
        char bb[] = { 25, 8, 18, 20, 27, 31, 30, 26, 7, 13, 5, 11, 16, 9, 34, 32, 22, 10, 19, 23, 24, 15, 28, 36, 12, 33, 17, 6, 14, 35, 21, 29 };
        char flag[40];
        for (int i = 0; i < 32; i++)
        {
                flag[bb[i]] = aa[i];

        }
        for (int i = 5; i < 40; i++)
        {
                printf("%c", flag[i]);
        }

GoGpt

go 语言,用工具恢复符号表

逻辑为:flag 与 TcR@3t_3hp_5_G1HTcR@3t_3hp_5_G1H 异或,结果 base64 之后是 fiAGBkgXN3McFy9hAHRfCwYaIjQCRDFsXC8ZYBFmEDU=

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include <iostream>
using namespace std;
char aa[] = "TcR@3t_3hp_5_G1HTcR@3t_3hp_5_G1H";
//char flag[] = "flag{12345678909876543212345678}";
char cc[] = { 126, 32, 6, 6, 72, 23, 55, 115, 28, 23, 47, 97, 0, 116, 95, 11, 6, 26, 34, 52, 2, 68, 49, 108, 92, 47, 25, 96, 17, 102, 16, 53 };
    //fiAGBkgXN3McFy9hAHRfCwYaIjQCRDFsXC8ZYBFmEDU=
int main()
{
        for (int i = 0; i < 32; i++)
        {
                printf("%c",cc[i]^aa[i]);
        }
        return 0;
}
Licensed under CC BY-NC-SA 4.0
使用 Hugo 构建
主题 StackJimmy 设计