简单说一下函数逻辑:
首先输入
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