【Rev】2021 极客大挑战(部分)
1、调试
0x1
什么?得安装linux虚拟机?像我这种直接用ubuntu系统的根本不虚!
0x2
尝试直接运行,未果
拖入ida中分析,先看main
上来就比较字符串,然后返回,v4是栈里的变量,初始化为0,必然不等于后面的字符串
看看汇编,发现了端倪
如果不相等就去loc_14A0这个函数,发现这个函数直接退出了,没啥用
我们看看如果想等跳转的函数loc_14551。怎么说都比上面退出的函数正常吧。
0x3
到这里我们想直接调用到loc_1455这个函数其实也可以,改汇编的jnz为jz就可以了
保存为ts1,退出,运行,一气呵成!
get flag
2、Re1
0x1
逆向人必备技能了属于是
0x2
拖入ida中分析
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[256]; // [rsp+20h] [rbp-60h] BYREF
char Str[40]; // [rsp+120h] [rbp+A0h] BYREF
int v6; // [rsp+148h] [rbp+C8h]
char v7; // [rsp+14Ch] [rbp+CCh]
char v8[58]; // [rsp+150h] [rbp+D0h]
char v9[2]; // [rsp+18Ah] [rbp+10Ah] BYREF
int v10; // [rsp+198h] [rbp+118h]
int i; // [rsp+19Ch] [rbp+11Ch]
_main(argc, argv, envp);
v8[0] = 21;
v8[1] = 113;
v8[2] = 44;
v8[3] = 4;
v8[4] = 37;
v8[5] = 113;
v8[6] = 40;
v8[7] = 16;
v8[8] = 21;
v8[9] = 44;
v8[10] = 121;
v8[11] = 40;
v8[12] = 34;
v8[13] = 45;
v8[14] = 18;
v8[15] = 38;
v8[16] = 25;
v8[17] = 45;
v8[18] = 6;
v8[19] = 58;
v8[20] = 26;
v8[21] = 20;
v8[22] = 25;
v8[23] = 112;
v8[24] = 24;
v8[25] = 114;
v8[26] = 6;
v8[27] = 57;
v8[28] = 26;
v8[29] = 22;
v8[30] = 121;
v8[31] = 112;
v8[32] = 33;
v8[33] = 7;
v8[34] = 22;
v8[35] = 38;
v8[36] = 25;
v8[37] = 45;
v8[38] = 6;
v8[39] = 58;
v8[40] = 33;
v8[41] = 24;
v8[42] = 14;
v8[43] = 38;
v8[44] = 34;
v8[45] = 114;
v8[46] = 26;
v8[47] = 38;
v8[48] = 35;
v8[49] = 45;
v8[50] = 22;
v8[51] = 114;
v8[52] = 26;
v8[53] = 24;
v8[54] = 10;
v8[55] = 58;
v8[56] = 26;
v8[57] = 24;
qmemcpy(v9, "p}", sizeof(v9));
memset(Str, 0, sizeof(Str));
v6 = 0;
v7 = 0;
memset(v4, 0, sizeof(v4));
puts("please input your flag:");
scanf("%s", Str);
v10 = strlen(Str);
if ( v10 != 44 )
{
puts("flag length is wrong");
exit(0);
}
enc0(Str, v4, 44i64);
enc1(v4);
for ( i = 0; i < strlen(v4); ++i )
{
if ( v8[i] != v4[i] )
{
puts("sorry,your flag is incorrect");
exit(0);
}
}
printf("congradulations!your flag is: %s", Str);
return 0;
}
直接给了flag加密后的数据,flag长度为44,经过两个加密
那么我们逆回去先dec1再dec0
0x3
enc1就是简单的异或,直接异或回去就好了
enc0就是base64,都没改表
那么我们直接写exp
#include<stdio.h>
int main() {
int v8[100] = {0};
v8[0] = 21;
v8[1] = 113;
v8[2] = 44;
v8[3] = 4;
v8[4] = 37;
v8[5] = 113;
v8[6] = 40;
v8[7] = 16;
v8[8] = 21;
v8[9] = 44;
v8[10] = 121;
v8[11] = 40;
v8[12] = 34;
v8[13] = 45;
v8[14] = 18;
v8[15] = 38;
v8[16] = 25;
v8[17] = 45;
v8[18] = 6;
v8[19] = 58;
v8[20] = 26;
v8[21] = 20;
v8[22] = 25;
v8[23] = 112;
v8[24] = 24;
v8[25] = 114;
v8[26] = 6;
v8[27] = 57;
v8[28] = 26;
v8[29] = 22;
v8[30] = 121;
v8[31] = 112;
v8[32] = 33;
v8[33] = 7;
v8[34] = 22;
v8[35] = 38;
v8[36] = 25;
v8[37] = 45;
v8[38] = 6;
v8[39] = 58;
v8[40] = 33;
v8[41] = 24;
v8[42] = 14;
v8[43] = 38;
v8[44] = 34;
v8[45] = 114;
v8[46] = 26;
v8[47] = 38;
v8[48] = 35;
v8[49] = 45;
v8[50] = 22;
v8[51] = 114;
v8[52] = 26;
v8[53] = 24;
v8[54] = 10;
v8[55] = 58;
v8[56] = 26;
v8[57] = 24;
for(int i = 0; i < 58; i++) {
v8[i] ^= 0x40;
printf("%c",(char)v8[i]);
}
}
3、win32
0x1
0x2
拖入ida中分析,只有一片区域,被加壳了,首先尝试upx脱壳
0x3
再次拖入ida中分析,直接shift+f12看字符
直接是没换表的base64和一个加密结果,我们直接base64 decode
get flag
3、wasm
0x1
这道题下载下来是一个html+js+wasm文件的一个web页面,如果flag输入正确就给你flag
之前的re没做过这种,在网上搜了搜,解法分为两种——动调和静态分析
0x2
先分享两个学习链接
Reversing Web Assembly (WASM)(chrom动调)
我先看了看chrom动调,体验极差,之后看了这个静态的,觉得不错,也是直接穿了。
我们来看看如何解题
首先是三个附件,我这里用tomcat运行打开前端,就仅仅是一个输入flag的输入框,提交表单之后会反馈是否输入正确。(直接打开无法运行,建议使用tomcat打开)
根据静态调试的博客,我们先来搞出ida可以分析的elf文件!
按照博文中的方法搞出.o文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S6lm94gj-1638161601772)(https://gitee.com/Awoodwhale/blogimg/raw/master/img/image-20211101200033076.png)]
0x3
我们可以把o文件放入ida中进行分析
首先是mian函数
我们可以发现,result是f11函数的返回值,其他没什么需要注意的,粉色的应该是wasm的动态链接之类的东西,我们直接步入f11
仍然是粉色的函数不看,直接看到关键判断,这里是说我们load进入的参数是否等于22,如果不等于就f96
如果等于就去f10。
之后看这些东西直接昏了头,大概就是f96是失败,f10会进入下一步。
0x4
其实到上面那里我就看不下去了,就算是wasm可以进入ida反编译,也确实难看
我们注意到上面静态分析的博文中,可以在wasm.c中找常量,我们直接开始!
找到一个非常大的数组
我尝试性的试一试,因为题目是xorwasm,肯定和异或有关
由于flag格式是SYC{xxxx},我们尝试一下第一个字母,发现第一个数据异或上102就可以得到S,带入第二个数组值,惊奇的得到了Y,那么是不是直接异或一下102就可以了呢?
答案是肯定的,我们先得到}
字符异或102的hex,是0x1b,到数组中找到0x1b的位置
找到位置之后就是数据处理了
这题出了只能说是运气好-w-
4、Brute_force
0x1
go的逆向,这题纯靠看
0x2
托人ida分析,直接看main
这里直接猜测是判断长度,flag的长度为24
然后分析下面的main_unnamed函数
看到两个关键字,main_encode肯定是加密算法,下面那个&main_cipher1肯定是flag加密后的
进入main_encode函数,发现是md5加密
然后去到刚刚的flag密文那里,看到3个md5值
并且在下面又看到类似md5加密后的值
之后就去在线网页解密,得到解密结果如下
然后就硬看,首先和go相关,那这个g0
就很有用,p
可以跟着rogarm
,然后就拼出了
用程序验证一下:
得到flag
SYC{7h3_g0_pr0g@rm_13_slgned}