源鲁杯2024 RE

官方wp:

2024YLCTF WP RE篇​​​​​​

网址:

2024“源鲁杯”高校网络安全技能大赛 - YL::CTF

xor

64位有壳

nc获得数据

写脚本

#include<stdio.h>
#include<string.h>
int main()
{
	int i,n;
	char v9[]={0x45,0x50,0x5f,0x48,0x5a,0x67,0x2a,0x2c,0x2f,0x24,0x29,0x79,0x2c,0x7a,0x31,0x2f,0x25,0x2a,0x29,0x31,0x28,0x2b,0x78,0x2e,0x31,0x25,0x2c,0x7a,0x2d,0x31,0x7a,0x2b,0x7a,0x78,0x78,0x2b,0x7d,0x28,0x7a,0x2a,0x7f,0x78,0x61,0x1c};
  for ( i = 0; i <= 43; i++ )
  {
    v9[i]=v9[i]^0x1C;
    printf("%c",v9[i]);
  }
	//YLCTF{60385e0f-3965-47d2-90f1-f7fdd7a4f6cd}
	
	return 0;
} 

xorplus

RC4init有一个加1300的魔改,但是初始化不需要逆向

crypt函数这里有一个魔改,逆向进行-20的操作,这里注意逆向的对象。


#include<stdio.h>
#include<string.h>
typedef unsigned longULONG;

/*初始化函数*/
void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
{
    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]+1300) % 256;
        tmp = s[i];
        s[i] = s[j]; // 交换s[i]和s[j]
        s[j] = tmp;
    }
}

/*加解密*/
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]^(Data[k]-20);
    }
}

int main()
{
    unsigned char s[256] = { 0 }, s2[256] = { 0 }; // S-box
    char key[256] = {"welcometoylctf"};
    char pData[] = {0x91,0x86,0x1b,0x2d,0x9e,0x6f,0x58,0x5d,0x77,0xea,0xef,0xa1,0x1,0x42,0x22,0x14,0x3a,0xf1,0x32,0x2d,0x80,0x2b,0x78,0x15,0x6c,0x76,0x4c,0x49,0x7f,0x26,0xb6,0x9a,0x38,0x4a,0x32,0xd2,0x7,0x75,0x5b,0xca,0xb6,0x88,0xa6};

    unsigned long len = strlen(pData);
    int i;

    printf("pData=%s\n", pData);
    printf("key=%s,length=%d\n\n", key, strlen(key));

    rc4_init(s, (unsigned char*)key, strlen(key)); // 已经完成了初始化
    printf("\n\n");
    for (i = 0; i < 256; i++) // 用s2[i]暂时保留经过初始化的s[i],很重要的!!!
    {
        s2[i] = s[i];
    }

    //可以看到,加解密函数都是相同的
    printf("已经加密,现在解密:\n\n");
    rc4_crypt(s2, (unsigned char*)pData, len); // 解密
    printf("pData=%s\n\n", pData);
    //YLCTF{5b58f6eb-097d-4440-a63e-546b26c90acd}
    return 0;
}

ezgo

题目可得,go语言的简单逆向

#include<stdio.h>
#include<string.h>
int main()
{
	char data[]={108,122,116,108,127,65,8,4,8,10,15,117,32,116,110,112,32,116,127,101,125,44,126,
	46,6,119,44,54,104,127,54,53,98,103,111,108,110,109,63,105,106,104,34};

	for(int i=0;i<strlen(data);i++)
	{
		data[i]=(53+i)^data[i];
	}
	puts(data);
	return 0;
}
//YLCTF{385405a6-4e28-4f5bK9cf9-ea718477d576}

math

没得到什么提示,继续向下看

看一下check函数

但我们无法看到num的值,左侧有一个init函数

在结尾下断点,动调

elf文件

结合check函数,发现可能是一个数独,在线解密一下

在线数独求解器

输入求解的数据

calc

使用了源代码级混淆,使得所有的函数和变量都以宏定义的形式给出。并且对源代码进行了不可编译的修改,使得选手无法编译出项目,只能肉眼观察项目,但是这样混淆下来实际上是很难看懂的,或者去修改宏定义,将宏定义名称修改成它本身的定义,再进行替换即可

利用了栈的逆波兰运算

ezvvvvm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值