打开之后得到三个同名文件,分别是.js .wasm .html
.html用浏览器打开,发现让我们输入flag。由于.js在我电脑里好像打不开,没配置相关环境,所以选择通过.wasm进行逆向。
.wasm逆向的一般套路,用wasm2c将wasm转化成c伪代码,然后再用gcc -c命令编译但是不链接得到.o文件。注意编译时缺少什么文件就在wasm2c文件夹中复制过去即可。
.o文件用ida打开,然后f15函数得到加密函数
首先我们看得出来是个XTEA加密,并且key为0(即v44的值,在加密过程之前会初始化,可以看到明显的置零语句)。
然后这样的加密函数会进行4次,每次从输入的flag中依次取8位进行XTEA加密。
于是我们就开始寻找加密后的数据,继续分析,在f15下面可以找到一片赋值操作
是用加密后的每一位分别异或一个值,然后取低8位,最后和前面一次算出来的值迭代相加。
我们可以假设所有的值最后算出来都等于0,然后就可以反推出加密得到的数据即为异或的数据
0x21,0x04,0x24,0x9a,
0xe1,0x41,0xc1,0xa4,//part1
0x2d,0x00,0x63,0x6d,
0x1c,0x8b,0x16,0x9b,//part2
0x9e,0x6d,0xb2,0x05,
0x6c,0x5d,0x33,0x3B,//part3
0x88,0x91,0xd5,0x60,
0x17,0xfe,0x99,0x2e,//part4
0x34,0x62,0x66,0x34,0x61,0x7d//未加密的部分
找到了一个比较靠谱的XTEA加密的轮子,然后跑一下即可
#include
#include
/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;
for (i=0; i < num_rounds; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
}
v[0]=v0; v[1]=v1;
}
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
for (i=0; i < num_rounds; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
}
v[0]=v0; v[1]=v1;
}
int main(){
unsigned int key[4]={0,0,0,0};
unsigned char data[]={
0x21,0x04,0x24,0x9a,
0xe1,0x41,0xc1,0xa4,
0x2d,0x00,0x63,0x6d,
0x1c,0x8b,0x16,0x9b,
0x9e,0x6d,0xb2,0x05,
0x6c,0x5d,0x33,0x3B,
0x88,0x91,0xd5,0x60,
0x17,0xfe,0x99,0x2e,
0x34,0x62,0x66,0x34,0x61,0x7d
};
for(int i=0;i<4;i++)
decipher(32,(unsigned int*)(data+i*8),key);
printf("%s",data);
}