强网杯_JustRe

发布于 2019-05-26  926 次阅读


JustRe

JustRe.7z

思路

程序读入了26位 十六进制数

其中前8为送入eax寄存器

把eax扩展为了16个字节 01234567012345670123456701234567 记作 input

后两位(假设为ab) 填充为了ababababababababab.....ababab,记作 ab

从内存中取16个字节,记作 key1

还从内存取了16个字节,形如00000003000000020000000100000000 记作 key2

key = (ab + key1)^ (input + key2) 并且将结果存在原来key1的位置

依次循环

注意key2第二次 key2' += key2 ,而不是直接从内存取

接下来的循环 循环了八次,是对从0x405058的32个字节进行处理,每次四个字节

同样

input 01 23 45 67

key 从内存中取四个字节

ab 用89位填充的四个字节

esi 从0x10 开始 一直到0x18

key = (ab + key) ^ (input + esi) 并且将结果存在key的位置

然后 0x405018 和 0x404148的 0x60个字节进行比较,要相等

事实证明,后面这些运算,对于解出input的帮助并不大,我们只需要解出一组input,并且判断它们是否是四个分块都相等即可

dec1 = 0x4364162A031410D2EF95C26D80B899BD
enc1 = 0x405004A100000278EC81F0E483EC8B55
key1 = 0x00000003000000020000000100000000

def FILL(a):  #用八九位这一个字节去填充为16字节
    return a * 0x01010101010101010101010101010101

def DIVIDE(a):
    for i in range(4):
        res.append((a << (32 * i) & 0xffffffffffffffffffffffffffffffff) >> (32 * 3))
    return res

def ADD(a, b):
    a = DIVIDE(a)
    b = DIVIDE(b)
    res = 0
    for i in range(4):
        res += ((a[i]+b[i]) & 0xffffffff) << (32 * (3-i))
    return res

def CALC(dec,enc,key,t):
    return (ADD(FILL(t),dec) ^ enc) - key

for t in range(100):#枚举第八第九位的所有情况
    res = CALC(dec1,enc1,key1,t)
    if(inpu & 0xffffffff == res >> (3 * 32)):
        print(hex(CALC(dec1,enc1,key1,t) >> (3*32)),hex(t))

前十位 1324229810

用来过验证的passwd:13242298100123456789abcdef

后面这个加密函数是好像藏在data区里面的,看起来应该是一个加密算法,谷歌了几个比较关键的常数,发现是个3des加密

https://www.cnblogs.com/one--way/archive/2016/07/05/5643771.html

密钥应该是这个 AFSAFCEDYCXCXACNDFKDCQXC

再配上解密后的密文(实际上只用到了16个字节,剩下的8个字节可要可不要)

注意:大端序,不能直接复制,要先把顺序颠倒一下

轮子不太完整,修改了一下,以下是main函数中修改过的内容

    char k[32] = "AFSAFCEDYCXCXACNDFKDCQXC";

    char data[128] = {
        0x50,0x7C,0xA9,0xE6,
        0x87,0x09,0xCE,0xFA,
        0x20,0xD5,0x0D,0xCF,
        0x90,0xBB,0x97,0x6C,0
        };  /* 原始明文 */
    nlen = strlen(data);

.....

for (i = 0; i < len; i += 8) {
        DES_ecb3_encrypt((const_DES_cblock *)(src + i), (DES_cblock *)(out + i), &ks1, &ks2, &ks3, DES_DECRYPT);
    }

    printf("encrypted Hex:");
    for (i = 0; i < len; i++) {
        printf("%02X" , *(out + i));
    }
    printf("\n");

    printf("encrypted Bin:");
    for (i = 0; i < len; i++) {
        printf("%c", *(out + i));
    }
    printf("\n");

CTFer|NOIPer|CSGO|摸鱼|菜鸡