wust蚁景杯

X0r

upx壳

用工具先脱壳

然后拖进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
// local variable allocation has failed, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
char Str2[8]; // [rsp+20h] [rbp-A0h]
char Str1[32]; // [rsp+40h] [rbp-80h]
char v6[32]; // [rsp+60h] [rbp-60h]
int i4; // [rsp+80h] [rbp-40h]
int i3; // [rsp+84h] [rbp-3Ch]
int i2; // [rsp+88h] [rbp-38h]
int i1; // [rsp+8Ch] [rbp-34h]
int nn; // [rsp+90h] [rbp-30h]
int mm; // [rsp+94h] [rbp-2Ch]
int ll; // [rsp+98h] [rbp-28h]
int kk; // [rsp+9Ch] [rbp-24h]
int jj; // [rsp+A0h] [rbp-20h]
int ii; // [rsp+A4h] [rbp-1Ch]
int n; // [rsp+A8h] [rbp-18h]
int m; // [rsp+ACh] [rbp-14h]
int l; // [rsp+B0h] [rbp-10h]
int k; // [rsp+B4h] [rbp-Ch]
int j; // [rsp+B8h] [rbp-8h]
int i; // [rsp+BCh] [rbp-4h]

_main(*(_QWORD *)&argc, argv, envp);
strcpy(Str2, "ys~xdGPM@.q@Mz@.l@Z+lfb");
puts("please input your flag:");
scanf("%s", v6);
for ( i = 0; i <= 22; ++i )
Str1[i] = v6[i] ^ 0x17;
for ( j = 0; j <= 22; ++j )
Str1[j] ^= 0x39u;
for ( k = 0; k <= 22; ++k )
Str1[k] ^= 0x4Bu;
for ( l = 0; l <= 22; ++l )
Str1[l] ^= 0x4Au;
for ( m = 0; m <= 22; ++m )
Str1[m] ^= 0x49u;
for ( n = 0; n <= 22; ++n )
Str1[n] ^= 0x26u;
for ( ii = 0; ii <= 22; ++ii )
Str1[ii] ^= 0x15u;
for ( jj = 0; jj <= 22; ++jj )
Str1[jj] ^= 0x61u;
for ( kk = 0; kk <= 22; ++kk )
Str1[kk] ^= 0x56u;
for ( ll = 0; ll <= 22; ++ll )
Str1[ll] ^= 0x1Bu;
for ( mm = 0; mm <= 22; ++mm )
Str1[mm] ^= 0x21u;
for ( nn = 0; nn <= 22; ++nn )
Str1[nn] ^= 0x40u;
for ( i1 = 0; i1 <= 22; ++i1 )
Str1[i1] ^= 0x57u;
for ( i2 = 0; i2 <= 22; ++i2 )
Str1[i2] ^= 0x2Eu;
for ( i3 = 0; i3 <= 22; ++i3 )
Str1[i3] ^= 0x49u;
for ( i4 = 0; i4 <= 22; ++i4 )
Str1[i4] ^= 0x37u;
if ( !strcmp(Str1, Str2) )
puts("Congratulations!You are right!");
else
puts("Oh no!You are wrong!Don't Give up!");
return 0;
}

就是一个多次异或的变换,逆向就是编写脚本把Str2再重复一遍这些异或操作即可

flag{XOR_1n_Re_1s_E4sy}

ez_re

64位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
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rdx
int result; // eax
__int64 v5; // rdx
char v6; // [rsp+0h] [rbp-30h]
unsigned __int64 v7; // [rsp+28h] [rbp-8h]

v7 = __readfsqword(0x28u);
puts("You got something good for me?\n>", argv, envp);
_isoc99_scanf((unsigned __int64)"%33s");
if ( j_strlen_ifunc(&v6, &v6) == 33 )
{
crypto((__int64)&v6);
printf((unsigned __int64)"checking...");
if ( (unsigned int)check((__int64)&v6) )
puts("Well done,h4cker!", &v6, v5);
else
puts("O0ops....", &v6, v5);
result = 0;
}
else
{
puts("O0ops....", &v6, v3);
result = 0;
}
return result;
}

进入crypto函数发现加密函数如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
_BYTE *__fastcall crypto(__int64 a1)
{
_BYTE *result; // rax
signed int v2; // [rsp+10h] [rbp-8h]
signed int v3; // [rsp+14h] [rbp-4h]

v2 = 55;
v3 = 0;
while ( v3 <= 32 )
{
*(_BYTE *)(v3 + a1) -= 2;
result = (_BYTE *)(v3 + a1);
*result ^= v2;
++v3;
++v2;
}
return result;
}

解题脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>
using namespace std;
int main()
{
int i;
int v2=55;
char flag[]={0x53, 0x52, 0x66, 0x5F, 0x42, 0x4F, 0x71, 0x50, 0x0D, 0x21,
0x28, 0x1F, 0x6C, 0x35, 0x18, 0x26, 0x79, 0x39, 0x2E, 0x2B,
0x16, 0x7F, 0x24, 0x29, 0x25, 0x3A, 0x0C, 0x1F, 0x37, 0x09,
0x25, 0x67, 0x2C};

for (i=0;i<33;i++)
{
flag[i] ^=v2;
flag[i] +=2;
v2++;
cout<<flag[i];
}
return 0;
}

flag{uNp4ck_1s_b@sic_5kill_Of_r3}

tables

pyc文件;网上找到反编译工具反编译一下

代码及分析如下

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
a = [
17,
23,
7,
22,
1,
16,
6,
9,
21,
0,
15,
5,
10,
18,
2,
24,
4,
11,
3,
14,
19,
12,
20,
13,
8,
25]
b = [
21,
4,
24,
25,
20,
5,
15,
9,
17,
6,
13,
3,
18,
12,
10,
19,
0,
22,
2,
11,
23,
1,
8,
7,
14,
16]
tableA = list('abcdefghijklmnopqrstuvwxyz')
tableB = list('abcdefghijklmnopqrstuvwxyz')
flag = ''
flag = input('Tell me your story:')
flag = flag[5:-1]
print(flag)
result = ''
for i in range(len(flag)):
ind = tableA.index(flag[i]) #tableA[ind]=flag[i]
t = -1
for j in range(len(a)):
if a[j] == ind:
t = j
break #a[t]=ind
if t == -1:
print('Some err..')
exit(0)
mid = a[0]
for j in range(1, len(a)):
a[j - 1] = a[j]

a[len(a) - 1] = mid #a[]第一个元素放在最后,其余元素前移1个单位
tableA.append(tableA[0])
del tableA[0] #将tableA[0]移至列表末尾
b_index = -1
for j in range(len(b)):
if b[j] == t:
b_index = j #b[b_index]=t
break
if b_index == -1:
print('Some err..')
exit(0)
result += tableB[b_index] #result[i] = tableB[b_index]

print(result)
if result != 'cdofjlshalidzkxlwutyxzoq':
print('Your math is terrible....\n')
else:
print('Well done but no reward for you :)')

解题脚本如下:

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
a = [
17,
23,
7,
22,
1,
16,
6,
9,
21,
0,
15,
5,
10,
18,
2,
24,
4,
11,
3,
14,
19,
12,
20,
13,
8,
25]
b = [
21,
4,
24,
25,
20,
5,
15,
9,
17,
6,
13,
3,
18,
12,
10,
19,
0,
22,
2,
11,
23,
1,
8,
7,
14,
16]

tableA = list('abcdefghijklmnopqrstuvwxyz')
tableB = list('abcdefghijklmnopqrstuvwxyz')
text = 'cdofjlshalidzkxlwutyxzoq'
flag = ''

for i in range(len(text)):
b_index = ord(text[i])-ord('a')
t = b[b_index]
ind = a[t]
flag += tableA[ind]
mid = a[0]
for j in range(1, len(a)):
a[j - 1] = a[j]

a[len(a) - 1] = mid # a[]第一个元素放在最后,其余元素前移1个单位
tableA.append(tableA[0])
del tableA[0] # 将tableA[0]移至列表末尾

print(flag)

flag{ismytablethateasytocrack}

babyjvav

.class 文件,拖进idea查看

代码及分析如下

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
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Wust {
public Wust() {
}

public static void main(String[] args) {
System.out.println("WUSTCTF2021 Freshman competition");
System.out.println("Input your flag:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = null;
int[] flag = new int[]{60, 23, 23, 41, 110, 66, 44, 17, 126, 68, 43, 26, 113, 71, 10};

try {
str = br.readLine();
} catch (Exception var10) {
System.out.println("ERROR: Undefined Exception.");
}

if (str.isEmpty()) {
System.out.println("Nothing received.");
} else {
if (str.length() != 22) {
System.out.println("len Wrong!");
return;
}

String head = str.substring(0, 5);
if (!head.equals("flag{")) {
System.out.println("head Wrong!");
return;
}

String m = str.substring(5, str.length() - 1);

for(int i = 0; i < m.length() - 1; ++i) { //这里是逐个字符相邻异或
int a = m.charAt(i);
int b = m.charAt(i + 1);
int c = a ^ b;
if (c != flag[i]) {
System.out.println("Wrong!");
return;
}
}

System.out.println("Congratulations!");
}

}
}

因为不知道原flag字符,分析后大胆猜测flag是字母开头,就以26个字母遍历开头字母来推后续字符

一开始是以小写字母来遍历,发现有一个像flag的字符串jVAVSnTeSY;但是有乱码

又换大写字母遍历,flag就出来了;

python脚本如下:

1
2
3
4
5
6
7
8
9
text=[60, 23, 23, 41, 110, 66, 44, 17, 126, 68, 43, 26, 113, 71, 10]
flag = ''
for i in range(26):
flag =''
flag +=chr(65+i)
for j in range(15):
flag += chr(text[j]^ord(flag[j]))
print(flag)

flag{Jvav_1s_N0t_E4sy}

easypyc

先反编译pyc,如下:

1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env python
# visit http://tool.lu/pyc/ for more information
from libnum import *
ans = 0x6675FA7F228DBCEB6A2DC223A37FC64FE67E61
flag = s2n(input('Input your flag: '))
flag ^= flag >> 10
if flag == ans:
print('You are right!')
else:
print('Try again!')

很简单的一个变换算法,但一开始我思考逆向的时候,陷入了16进制整体变换的泥坑,思不得解

经某昊爷启发,二进制逐位异或去思考便很容易找到规律

脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import libnum
from libnum import *

ans = 0x6675FA7F228DBCEB6A2DC223A37FC64FE67E61
flag = [1,1,0,0,1,1,0,0,1,1,1,0,1,0,1,1,1,1,1,1,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,0,1,0,1,0,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,1,1,0,1,0,1,1,0,1,1,0,1,0,1,0,0,0,1,0,1,1,0,1,1,1,0,0,0,0,1,0,0,0,1,0,0,0,1,1,1,0,1,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,0,1,1,0,0,0,0,1]
# ans转成列表好操作
help = flag[0:len(flag) - 10]
for i in range(len(help)):
flag[i+10]=flag[i+10] ^ flag[i]

for i in range(len(flag)):
print(flag[i],end="")
# 提取出来好复制成数字
print()
true_flag = 0b1100110011011000110000101100111011110110101001101101000001100010110011001110100010111110011010001101110011001000101111101011000001100000111001001111101
print(n2s(true_flag))

Comments