[羊城杯 2020]easyre

下载附件,studyPE查壳,发现无壳

拖进IDA,打开就发现是flag所在的框图,F5查看伪代码

发现解题重点是encode_one,encode_two,encode_three这三个函数,点击函数跟进查看函数

encode_one如下

发现数组alphabet疑似base64编码表

alphabet={ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/A“}

发现cmove_bits为一个函数,跟进调查

综上可知:encode_one为base64加密字符串

看encode_two

易得encode_two为打乱字符串

看encode_three

仔细研究发现,encode_three是偏移三位的凯撒密码

综上所述:Str2是储存flag的字符串数组,而经过三个函数的变化后得到alphabet这个字符串数组,把上面的三个函数和主函数整合得到c语言代码如下:

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

char caesar(char little_c, int offset) {
    char c = little_c;
    if (islower(c)) {
        c = (c - 'a' + offset) % 26 + 'a';
        return c;
    }
    else if (isupper(c)) {
        c = (c - 'A' + offset) % 26 + 'A';
        return c;
    }
    else {
        return c;
    }
}

void solve1() {
    char str[] = "EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG";
    char result[100] = {0};
    int i;
    for (i = 0; i < strlen(str); i++) {
        char c = str[i];
        if (isalpha(c)) {
            result[i] = caesar(c, -3);
        }
        else if (isdigit(c)) {
            result[i] = ((c - '0') - 3 + 10) % 10 + '0';
        }
        else {
            result[i] = c;
        }
    }
    printf("solve1: %s\n", result);
}

void solve2() {
    char str[] = "BjYjM2Mjk4NzMR1dIVHs2NzJjY0MTEzM2VhMn0=zQ3NzhhMzhlOD";
    char str2[100] = {0};
    memset(str2, ' ', 100);
    strncpy(str2 + 26, str + 13, 13);
    strncpy(str2, str, 13);
    strncpy(str2 + 39, str + 26, 13);
    strncpy(str2 + 52, str + 39, strlen(str) - 39);
    printf("solve2: %s\n", str2);
}

void decode(char* code, char* decoded) {
    char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    int i, j;
    int len = strlen(code);
    int padding = 0;
    for (i = len - 1; i >= 0; i--) {
        if (code[i] == '=') {
            padding++;
        }
        else {
            break;
        }
    }
    len -= padding;
    for (i = 0; i < len; i += 4) {
        int values[4];
        for (j = 0; j < 4; j++) {
            char c = code[i + j];
            for (int k = 0; k < 64; k++) {
                if (table[k] == c) {
                    values[j] = k;
                    break;
                }
            }
        }
        decoded[i / 4 * 3] = (values[0] << 2) | (values[1] >> 4);
        if (values[2] < 64) {
            decoded[i / 4 * 3 + 1] = (values[1] << 4) | (values[2] >> 2);
        }
        if (values[3] < 64) {
            decoded[i / 4 * 3 + 2] = (values[2] << 6) | values[3];
        }
    }
    decoded[i / 4 * 3] = '\0';
}

void solve3() {
    char str[] = "R1dIVHs2NzJjYzQ3NzhhMzhlODBjYjM2Mjk4NzM0MTEzM2VhMn0=";
    char flag[100] = {0};
    decode(str, flag);
    printf("solve3: %s\n", flag);
}

int main() {
    solve1();
    solve2();
    solve3();
    return 0;
}

最后运行代码得到flag

GWHT{672cc4778a38e80cb362987341133ea2}!

即flag为NSSCTF{672cc4778a38e80cb362987341133ea2}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值