首先拿到查壳,发现是64位的ELF文件,所以直接IDA打开,找到main函数
- v9是这里解释为int类型,但是可以转为字符,所以为小端存储,既倒着取值;
- 这里效验v12为字符“}”,但是我们的输入在v11,所以输入应该为18位长度的字符串,刚好把最后一位溢出到v12;
- 这里只调用一个sub_83A函数,所以直接查看这个函数。但是F5的时候IDA会提示
too big function
,解决办法为修改IDA配置文件cfg\hexrays.cfg
MAX_FUNCSIZE = 64 // Functions over 64K are not decompiled
// 修改为:
MAX_FUNCSIZE = 1024 // Functions over 64K are not decompiled
然后这里反编译的时候较长,去刷会抖音再回来,就看到
3000行代码,250轮xor操作(其实有些不是,是++),这里效验出错的时候,它会提示你是哪一步错了,所以这里应该可以从头开始逐位爆破。
这里我写了一个C的exp:
#include<stdio.h>
void sub_83A(int *v1){
v1[0] ^= 0x2B;
v1[1] ^= 0x6C;
v1[2] ^= 0x7E;
v1[3] ^= 0x56;
v1[4] ^= 0x39;
v1[5] ^= 3;
v1[6] ^= 0x2D;
v1[7] ^= 0x28;
v1[8] ^= 8;
++v1[9];
v1[10] ^= 0x2F;
v1[11] ^= 0xA;
........ //太多不宜展示,就仅复制250轮加密就OK
}
int main(){
int a[] = {126,50,37,88,89,107,53,110,0,19,30,56,}; //效验值
int v1[20]; //存放临时值
int flag[20]; //存放flag
for(int x=0;x<=11;){
for(int y=0;y<=125;y++){
for(int z=0;z<x;z++)
v1[z] = flag[z]; //因为每次v1整个数组的值都要变,所以重新赋值正确值
v1[x] = y;
sub_83A(v1); //经过函数
if(v1[x] == a[x]){
flag[x] = y; //正确值进行存储
printf("v1[%d] : %c\n",x,y); //显示进度
x ++;
y = 0;
}
}
if(x < 12){
printf("ERROR : %d",x); //出错了就提示
return 0;
}
}
for(int i = 0;i<=11;i++){
printf("%c",flag[i]); //输出完整flag
}
return 0;
}
成功获取flag,因为是在buu上刷题,所以包上flag{}即可。
爆出flag后,想去看了看其他师傅的解,发现有也可以用python写,使用pwntools库。纯Re选手可能不清楚,可以了解一下。