获取中...

-

Just a minute...

控制流平坦化,混淆,c++模板编程

链接:https://pan.baidu.com/s/1bZQENF8qsjdRZVYWN3oJeA
提取码:of89


flat

用ida查看,这是一道控制流平坦化的题目

有5个主要的函数

五个主要函数

check1

输入的字符串长度在0和50之间

check2

字符串前5个字符为 “flag{“

check3

最后一个字符为 “}”

check4

判断第29,14,19,24个字符是否为”-“

check5

输入的字符串加密后与dest进行比较

首先找到dest数组,dest数组为J2261C63-3I2I-EGE4-IBCC-IE41A5I5F4HB

check5就是0到9的ascii码加17,a到z的减48,其余的不变

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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
while ( v11 == -1771681815 )
{
v6 = 1740029224;
if ( v15[v12] >= 'a' ) //大于等于a
v6 = -1207418117;
v11 = v6;
}
if ( v11 != 024713157204 )
break;
++v12;
v11 = -768723158;
}
if ( v11 != 2887065063 )
break;
v4 = -1188300396;
if ( v15[v12] <= '9' ) //小于等于9
v4 = -478229440;
v11 = v4;
}
if ( v11 != 3087549179 )
break;
v7 = 1740029224;
if ( v15[v12] <= 'z' ) //小于等于z
v7 = 2096910144;
v11 = v7;
}
if ( v11 != -1188300396 )
break;
v5 = -1771681815;
if ( v15[v12] == '-' ) //判断是否为"-"
v5 = -1167333891;
v11 = v5;
}
if ( v11 != -1167333891 )
break;
v13[v12] = v15[v12]; //当小于0,大于9,或者是"-"的时候不变
v11 = -118846692;
}
if ( v11 != -995934932 )
break;
v3 = -1188300396;
if ( v15[v12] >= '0' )
v3 = -1407902233;
v11 = v3;
}
if ( v11 != -991718889 )
break;
v11 = -1490231676;
}
if ( v11 != -768723158 )
break;
v8 = 1681851953;
if ( v12 < 36 )
v8 = 434013166;
v11 = v8;
}
if ( v11 != -624695604 )
break;
v2 = 659899916;
if ( v12 < 36 )
v2 = -995934932;
v11 = v2;
}
if ( v11 != -478229440 )
break;
v13[v12] = v15[v12] + 17; //将0到9加17
v11 = 1926387427;
}
if ( v11 != -451717645 )
break;
++v12;
v11 = -624695604;
}
if ( v11 != -118846692 )
break;
v11 = 1926387427;
}
if ( v11 != 329160926 )
break;
v16 = 0;
v11 = 1269730414;
}
if ( v11 != 434013166 )
break;
v9 = -991718889;
if ( v13[v12] != v14[v12] )
v9 = 329160926;
v11 = v9;
}
if ( v11 != 659899916 )
break;
v12 = 0;
v11 = -768723158;
}
if ( v11 == 1269730414 )
break;
switch ( v11 )
{
case 1681851953:
v16 = 1;
v11 = 1269730414;
break;
case 1740029224:
v11 = -118846692;
break;
case 1926387427:
v11 = -451717645;
break;
case 2096910144:
v13[v12] = v15[v12] - 1347911315 + 1347911267; //将a到z减48
v11 = 1740029224;
break;

脚本

1
2
3
4
5
6
7
8
9
10
11
dest="J2261C63-3I2I-EGE4-IBCC-IE41A5I5F4HB"
flag = "flag{"
for i in dest:
if i>='0' and i<='9':
flag += chr(ord(i)+48)
elif i>='A' and i<='Z':
flag += chr(ord(i)-17)
else:
flag +=i
print (flag)
print("}")

src_leak

看的不太懂,根据函数写的脚本。

flag格式

求出x1,x2,x3,x4,x5,x6就行了,flag是 flag{x1-x2-x3-x4-x5-x6}

x6

x6是计数的,跟func4有关

找到题目中有关func4的函数

脚本

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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include<stdio.h>

int NEXTN(int n,int m)
{
return((n % m != 0) * n);
}

/*template<uint n, uint m>struct NEXTN {
const static uint value = ((n % m != 0) * n);
};*/

int NEXTM(int n,int m)
{
return (m * m <= n ? (m + 1) : 0);
}
/*template<uint n, uint m>struct NEXTM {
const static uint value = (m * m <= n ? (m + 1) : 0);
};*/

int TEST(int n,int m)
{
if (n==0)
return 0;
else if(m==0)
return 1;
return TEST(NEXTN(n,m),NEXTM(n,m));
}
/*template<uint n, uint m>struct TEST {
const static uint value = TEST<NEXTN<n, m>::value, NEXTM<n, m>::value>::value;
};

*template<uint m>struct TEST<0, m> {
const static uint value = 0;
};
template<uint n>struct TEST<n, 0> {
const static uint value = 1;
};*/

int func4(int num)
{
if(num==1)
return 0;
if(num==2)
return 1;
else
{
return TEST(num,2);
}
}
/*template<uint n>struct func4 {
const static uint value = TEST<n, 2>::value;
};
template<>struct func4<1> {
const static uint value = 0;
};
template<>struct func4<2> {
const static uint value = 1;
};*/
int main()
{
int ans=0;
for(int i=1;i<=10000;i++)
{
ans+=func4(i);
}
printf("%d\n",ans);
}

X1-X5

x1-x5需要满足进入func1后结果是963 4396 6666 1999 3141,同时还要满足func3< func2的结果是1

func1

func1就是求一个数的开跟结果大约是963 4396 6666 1999 3141

func2

func3

脚本

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
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
52
#include<stdio.h>

int run2(int num)
{
if(num == 0)
return 0;
else
return (num % 2) + run2(num/2);
}
/*
template<size_t Input>
constexpr size_t func2 = (Input % 2) + func2< (Input / 2) >;

template<>
constexpr size_t func2<0> = 0;
*/


int run3(int num)
{
return num%2;
}
/*
template<size_t num>
constexpr size_t func3 = num % 2;
*/


int main()
{
int num;
for(int x1 = 963 * 963 ; x1 <= 964*964-1; x1++)
//for(int x2 = 4396 * 4396 ; x2 <= 4397*4397-1; x2++)
//for(int x3 = 6666 * 6666 ; x3 <= 6667*6667-1; x3++)
//for(int x4 = 1999 * 1999 ; x4 <= 2000*2000-1; x4++)
//for(int x5 = 3141 * 3141 ; x5 <= 3142*3142-1; x5++)
{
if(run3(run2(x1)) == 1)
//if(run3(run2(x2)) == 1)
//if(run3(run2(x3)) == 1)
//if(run3(run2(x4)) == 1)
//if(run3(run2(x5)) == 1)
{
printf("%d\n",x1);
//printf("%d\n",x2);
//printf("%d\n",x3);
//printf("%d\n",x4);
//printf("%d\n",x5);
break;
}
}
}

签到

题目:I’m gamectf.com, I love TXT.
考察查看域名的txt记录,使用命令dig -t txt gamectf.com得到flag

亚萨西

解压需要密码,用010editor查看,得到密码loli

查看图片,最后是Ook编码

得到flag{f71d6bca-3210-4a31-9feb-1768a65a33db}

24word

使用了Code Values Encoder编码,解码后得到CodeValues

用binwalk分离图片,得到一个压缩包,用CodeValues解压,扫描二维码得到flag

七代目

修改文件头为gif,得到图片

identify -format "%s %T \n" './1.gif'查看图片的每一帧

发现第6帧和其他的不一样,分离图片,得到flag

相关文章
评论
分享
  • 网鼎杯部分wp

    pwnboom1分析远程已经打不通了,远程的偏移和本地的偏移不一样,只能复现一下本地的了。 首先看到流程图,代码量很大,有很大的switch语句和嵌套结构,可能是虚拟机或者是解析器。 从下图看出是一个C语言的解析器。 然后看了...

    网鼎杯部分wp
  • 数字中国创新大赛

    又是自闭的一天。。 game这一题是关于python字节码的题目,之前没有了解过,看了几篇关于python字节码的文章,死磕,手工还原。。 python字节码 12345678910111213141516171819202122...

    数字中国创新大赛
  • hitcontraining_uaf

    一道简单的uaf的题目 保护12345Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX...

    hitcontraining_uaf
Please check the parameter of comment in config.yml of hexo-theme-Annie!