GACTF easyre复现

简单说一下函数逻辑:
 
首先输入 38 char 型数据过后进行三层加密 encode_one, encode_two, encode_three,然后对比在程序里面存放的数据,如果相同则通过,否则就不通过
 
encode_one:base64编码(啊...这里源码看了好久...算是看到第二层输出并且看了个源码大概然后蒙出来的,换个表就容易懵...base64源码之前看的有点囫囵吞枣,单看源码还有点懵,主要是移位感觉没太学好的样子,最近再仔细学一下写篇博客)
 
encode_two:每13个一组,换位置 ——1-3 2-1 3-4 4-2 
 
encode_three:偏移量为3的凯撒(ps. 这里数字也位移)
 
从下到上进行逆向,写个脚本:
(ps.这里字符串长度从52变成38主要是因为base64的缘故)
 

exp

#include <stdio.h> 
#include <string.h> 
const char ciphertext[] = {"EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG"};
const unsigned char base64_suffix_map[256] = { 
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 };
char cmove_bits(unsigned char src, unsigned lnum, unsigned rnum)
{
	src <<= lnum;
	src >>= rnum; 
	return src; 
}

int decode_one(const char *indata, int inlen, char *outdata, int *outlen) 
{
	int ret = 0; 
	if(indata == NULL || inlen <= 0 || outdata == NULL || outlen == NULL) 
	{
		return ret = -1; 
	}
	if(inlen % 4 != 0) 
	{
		return ret = -2; 
	}
	
	int t = 0, x = 0, y = 0, i = 0; 
	unsigned char c = 0; 
	int g = 3; 
	while(indata[x] != 0) 
	{
		c = base64_suffix_map[indata[x++]]; 
		if(c == 255) 
			return -1; 
		if(c == 253) 
			continue; 
		if(c == 254) 
		{
			c = 0; 
			g--; 
		}
		t = (t << 6) | c; 
		if(++y == 4) 
		{
			outdata[i++] = (unsigned char)((t >> 16) & 0xff); 
			if(g > 1) 
				outdata[i++] = (unsigned char)((t >> 8) & 0xff); 
			if(g > 2) 
				outdata[i++] = (unsigned char)(t & 0xff); 
				
			y = t = 0; 
		}
	}
	
	if(outlen != NULL) 
	{
		*outlen = i; 
	}
	
	return ret; 
}

int decode_two(const char *indata, int inlen, char *outdata, int *outlen) 
{
	int ret = 0; 
	if(indata == NULL || inlen == 0) 
	{
		return ret = -1; 
	}
	
	/*
	1-1 1-3 
	2-2 2-1 
	3-3 3-4 
	4-4 4-2 
	*/
	
	char *p = outdata; 
	strncpy(p+26,indata,13); 
	strncpy(p,indata+13,13); 
	strncpy(p+39,indata+26,13); 
	strncpy(p+13,indata+39,13); 
	return ret; 
}

int decode_three(const char *indata, int inlen, char *outdata, int *outlen) 
{
	int ret = 0; 
	if(indata == NULL || inlen == 0) 
	{
		return ret = -1; 
	}
	char *p = outdata; 
	for(int i = 0; i < inlen; i ++) 
	{
		char c = *indata; 
		if(c >= 'A' && c <= 'Z') 
			*p = ((c - 'A') + 23) % 26 + 'A'; 
		else if(c >= 'a' && c <= 'z') 
			*p = ((c - 'a') + 23) % 26 + 'a'; 
		else if(c >= '0' && c <= '9') 
			*p = ((c - '0') + 7) % 10 + '0'; 
		else 
			*p = c; 
		
		p ++; 
		indata ++; 
	}
	return ret; 
}

int main(int argc, char** argv) 
{
	char flag1[52]; 
	char flag2[52]; 
	char flag[38]; 
	int L; 
	decode_three(ciphertext, strlen(ciphertext), flag1, &L); 
	decode_two(flag1, strlen(flag1), flag2, &L); 
	decode_one(flag2, strlen(flag2), flag, &L); 
	printf(flag1); 
	printf("\n"); 
	printf(flag2); 
	printf("\n");
	printf(flag); 
	return 0;
} 

最后输出:

 
我直接把第二行输出base64解码得到的flag,看源码能力还是太菜了qaq
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值