川传ctf wp

上午还在军训,只做了3个小时,做了一半的re,没做完题,有点小难受吧。

java

jd-gui打开

简单的两个base64解密,做二维数组的row和rol

脚本

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

#include<stdio.h>

int main(void)
{
int s[18][18]={
{
99, 124, 119, 123, 242, 107, 111, 197, 48, 1,
103, 43, 254, 215, 171, 118 }, {
202, 130, 201, 125, 250, 89, 71, 240, 173, 212,
162, 175, 156, 164, 114, 192 }, {
183, 253, 147, 38, 54, 63, 247, 204, 52, 165,
229, 241, 113, 216, 49, 21 }, {
4, 199, 35, 195, 24, 150, 5, 154, 7, 18,
128, 226, 235, 39, 178, 117 }, {
9, 131, 44, 26, 27, 110, 90, 160, 82, 59,
214, 179, 41, 227, 47, 132 }, {
83, 209, 237, 32, 252, 177, 91, 106, 203, 190,
57, 74, 76, 88, 207 }, {
208, 239, 170, 251, 67, 77, 51, 133, 69, 249,
2, 127, 80, 60, 159, 168 }, {
81, 163, 64, 143, 146, 157, 56, 245, 188, 182,
218, 33, 16, 255, 243, 210 }, {
205, 12, 19, 236, 95, 151, 68, 23, 196, 167,
126, 61, 100, 93, 25, 115 }, {
96, 129, 79, 220, 34, 42, 144, 136, 70, 238,
184, 20, 222, 94, 11, 219 },
{
224, 50, 58, 10, 73, 6, 36, 92, 194, 211,
172, 98, 145, 149, 228, 121 }, {
231, 200, 55, 109, 141, 213, 78, 169, 108, 86,
244, 234, 101, 122, 174, 8 }, {
186, 120, 37, 46, 28, 166, 180, 198, 232, 221,
116, 31, 75, 189, 139, 138 }, {
112, 62, 181, 102, 72, 3, 246, 14, 97, 53,
87, 185, 134, 193, 29, 158 }, {
225, 248, 152, 17, 105, 217, 142, 148, 155, 30,
135, 233, 206, 85, 40, 223 }, {
140, 161, 137, 13, 191, 230, 66, 104, 65, 153,
45, 15, 176, 84, 187, 22 } };
int a[]={0,2,0,6,8,11,11,8,7,8,13,4,6,11,8,12,2,6,0,11,15};
int b[]={10,14,2,8,4,3,12,4,2,4,3,8,8,12,4,10,14,4,5,12,13};

int i;

for(i=0;i<22;i++)
{
printf("%c",s[a[i]][b[i]]);
}
}
//g1wE_me_@_fREe_t1CkeT

RELF

elf文件

ida分析

脚本

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

#include<stdio.h>

int main()
{
int v3[30];
int v5[30];
int v4[30];
int flag[30];
int i;

v5[0] = 34;
v5[1] = 29;
v5[2] = 76;
v5[3] = 98;
v5[4] = 43;
v5[5] = 52;
v5[6] = 97;
v5[7] = 24;
v5[8] = 40;
v5[9] = 23;
v5[10] = 4;
v5[11] = 69;
v5[12] = 44;
v5[13] = 52;
v5[14] = 43;
v5[15] = 80;
v5[16] = 1;
v5[17] = 63;
v5[18] = 79;
v5[19] = 48;
v5[20] = 55;
v5[21] = 8;
v5[22] = 26;
v5[23] = 95;
v5[24] = 4;
v5[25] = 34;
v5[26] = 82;
v5[27] = 11;
v5[28] = 51;
v5[29] = 81;
v4[0] = 297;
v4[1] = 169;
v4[2] = 431;
v4[3] = 229;
v4[4] = 423;
v4[5] = 257;
v4[6] = 465;
v4[7] = 288;
v4[8] = 437;
v4[9] = 86;
v4[10] = 364;
v4[11] = 123;
v4[12] = 390;
v4[13] = 485;
v4[14] = 232;
v4[15] = 352;
v4[16] = 244;
v4[17] = 469;
v4[18] = 54;
v4[19] = 359;
v4[20] = 16;
v4[21] = 110;
v4[22] = 355;
v4[23] = 244;
v4[24] = 256;
v4[25] = 94;
v4[26] = 187;
v4[27] = 19;
v4[28] = 242;
v4[29] = 432;
v3[0] = 3765;
v3[1] = 3301;
v3[2] = 7803;
v3[3] = 10323;
v3[4] = 5712;
v3[5] = 3845;
v3[6] = 5218;
v3[7] = 1968;
v3[8] = 4237;
v3[9] = 1696;
v3[10] = 704;
v3[11] = 7713;
v3[12] = 4746;
v3[13] = 6517;
v3[14] = 2339;
v3[15] = 4192;
v3[16] = 354;
v3[17] = 6454;
v3[18] = 6137;
v3[19] = 5015;
v3[20] = 6396;
v3[21] = 942;
v3[22] = 2825;
v3[23] = 8129;
v3[24] = 448;
v3[25] = 1760;
v3[26] = 9863;
v3[27] = 778;
v3[28] = 6617;
v3[29] = 432;
for(i=0;i<30;i++)
{
flag[i]=(v3[i]-v4[i])/v5[i];
printf("%c",flag[i]);
}
}
//flag{E1F_FUnct10n_Math_S01vE}

反调试

一个TLSCallback函数,检查ida.exe,和od是否运行的反调试

两个做法,直接乱设置ip,或者静态解,反正就是一些异或

我这里是动调得到flag
flag{congratula tions_for_you}

main

exe文件,随机产生一个数,然后输入一个数满足一些条件就会输出flag。

直接动调绕过

算法

简单的算法,就是取表中的数据组成flag

爆破脚本

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

#include<stdio.h>

int main()
{
char *v1; // edx
int len; // esi
int v3; // edi
char v4; // al
int v5; // eax
char v6; // al
char v8[68]="0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; // [esp+Ch] [ebp-130h] BYREF
char v9[68]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/"; // [esp+50h] [ebp-ECh] BYREF
char v10[68]="+/abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // [esp+94h] [ebp-A8h] BYREF
char v11[68]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // [esp+D8h] [ebp-64h] BYREF
char v12[28]="QASWZXDECVFRBNGTHYJUMKIOLP";
// flag{ZN0Y_is_a_easy_YuanLa}
int code[]={116,102,111,81,53,99,107,107,119,104,88,53,49,72,89,112,120,65,106,107,77,81,89,84,65,112,53};
int i,j;


for(i=0;i<27;i++)
{
for(j=95;j<127;j++)
{

v5=j-v12[i%26];
switch ( v5 & 0x80000003)
{
case 0u:
v6 = v11[v5];
break;
case 1u:
v6 = v10[v5];
break;
case 2u:
v6 = v9[v5];
break;
case 3u:
v6 = v8[v5];
break;
}
if((v6==code[i]))
{
printf("%c",j);
break;
}
}
}
}
//flag{this_is_a_easy_suanfa}

get_flag

去花,去掉几个E8 ,然后逻辑比较简单

z3来解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

from z3 import *
code=[0xB9, 0x3A, 0xA9, 0xD8, 0x15, 0x8A, 0xE7, 0x42, 0x69, 0x90, 0xCA, 0xA3, 0x4D, 0xD8, 0xD9, 0xC9]

s = Solver()
flag = [BitVec(('x%d' % i), 8) for i in range(16)]
for i in range(16):
mid=flag[i]
mid=mid^(mid*2-6)
mid=mid-i*2
s.add(mid==code[i])

if s.check() == sat:
model = s.model()
str = [chr(model[flag[i]].as_long().real) for i in range(16)]
print("".join(str))
exit()
else:
print("no_sat")
#mBqL!zS6-hLm)XY_

cpp

这道题比较有意思的是那个异或加密的伪代码和汇编层的样子。估计是因为64位程序,转换为那样的汇编比较快吧。

ida分析,加密1

加密二,数组内异或加密

脚本

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

#include<stdio.h>
int main(void)
{
int flag[32]={0x99,0xb0,0x87,0x9e,0x70,0xe8,0x41,0x44,0x05,0x04,0x8b,0x9a,0x74,0xbc,0x55,0x58,0xb5,0x61,0x8e,0x36,0xac,0x09,0x59,0xe5,0x61,0xdd,0x3e,0x3f,0xb9,0x15,0xed,0xd5};
int i,j;
// unsigned __int64 v[]={0x4441E8709E87B099,0x5855BC749A8B0405,0xE55909AC368E61B5,0xD5ED15B93F3EDD61};
//
// for(j=0;j<4;j++)
// {
// for(i=0;i<8;i++)
// {
// printf("0x%02x,",v[j]&0xff);
// v[j]=v[j]>>8;
// }
// }

for(i=0;i<=3;i++)
{
for(j=31;j>0;j--)
{
// flag[j]=flag[j]^flag[j-1];
flag[j]=flag[j]^flag[j-1];
}
}

for(i=0;i<32;i++)
{
// flag[i]=(flag[i]>>6)|(flag[i]<<2) ^ i
flag[i]^=i;
flag[i]=((flag[i]&3)<<6)|((flag[i]>>2)&0x3f);
printf("%c",flag[i]);
}
}
//flag{W0w_y0u_m4st3r_C_p1us_p1us}

What

一个md5加密的算法,然后需要满足后面的一些条件,爆破就行了。

python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

import hashlib

for a in range(97,123):
for b in range(97,123):
for c in range(97,123):
for d in range(97,123):
for e in range(97,123):
for f in range(97,123):
str = chr(a)+chr(b)+chr(c)+chr(d)+chr(e)+chr(f)
flag = hashlib.md5(str.encode('utf-8')).hexdigest()
v14 = 0
v13 = 0
for i in range(32):
if(flag[i]=='0'):
v14+=1
v13+=i
if (10 * v14 + v13 == 403):
print(str)
#ozulmt

然后这个程序也不能运行了,后面的check函数也要通过decode函数解密出来,我解密出来,看不出什么逻辑。

app

好像要调试,调试so文件一直有问题,后面来解决

muma.apk

apk做的比较少,后面学习了在来看。