实验吧 catalyst-system catalyst 反汇编

链接:http://www.shiyanbar.com/ctf/2004

下面是手动反汇编的源码,具体内容注释里已说明:

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

// arg_int_i must be 8 or 12
void judge(int arg_int_i)
{
    int result; // rax

    if (4 * (arg_int_i >> 2) != arg_int_i || 4 * (arg_int_i >> 4) == arg_int_i >> 2 || (!result) || arg_int_i >> 4)
    {
        puts("invalid username or password");
        exit(0);
    }
}

void judge_username_length(char *p_char_username)
{
    int i; // [rsp+1Ch] [rbp-4h]

    for (i = 0; i <= 49 && p_char_username[i]; ++i)
    {
    }
    judge(i);
}

// so username_length must be 12
void judge_username(unsigned int *p_char_username)
{
    long long username8_11; // [rsp+10h] [rbp-20h]
    long long username4_7;  // [rsp+18h] [rbp-18h]
    long long username0_3;  // [rsp+20h] [rbp-10h]

    username0_3 = *p_char_username;
    username4_7 = p_char_username[1];
    username8_11 = p_char_username[2];

    // username0_3 - username4_7 + username8_11 == 1550207830
    // username4_7 + 3 * (username8_11 + username0_3) == 12465522610LL
    // username8_11 * username4_7 == 3651346623716053780LL
    // 这里可以自己解方程,我个人比较懒,用Python来计算
    /*
    #!/usr/bin/python3
    from sympy import *
    username0_3 = Symbol('username0_3')
    username4_7 = Symbol('username4_7')
    username8_11 = Symbol('username8_11')

    print(solve(
        [
            username0_3 - username4_7 + username8_11 - 1550207830,
            username4_7 + 3 * (username8_11 + username0_3) - 12465522610,
            username8_11 * username4_7 - 3651346623716053780
        ],
        [username0_3, username4_7, username8_11]
    ))
    */
    // 结果:[(1635017059, 1953724780, 1868915551)]
    // 也就是:0x61746163, 0x7473796c, 0x6f65635f
    // 所以username 为 catalyst_ceo ,后面这个要做随机种子
    if (username0_3 - username4_7 + username8_11 != 1550207830 || username4_7 + 3 * (username8_11 + username0_3) != 12465522610LL || (username8_11 * username4_7 != 3651346623716053780LL))
    {
        puts("invalid username or password");
        exit(0);
    }
}

// 不可以为大写字母
void judge_username_2(char *p_char_username)
{
    int i; // [rsp+1Ch] [rbp-4h]

    for (i = 0; p_char_username[i] != '\0'; ++i)
    {
        // 不可以为大写字母
        if ((p_char_username[i] <= 96 || p_char_username[i] > 122) && p_char_username[i] != 95)
        {
            puts("invalid username or password");
            exit(0);
        }
    }
}

void judge_password(int *p_int_username, int *p_int_password)
{
    int i; // [rsp+2Ch] [rbp-14h]

    char *p_char_password = (char *)p_int_password;

    for (i = 0; p_char_password[i]; ++i)
    {
        // 对密码进行过滤
        // 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
        if ((p_char_password[i] <= 96 || p_char_password[i] > 122) && (p_char_password[i] <= 64 || p_char_password[i] > 90) && (p_char_password[i] <= 47 || p_char_password[i] > 57))
        {
            puts("invalid username or password");
            exit(0);
        }
    }
    srand(p_int_username[1] + p_int_username[0] + p_int_username[2]);
    //   下面是十次随机数值:
    // 0x00684749
    // 0x673CE537
    // 0x7B4505E7
    // 0x70A0B262
    // 0x33D5253C
    // 0x515A7675
    // 0x596D7D5D
    // 0x7CD29049
    // 0x59E72DB6
    // 0x4654600D

    // 下面是批量解密后的结果
    // 0x56534C73
    // sLSV
    // 0x76345170
    // pQ4v
    // 0x4763334B
    // K3cG
    // 0x38577957
    // WyW8
    // 0x5A694136
    // 6AiZ
    // 0x77676768
    // hggw
    // 0x6A42484C
    // LHBj
    // 0x4339786D
    // mx9C
    // 0x56707352
    // RspV
    // 0x6A676747
    // Gggj

    // 所以密码为: sLSVpQ4vK3cGWyW86AiZhggwLHBjmx9CRspVGggj

    if (p_int_password[0] - rand() != 1441465642)
    {
        puts("invalid username or password");
        exit(0);
    }

    if (p_int_password[1] - rand() != 251096121)
    {
        puts("invalid username or password");
        exit(0);
    }

    if (p_int_password[2] - rand() != -870437532)
    {
        puts("invalid username or password");
        exit(0);
    }

    if (p_int_password[3] - rand() != -944322827)
    {
        puts("invalid username or password");
        exit(0);
    }

    if (p_int_password[4] - rand() != 647240698)
    {
        puts("invalid username or password");
        exit(0);
    }

    if (p_int_password[5] - rand() != 638382323)
    {
        puts("invalid username or password");
        exit(0);
    }

    if (p_int_password[6] - rand() != 282381039)
    {
        puts("invalid username or password");
        exit(0);
    }

    if (p_int_password[7] - rand() != -966334428)
    {
        puts("invalid username or password");
        exit(0);
    }

    if (p_int_password[8] - rand() != -58112612)
    {
        puts("invalid username or password");
        exit(0);
    }

    if (p_int_password[9] - rand() != 605226810)
    {
        puts("invalid username or password");
        exit(0);
    }
}

void flag_print(char *p_char_username, char *p_char_password)
{
    int i; // [rsp+1Ch] [rbp-14h]
    char str[] = {0x42, 0x13, 0x27, 0x62, 0x41, 0x35, 0x6B, 0x0F, 0x7B, 0x46, 0x3C, 0x3E, 0x67, 0x0C, 0x08, 0x59, 0x44, 0x72, 0x36, 0x05, 0x0F, 0x15, 0x54, 0x43, 0x38, 0x17, 0x1D, 0x18, 0x08, 0x0E, 0x5C, 0x31, 0x21, 0x16, 0x02, 0x09, 0x18, 0x14, 0x54, 0x59};

    printf("your flag is: ALEXCTF{");
    for (i = 0; i < strlen(p_char_password); ++i)
    {
        putchar(str[i] ^ p_char_password[i]);
    }
    puts("}");
}

int main()
{
    char username[128] = {0};
    char password[128] = {0};
    // char *username="catalyst_ceo";
    // char *password="sLSVpQ4vK3cGWyW86AiZhggwLHBjmx9CRspVGggj";

    printf("Username: ");
    scanf("%s", username);
    printf("Password: ");
    scanf("%s", password);
    printf("Logging in");

    judge_username_length(username);
    judge_username((int *)username);
    judge_username_2(username);
    judge_password((int *)username, (int *)password);
    flag_print(username, password);
}