combat_slogan

解压ctftest.jar文件后,在ctftest\com\xaut路径找到Main.class文件,用java反编译得到java代码

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
package com.xaut;

import java.util.Scanner;

public class Main {

public static String stringTransformAscii(String value) {
StringBuffer sbu = new StringBuffer();
char[] chars = value.toCharArray();

for(int i = 0; i < chars.length; ++i) {
if(i != chars.length - 1) {
sbu.append(chars[i]).append(",");
} else {
sbu.append(chars[i]);
}
}

return sbu.toString();
}

public static String ttk(String input) {
StringBuilder sb = new StringBuilder();

for(int i = 0; i < input.length(); ++i) {
char c = input.charAt(i);
if(c >= 97 && c <= 109) {
c = (char)(c + 13);
} else if(c >= 65 && c <= 77) {
c = (char)(c + 13);
} else if(c >= 110 && c <= 122) {
c = (char)(c - 13);
} else if(c >= 78 && c <= 90) {
c = (char)(c - 13);
}

sb.append(c);
}

return sb.toString();
}

public static void main(String[] args) {
System.out.println("Please input your keyword锛�");
Scanner scan = new Scanner(System.in);
String str2 = "ddd";
if(scan.hasNextLine()) {
str2 = scan.nextLine();
}

scan.close();
String stringTransformAscii = stringTransformAscii(str2);
String[] offerCodeString = stringTransformAscii.split(",");
StringBuffer str5 = new StringBuffer();
String[] flag = offerCodeString;
int var7 = offerCodeString.length;

for(int var8 = 0; var8 < var7; ++var8) {
String s = flag[var8];
str5.append(s);
}

int var10 = ttk(str2).compareTo("Jr_j11y_s1tug_g0_raq_g0_raq_pnml");
if(var10 == 0 && str5.toString().compareTo("871019511949491089510249103104116951164895101110100951164895101110100959997122121") == 0) {
System.out.println("Your keyword is correct!");
} else {
System.out.println("Your keyword is wrong!");
}

}
}

一个很简单的类似单表代换的操作,写exp的时候记得改一下条件就行了。

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
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

char a[100]="Jr_j11y_s1tug_g0_raq_g0_raq_pnml";

int main()
{
for(int i = 0; i < strlen(a); ++i)
{
char c = a[i];
if(c >= 97 + 13 && c <= 109 + 13)
{
c = (char)(c - 13);
} else if(c >= 65 + 13 && c <= 77 + 13)
{
c = (char)(c - 13);
} else if(c >= 110 - 13 && c <= 122 - 13)
{
c = (char)(c + 13);
} else if(c >= 78 - 13 && c <= 90 - 13)
{
c = (char)(c + 13);
}
printf("%c",c);
}
}

运行得到

1
flag{We_w11l_f1ght_t0_end_t0_end_cazy}

cute_doge

解压后发现一个.exe文件,打开以后

获得提示,先打开IDApro直接进入动态调试。

在这一步的时候点击OK发现直接弹出了

得到

1
flag{Ch1na_yyds_cazy}

hello_py

一道python反编译题,用uncompyle6指令反编译得到python代码

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
# uncompyle6 version 3.8.0
# Python bytecode 3.8.0 (3413)
# Decompiled from: Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: C:\Users\Administrator\Desktop\easy_py.py
# Compiled at: 2021-12-28 15:45:17
# Size of source mod 2**32: 1099 bytes
import threading, time

def encode_1(n):#简单异或
global num#global的意思就是在子函数内也可以更改全局变量,也没什么用,一开始num是等于9的
while True:
if num >= 0:
flag[num] = flag[num] ^ num
num -= 1
time.sleep(1)
if num <= 0:
break


def encode_2(n):#简单异或
global num
while True:
if num >= 0:
flag[num] = flag[num] ^ flag[(num + 1)]
num -= 1
time.sleep(1)
if num < 0:
break


while True:
Happy = [
44, 100, 3, 50, 106, 90, 5, 102, 10, 112]
num = 9
f = input('Please input your flag:')
if len(f) != 10:
print('Your input is illegal')
else:
flag = list(f) #list() 方法用于将元组或字符串转换为列表。
j = 0
for i in flag:#把flag通过ASCII码变成数字
flag[j] = ord(i)
j += 1
else:
print("flag to 'ord':", flag)
t1 = threading.Thread(target=encode_1, args=(1, ))
t2 = threading.Thread(target=encode_2, args=(2, ))
t1.start()
time.sleep(0.5)
t2.start()
t1.join()
t2.join()
#这个threading就是多线程跑代码的意思,先用t1.start(),再用t2.start()先后加密flag
if flag == Happy:
print('Good job!')
else:
print('No no no!')

代码理解已贴注释,放上c++exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

char flag[10]={ 44, 100, 3, 50, 106, 90, 5, 102, 10, 112};

int main()
{
for(int i=0;i<10;i+=2)flag[i]=flag[i]^flag[i+1];
for(int i=1;i<10;i+=2)flag[i]=flag[i]^i;
cout<<flag;
}

运行得到

1
flag{He110_cazy}

lemon

这签到题属实给我整不会了,第一次见到字节码概念,感觉跟汇编差不多,有点类似python字节码,需要硬看字节码还原代码,我人麻了,下面放上缩进+注释版字节码

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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
0: const 60 ; <module 'main'> 
5: module 9 592
11: const 26 ; 83
16: const 27 ; 69
21: const 28 ; 65
26: array 3
31: store 0 0//var_00数组,里面存的65,69,83(小端序,可能是入栈顺序的原因?)
34: const 30 ; 101
39: const 31 ; 108
44: const 32 ; 111
49: const 33 ; 117
54: const 34 ; 122
59: const 30 ; 101
64: const 35 ; 105
69: const 36 ; 98
74: const 30 ; 101
79: const 31 ; 108
84: const 33 ; 117
89: const 35 ; 105
94: const 37 ; 113
99: const 33 ; 117
104: const 35 ; 105
109: const 37 ; 113
114: array 16
119: store 0 1//var_01数组,里面倒序存了16个值
122: const 39 ; 0
127: store 0 2//var_02变量=0
130: array 0
135: store 0 3//var_03数组为空
138: load 0 2//将var_02入栈
141: const 42 ; 256 //常数256
146: lt//var_02 less than 256
147: jz 184//不成立就跳到184行
152: load 0 3//将var_03入栈
155: const 43 ; append//对var_03调用append方法
160: getattr
161: load 0 2//将var_02入栈
164: call 1//对将栈顶往下的一个值var_02使用append方法
166: pop//append结束
167: load 0 2//var_02入栈
170: const 44 ; 1//常数1
175: add//和var_02相加
176: store 0 2//更新var_02的值
179: jmp 138//循环语句,跳转至138行
184: const 39 ; 0//常数0
189: store 0 4//更新var_04=0
192: load 0 4//var_04入栈
195: const 42 ; 256 //常数256
200: lt//var_04<256
201: jz 271//跳转271行
206: load 0 3//var_03数组
209: load 0 4
212: getitem//将var_04作为下标
213: load 0 0//var_00数组
216: load 0 4
219: const 46 ; 3//常数3
224: mod
225: getitem//将var_04 % 3作为下标
226: add//将上面两个下标对应的值做加法
227: load 0 1//var_01数组
230: load 0 4
233: const 47 ; 16
238: mod
239: getitem//var_04 % 16作为下标
240: add//将上面两个下标对应的值做加法
241: const 42 ; 256
246: mod//结果%256
247: load 0 3//var_03
250: load 0 4//下标为var_04
253: setitem//更新var_03[var_04]的值
254: load 0 4
257: const 44 ; 1
262: add
263: store 0 4//var_04+=1
266: jmp 192//循环语句
271: const 39 ; 0
276: store 0 5//var_05=0
279: load 0 5
282: const 46 ; 3
287: lt//var_05 less than 3
288: jz 448//跳转
293: const 39 ; 0
298: store 0 6//var_06=0
301: load 0 6
304: const 42 ; 256
309: lt//var_06 less than 256
310: jz 366//跳转
315: load 0 3
318: load 0 6
321: getitem//var_03[var_6]
322: load 0 3
325: load 0 6
328: const 44 ; 1
333: add
334: const 42 ; 256
339: mod
340: getitem//var_03[(var_06+1)%256]
341: bxor//将上面两个值异或
342: load 0 3
345: load 0 6
348: setitem//更新var_03[var_06]
349: load 0 6
352: const 44 ; 1
357: add
358: store 0 6//var_06+=1
361: jmp 301//内循环结束
366: const 39 ; 0
371: store 0 7//var_07=0
374: load 0 7
377: const 42 ; 256
382: lt//var_07 < 256
383: jz 431
388: load 0 3
391: load 0 7
394: getitem//var_03[var_07]
395: const 44 ; 1
400: add//var_03[var_07]+1
401: const 42 ; 256
406: mod//%256
407: load 0 3
410: load 0 7
413: setitem//更新
414: load 0 7
417: const 44 ; 1
422: add
423: store 0 7//var_07+=1
426: jmp 374//内循环结束
431: load 0 5
434: const 44 ; 1
439: add
440: store 0 5//var_05+=1
443: jmp 279//外循环结束
448: const 39 ; 0
453: store 0 5
456: const 39 ; 0
461: store 0 8//var_05=var_08=0
464: load 0 5
467: const 42 ; 256
472: lt//var_05 < 256
473: jz 509
478: load 0 8
481: load 0 3
484: load 0 5
487: getitem
488: add
489: store 0 8//var_08+=var_03[var_05]
492: load 0 5
495: const 44 ; 1
500: add
501: store 0 5//var_05+=1
504: jmp 464//循环结束
509: load 0 8
512: const 51 ; 20
517: mul//var_08*20
518: const 52 ; 5
523: add//+5
524: store 0 8//更新
527: load 0 8
530: const 54 ; 30
535: mul
536: const 52 ; 5
541: sub
542: store 0 8//var_08*=30,var_08-=5
545: load 0 8
548: const 56 ; 40
553: mul
554: const 52 ; 5
559: sub
560: store 0 8//var_08*=40,var_08-=5
563: load 0 8
566: const 58 ; 50 //var_08*=50,var_08-=5
571: mul
572: const 59 ; 6645
577: add
578: store 0 8//var_08+=6645
581: const 23 ; <function 'print'>
586: load 0 8
589: call 1
591: pop//print(var_08);

注释已经非常详尽,然而我捏妈打个ctf还遇到爆int然后调long long调了半小时这就有点说不过去了吧

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
#include<iostream>
#include<cstdio>
using namespace std;
int var_00[3]={65,69,83};
int var_01[16]={113,105,117,113,105,117,108,101,98,105,101,122,117,111,108,101};
int var_02=0;
int var_03[256];
int main()
{
while(var_02<256)
{
var_03[var_02]=var_02;
var_02++;
}
int var_04=0;
while(var_04<256)
{
var_03[var_04]=(var_03[var_04]+var_00[var_04%3]+var_01[var_04%16])%256;
var_04++;
}
int var_05=0;
while(var_05<3)
{
int var_06=0;
while(var_06<256)
{
var_03[var_06]^=var_03[(var_06+1)%256];
var_06++;
}
int var_07=0;
while(var_07<256)
{
var_03[var_07]=(var_03[var_07]+1)%256;
var_07++;
}
var_05++;
}
var_05=0;
long long var_08=0;
while(var_05<256)
{
var_08+=var_03[var_05];
var_05++;
}
var_08*=20;
var_08+=5;
var_08*=30;
var_08-=5;
var_08*=40;
var_08-=5;
var_08*=50;
var_08+=6645;
cout<<var_08;
}

运行得到
1
flag{23075096395}