比赛太卷了,麻了,wp还没出来,先把能写的写了

你这主函数保真么

能看到主函数前面还有很多函数
2024-08-28T08:50:20.png
显示输入flag判断长度,接着注册tcf_2函数如下,里面与密文进行比较,但是现在并不会执行,因为atexit()函数用于注册在程序正常终止时调用的函数,也就是说这些注册的函数会在主函数正常结束后进行调用
2024-08-28T08:50:35.png
test2函数进行rot13加密,也很明显,没有去符号,接着下面又注册了一个函数tcf_3,同样的也是主函数结束后调用

接着往下调就进去主函数,主函数没有什么加密过程,主函数过了之后就来到了之前返回的注册函数tcf_3
2024-08-28T08:50:51.png
2024-08-28T08:50:57.png
encrypt函数是一维度DCT加密,加密之后就来到了check部分,比较check和in数组的误差范围,这里check是正确flag的密文,in数组是输入flag的密文,所以解题思路就是先解一维度DCT ,再进行rot13解密即可
2024-08-28T08:51:10.png
2024-08-28T08:51:17.png
解密脚本:


import numpy as np
from scipy.fftpack import idct

# 准备输入的离散余弦变换系数矩阵
YY = np.array(
    [513.355, -37.7986, 8.7316, -10.7832, -1.3097, -20.5779, 6.98641, -29.2989, 15.9422, 21.4138, 29.4754,
-2.77161, -6.58794, -4.22332, -7.20771, 8.83506, -4.38138, -19.3898, 18.3453, 6.88259, -14.7652, 14.6102,
24.7414, -11.6222, -9.754759999999999, 12.2424, 13.4343, -34.9307, -35.735, -20.0848, 39.689, 21.879,
26.8296])
XX = idct(YY, norm='ortho')
# 打印还原后的图像块
for data_point in XX:
    temp = int(round(data_point))
    print(chr(temp), end='')

得到结果解rot13
2024-08-28T08:51:37.png
2024-08-28T08:51:45.png

docCrack

docm文件,打开后运行一下宏,有一个flag的check,随便输入测试一下
2024-08-28T08:51:57.png
尝试修改宏发现要密码,退出时候会释放一个tmp文件按,(但是不知道怎么回事,有的没释放出来

可以用沙箱分析一下,能够发现用到了base64加密,解密2次能得到一个exe文件
2024-08-28T08:52:11.png
逻辑还是比较简单的,直接逆

#include <stdio.h>
int main()
{
  unsigned int v9[54];
  v9[0] = 4288;
  v9[1] = 4480;
  v9[2] = 5376;
  v9[3] = 4352;
  v9[4] = 5312;
  v9[5] = 4160;
  v9[6] = 7936;
  v9[7] = 5184;
  v9[8] = 6464;
  v9[9] = 6528;
  v9[10] = 5632;
  v9[11] = 3456;
  v9[12] = 7424;
  v9[13] = 5632;
  v9[14] = 6336;
  v9[15] = 6528;
  v9[16] = 6720;
  v9[17] = 6144;
  v9[18] = 6272;
  v9[19] = 7488;
  v9[20] = 6656;
  v9[21] = 7296;
  v9[22] = 7424;
  v9[23] = 2432;
  v9[24] = 2432;
  v9[25] = 2432;
  v9[26] = 5632;
  v9[27] = 4416;
  v9[28] = 3456;
  v9[29] = 7168;
  v9[30] = 6528;
  v9[31] = 7488;
  v9[32] = 6272;
  v9[33] = 5632;
  v9[34] = 3520;
  v9[35] = 6208;
  v9[36] = 5632;
  v9[37] = 4736;
  v9[38] = 6528;
  v9[39] = 6400;
  v9[40] = 7488;
  v9[41] = 3520;
  v9[42] = 5632;
  v9[43] = 5184;
  v9[44] = 3456;
  v9[45] = 7488;
  v9[46] = 7296;
  v9[47] = 3200;
  v9[48] = 6272;
  v9[49] = 7424;
  v9[50] = 2432;
  v9[51] = 2432;
  v9[52] = 2432;
  v9[53] = 7808;
  for (int i = 0; i < 54; i++)
  {
    v9[i] = v9[i] >> 6;
    printf("%c", v9[i] );
  }
  return 0;
}

得到乱七八糟的东西

CFTDSA|QefX6tXcfibuhrt&&&XE6pfubX7aXJfdu7XQ6ur2bt&&&z`

用厨子解一下就可以了
2024-08-28T08:52:44.png

pic

题目给了两个文件一个是exe,一个是png,但是png文件格式不对,应该是被处理了

是rust写的,7.7ida不太好看很多符号没分析出来,用8.3ida打开比较清晰
2024-08-28T08:54:05.png
前面的反调试要过掉,主要思路就是输入长度为5的key,作为密钥去给图片rc4加密,main_NewCipher 是rc4加密初始化部分,下面再调试只能在汇编窗口去调(不知道为什么没法反编译这部分
2024-08-28T08:54:22.png
程序先给打开的png文件整体异或输入key的key[1],得到结果再存回原来存放png数据的内存中
2024-08-28T08:54:35.png
rc4加密逻辑比较清晰,但是被魔改了一下,多异或了一个0x11

所以,大概思路就是png文件数据异或key[1]->rc4加密(多异或一个0x11),要把输入的key爆出来,感觉难就难在这里,脚本不会写😭 ,试过subproces和直接爆密钥,但是太多可能了,爆不出来

写脚本爆破,只爆前面关键部分,更快一下

"""
RC4加解密算法
Args:
    key (bytes): 密钥,用于初始化RC4算法
    data (bytes): 要加密或解密的数据
Returns:
"""
def RC4(key, data,ch):

    # 初始化S盒
    def KSA(key):
        key_length = len(key)
        S = list(range(256))
        j = 0

        for i in range(256):
            j = (j + S[i] + key[i % key_length]) % 256
            S[i], S[j] = S[j], S[i]

        return S

    # 生成密钥流
    def PRGA(S, length):
        i = 0
        j = 0
        key_stream = []

        for _ in range(length):
            i = (i + 1) % 256
            j = (j + S[i]) % 256
            S[i], S[j] = S[j], S[i]
            key_stream.append(S[(S[i] + S[j]) % 256])

        return key_stream

    S = KSA(key)  # 初始化S盒
    key_stream = PRGA(S, len(data))  # 生成密钥流

    # #打印密钥流内容
    # for i in range(len( key_stream)):
    #     print(hex(key_stream[i]),end=' ')
    #     if (i+1)%10==0 :
    #         print()

    result = bytearray()
    for i in range(len(data)):
        result.append(data[i] ^ key_stream[i]^0x11^ch)  # 异或运算得到加密/解密结果

    return bytes(result)

first_bytes=b'\x85\x43\x72\x78'#原png图片的前几个字节
dest=b'\x89PNG'#正确图片前一个字节
times=0
if __name__ == "__main__":
    key='?????'#key长度是5个字符
    for a in "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-{}":
        for b in "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-{}":
            for c in "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-{}":
                for d in "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-{}":
                    for e in "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-{}":
                        key_try = key.replace('?', a, 1).replace('?', b, 1).replace('?', c, 1).replace('?', d, 1).replace('?', e, 1)
                        key_try_bytes=key_try.encode('utf-8')
                        tmp_bytes=first_bytes
                        result = RC4(key_try_bytes, tmp_bytes,key_try_bytes[1])#只去加密原png的前几个字节,这样大大减少了计算量
                        if result == dest:#最后加密结果等于最后正确png的文件格式
                            print("key:",key_try)
                            exit(0)
                        if times%100000==0:
                            print("times:",times)
                        times+=1

2024-08-28T08:54:55.png
爆出来key等于0173d
再去运行一下就能得到正确图片
2024-08-28T08:55:17.png