2023—VNCTF-re-PZGalaxy

二木 王者

PZGalaxy

这道题是用js写的代码

用浏览器打开 开发者工具查看源码

Untitled

![Untitled 3](/Untitled 3.png)

源码很有特点,就是进行rc4加密。

![Untitled 2](/Untitled 2.png)

这里分析一下我们就可以知道,data和enc都传入了Leaf中进行加密,我们就可以推测出data,就是进行加密的密钥。

后面的一行代码,分别是判断flag前面四个字符,和data前面的四个字符,并且我们可以知道,data的长度为8.

![Untitled 1](/Untitled 1.png)

知道key的前四个字符,也知道key的前四个字符,自然想到对key进行爆破。

#include <stdio.h>
#include <string.h>
#include <math.h>

//将数字转换为字符串
char *ccc(int a, char key[])
{

    int i, b = 0, j, x = 1, y = 0;

    for (i = 7; i > -1; i--)
    {
        x = 1;
        for (j = 0; j < i; j++)
            x *= 10;

        b = a / x;

        key[y++] = b + '0';
        a %= x;
    }
    return key;
}

//s盒的初始化,生成密钥流
void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len) // 对S盒进行初始化
{
    int i = 0, j = 0;
    char k[256] = {0};
    unsigned char tmp = 0;

    for (i = 0; i < 256; i++)
    {
        s[i] = i;
        k[i] = key[i % Len];
    }

    for (i = 0; i < 256; i++)
    {
        j = (j + s[i] + k[i]) % 256;

        tmp = s[i];
        s[i] = s[j]; // 交换s[i]和s[j]
        s[j] = tmp;
    }
}
//rc4加密
void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len)
{
    int i = 0, j = 0, t = 0;
    unsigned long k = 0;
    unsigned char tmp;

    for (k = 0; k < Len; k++)
    {
        i = (i + 1) % 256;
        j = (j + s[i]) % 256;

        tmp = s[i];
        s[i] = s[j]; // 交换s[x]和s[y]
        s[j] = tmp;

        t = (s[i] + s[j]) % 256;
        Data[k] ^= s[t];
    }
}

//rc4执行函数
char *rc4_run(char pData[], char key[])
{
    unsigned long len = strlen(pData);
    unsigned char s[256] = {0}, s2[256] = {0};
    int i;

    key[8] = '\0';

    rc4_init(s, (unsigned char *)key, 8);

    for (i = 0; i < 256; i++) // 用s2[i]暂时保留经过初始化的s[i],很重要的!!!
    {
        s2[i] = s[i];
    }

    rc4_crypt(s2, (unsigned char *)pData, len);

    return pData;
}

int main()
{
    char *arr, *key;
//注意,最好将不变的数据放入静态数据区,以保障其值
    static char flag[5] = {"flag"};

    char data[8] = {0};
    char pData[512];
    char x[512] = {0xa6, 0x70, 0x3a, 0xdc, 0x92, 0xc3, 0x97, 0xf3, 0x1a, 0xdf, 0x8, 0xd6, 0x41, 0xa0, 0x35, 0x90, 0x7b, 0x6, 0xd4, 0xf7, 0x73, 0x5f, 0x1d, 0x3a, 0x49, 0x4c, 0x43, 0x58, 0xd1, 0xb9, 0x4f, 0x99, 0x85, 0x33, 0xe0, 0x69, 0x7c}; // 密文
    int a = 20230000, i, j;
//遍历后四为可能出现的值,进行爆破
    while (a < 20239999)
    {

        j = 0;

        for (i = 0; i < 512; i++)
            pData[i] = x[i];

        arr = NULL;
        key = NULL;

        key = ccc(a, data);

        arr = rc4_run(pData, key);

//寻找满足条件的,数据
        for (i = 0; i < 4; i++)
        {
            if (arr[i] != flag[i])
            {
                break;
            }
        }
        if (i == 4)
        {
            break;
        }

        rc4_run(pData, key);

        a++;
    }
    printf("%s\n", arr);
    return 0;
}

解出flag:flag{HitYourSoulAndSeeYouInTheGalaxy}

 评论
目录