附件是一个无壳的32位exe程序
先用ida静态分析,伪代码如下:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
int v5; // [esp+14h] [ebp-4Ch]
int v6; // [esp+3Ch] [ebp-24h]
int v7; // [esp+40h] [ebp-20h]
int v8; // [esp+44h] [ebp-1Ch]
int v9; // [esp+48h] [ebp-18h]
int v10; // [esp+4Ch] [ebp-14h]
size_t v11; // [esp+50h] [ebp-10h]
int v12; // [esp+54h] [ebp-Ch]
int i; // [esp+58h] [ebp-8h]
int v14; // [esp+5Ch] [ebp-4h]
__main();
puts("There is a long way to defeat it.");
scanf("%s", flag);
v12 = strlen(flag);
v6 = 0;
v7 = 0;
v8 = 0;
v9 = 0;
v10 = 0;
v14 = 0;
v11 = 0;
for ( i = 0; i < v12; ++i ) // 循环flag的位数次
{
if ( flag[i] == 45 )
{
v3 = v14++;
*(&v6 + v3) = i; // v6 为一个字符串 flag有四位为- 记录哪四位为-
}
if ( !v14 ) // 如果v14==0
{
*(&v5 + i) = flag[i] - 48; // v5也是一个字符串 flag中不为_的字符(前四个)被-48(0x30) v5记录变换之后的flag进行对比 不能大于9(0x39)和小于0(0x30)
// 根据cheekflag的参数以及所做运算来看,这个字符串所要求的四个字符应该是控制哪个地图先做检验
if ( *(&v5 + i) > 9 || *(&v5 + i) < 0 )
return 0;
}
}
if ( v14 != 4 )
return 0;
v10 = v12;
for ( i = 1; i <= v14; ++i ) // v14=4 按照-分割输入的flag
{
v11 = *(&v6 + i) - *(&v6 + i - 1) - 1; // v11为v6字符串的前一位减去后一位减1 需要计算出flag中哪四位为-以求达到程序要求
if ( step[i] != v11 )
return 0;
strncpy(&road[200 * i], &flag[*(&v6 + i - 1) + 1], v11);// 根据-把flag裁剪成几段之后再拼接
}
for ( i = 0; i <= 3; ++i ) // 分4段cheekflag 先从最长的分割位开始
{
if ( check_flag(&global_map + 200 * *(&v5 + i), *(&v5 + i), &road[200 * (i + 1)]) )// cheekFLAG需要返回0
{
puts("How about try again?");
return 0;
}
if ( i == 3 )
printf("Great! We will defeat it!!! your flag is flag{%s}", flag);
}
return 0;
}
旁边的注释是学长写的,我比较菜,刚开始都没分析出程序,看着学长注释最后等得出flag的框架
一步一步开始分析:
得到v12等于字符串的长度
v6为一个数组,记录flag中 - 的位置
如果v14等于0,执行如下代码,v5为一个数组,和上面一段联系起来意思是第一个-之前执行有几位就执行几次下面代码几次,并且大于0次小于9次,48为ASCII码值,值为 0,所以v5[i]=flag[i]
再将前面代码和下面代码串起来,v14的只能等于4,也就是说-有4个
但是我们依旧不知道v5的值,也就是说不知道flag中第一个-前面的值有几位,是干什么用的,甚至都不知道还有用处,所以需要继续分析
v10等于flag的长度,v14=4,循环3次,v11等于flag中后一个-的位置减去前一个-的位置再减一,意思为后一个-与前一个-之间的距离,step[]记录v11的值也就是第一个-与第二个-之间的距离为step[0],将-之间的值分成4份储存到road数组中
循环4次下面的check_flag函数里面用到了v5数组和road数组,还有一个global_map函数,map函数里面有4份迷宫地图,经过一顿脑洞分析v5应该代表的是进入那个地图的顺序,最后需要check_flag函数返回0
迷宫(从s到d)按从上到下(1234)顺序为:
我只能在赛后的角度加上学长的注解进行静态分析,还是对动态分析有很大的困难,需要积累,最后知道flag大致格式为:前面四位为代表先进行哪个迷宫的顺序,后面加-将路径分开,正确做法应该进行动态分析了,我由于知道答案了就写个python3脚本试试碰撞flag玩玩,当然没有答案之前不知道具体格式肯定是不能这么玩的,脚本如下:
# 知道格式简单的碰撞flag
array=[1,2,3,4]
str1=''
def str01():
str1=''
for i in range(4):
str1+=str(list1[i])
return str1
def str02(w):
s1=''
if w==1:
s1='d'*9+'s'*5+'a'*9+'w'*3
elif w==2:
s1='sd'*6+'sdd'+'wd'*6+'w'
elif w==3:
s1='a'*9+'s'*7+'d'*9
elif w==4:
s1='w'*5+'d'*9+'s'*5
return s1
list1=[0,0,0,0]
for i in array:
for j in array:
for x in array:
for d in array:
if i!=j and j!=x and i!=x and i!=d and j!=d and x!=d:
list1[0]=i
list1[1]=j
list1[2]=x
list1[3]=d
str2=str01()
print(str2)
flag='flag{'+str2+'-'+str02(int(str2[0]))+'-'+str02(int(str2[1]))+'-'+str02(int(str2[2]))+'-'+str02(int(str2[3]))+'}'
print(flag)
if flag=='flag{4312-wwwwwdddddddddsssss-aaaaaaaaasssssssddddddddd-dddddddddsssssaaaaaaaaawww-sdsdsdsdsdsdsddwdwdwdwdwdwdw}':
print('\n真正的flag:'+flag+'\n')
run:
C:\Users\Dell\AppData\Local\Programs\Python\Python37\python.exe C:/Users/Dell/Desktop/Python脚本/text.py
1234
flag{1234-dddddddddsssssaaaaaaaaawww-sdsdsdsdsdsdsddwdwdwdwdwdwdw-aaaaaaaaasssssssddddddddd-wwwwwdddddddddsssss}
1243
flag{1243-dddddddddsssssaaaaaaaaawww-sdsdsdsdsdsdsddwdwdwdwdwdwdw-wwwwwdddddddddsssss-aaaaaaaaasssssssddddddddd}
1324
flag{1324-dddddddddsssssaaaaaaaaawww-aaaaaaaaasssssssddddddddd-sdsdsdsdsdsdsddwdwdwdwdwdwdw-wwwwwdddddddddsssss}
1342
flag{1342-dddddddddsssssaaaaaaaaawww-aaaaaaaaasssssssddddddddd-wwwwwdddddddddsssss-sdsdsdsdsdsdsddwdwdwdwdwdwdw}
1423
flag{1423-dddddddddsssssaaaaaaaaawww-wwwwwdddddddddsssss-sdsdsdsdsdsdsddwdwdwdwdwdwdw-aaaaaaaaasssssssddddddddd}
1432
flag{1432-dddddddddsssssaaaaaaaaawww-wwwwwdddddddddsssss-aaaaaaaaasssssssddddddddd-sdsdsdsdsdsdsddwdwdwdwdwdwdw}
2134
flag{2134-sdsdsdsdsdsdsddwdwdwdwdwdwdw-dddddddddsssssaaaaaaaaawww-aaaaaaaaasssssssddddddddd-wwwwwdddddddddsssss}
2143
flag{2143-sdsdsdsdsdsdsddwdwdwdwdwdwdw-dddddddddsssssaaaaaaaaawww-wwwwwdddddddddsssss-aaaaaaaaasssssssddddddddd}
2314
flag{2314-sdsdsdsdsdsdsddwdwdwdwdwdwdw-aaaaaaaaasssssssddddddddd-dddddddddsssssaaaaaaaaawww-wwwwwdddddddddsssss}
2341
flag{2341-sdsdsdsdsdsdsddwdwdwdwdwdwdw-aaaaaaaaasssssssddddddddd-wwwwwdddddddddsssss-dddddddddsssssaaaaaaaaawww}
2413
flag{2413-sdsdsdsdsdsdsddwdwdwdwdwdwdw-wwwwwdddddddddsssss-dddddddddsssssaaaaaaaaawww-aaaaaaaaasssssssddddddddd}
2431
flag{2431-sdsdsdsdsdsdsddwdwdwdwdwdwdw-wwwwwdddddddddsssss-aaaaaaaaasssssssddddddddd-dddddddddsssssaaaaaaaaawww}
3124
flag{3124-aaaaaaaaasssssssddddddddd-dddddddddsssssaaaaaaaaawww-sdsdsdsdsdsdsddwdwdwdwdwdwdw-wwwwwdddddddddsssss}
3142
flag{3142-aaaaaaaaasssssssddddddddd-dddddddddsssssaaaaaaaaawww-wwwwwdddddddddsssss-sdsdsdsdsdsdsddwdwdwdwdwdwdw}
3214
flag{3214-aaaaaaaaasssssssddddddddd-sdsdsdsdsdsdsddwdwdwdwdwdwdw-dddddddddsssssaaaaaaaaawww-wwwwwdddddddddsssss}
3241
flag{3241-aaaaaaaaasssssssddddddddd-sdsdsdsdsdsdsddwdwdwdwdwdwdw-wwwwwdddddddddsssss-dddddddddsssssaaaaaaaaawww}
3412
flag{3412-aaaaaaaaasssssssddddddddd-wwwwwdddddddddsssss-dddddddddsssssaaaaaaaaawww-sdsdsdsdsdsdsddwdwdwdwdwdwdw}
3421
flag{3421-aaaaaaaaasssssssddddddddd-wwwwwdddddddddsssss-sdsdsdsdsdsdsddwdwdwdwdwdwdw-dddddddddsssssaaaaaaaaawww}
4123
flag{4123-wwwwwdddddddddsssss-dddddddddsssssaaaaaaaaawww-sdsdsdsdsdsdsddwdwdwdwdwdwdw-aaaaaaaaasssssssddddddddd}
4132
flag{4132-wwwwwdddddddddsssss-dddddddddsssssaaaaaaaaawww-aaaaaaaaasssssssddddddddd-sdsdsdsdsdsdsddwdwdwdwdwdwdw}
4213
flag{4213-wwwwwdddddddddsssss-sdsdsdsdsdsdsddwdwdwdwdwdwdw-dddddddddsssssaaaaaaaaawww-aaaaaaaaasssssssddddddddd}
4231
flag{4231-wwwwwdddddddddsssss-sdsdsdsdsdsdsddwdwdwdwdwdwdw-aaaaaaaaasssssssddddddddd-dddddddddsssssaaaaaaaaawww}
4312
flag{4312-wwwwwdddddddddsssss-aaaaaaaaasssssssddddddddd-dddddddddsssssaaaaaaaaawww-sdsdsdsdsdsdsddwdwdwdwdwdwdw}
真正的flag:flag{4312-wwwwwdddddddddsssss-aaaaaaaaasssssssddddddddd-dddddddddsssssaaaaaaaaawww-sdsdsdsdsdsdsddwdwdwdwdwdwdw}
4321
flag{4321-wwwwwdddddddddsssss-aaaaaaaaasssssssddddddddd-sdsdsdsdsdsdsddwdwdwdwdwdwdw-dddddddddsssssaaaaaaaaawww}
Process finished with exit code 0