318's Blog

来人间一趟,总要见见太阳

0%

hgame2021_re部分wp

RE部分

Day 1 helloRe

第一天的第一道题~~这道题是真.签到题啊

进入ida,没有明显的main函数,F12查找字符串,看到input flag点进去
在这里插入图片描述
发现主函数应该是sub_1400014C0
在这里插入图片描述
在这里插入图片描述
逻辑很简单,脚本也挺好写的
在这里插入图片描述

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

int main()
{
char memory[30] = "";
int v6 = 0x0FF;
char asc_[23] = "棛湋瀬憹洑毇仐畝儚攭櫁";
for (int i = 0; i < 23; i++)
{
memory[i] = asc_[i] ^ (v6--);
}
printf("%s", memory);

}

Day 2 pypy

第一次做python反汇编,好在题目比较友好,没有太复杂

照着类似题的wp和dis–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
 0 LOAD_GLOBAL              0 (input)
2 LOAD_CONST 1 ('give me your flag:\n')
4 CALL_FUNCTION 1
6 STORE_FAST 0 (raw_flag)

5 8 LOAD_GLOBAL 1 (list)
10 LOAD_FAST 0 (raw_flag)
12 LOAD_CONST 2 (6)
14 LOAD_CONST 3 (-1)
16 BUILD_SLICE 2 取raw_flag的第六位到倒数第一位
18 BINARY_SUBSCR 所以最后要包上hgame{}才是flag
20 CALL_FUNCTION 1
22 STORE_FAST 1 (cipher)

6 24 LOAD_GLOBAL 2 (len)
26 LOAD_FAST 1 (cipher)
28 CALL_FUNCTION 1 length=len(cipher)
30 STORE_FAST 2 (length)

8 32 LOAD_GLOBAL 3 (range)
34 LOAD_FAST 2 (length)
36 LOAD_CONST 4 (2)
38 BINARY_FLOOR_DIVIDE

40 CALL_FUNCTION 1
42 GET_ITER
>> 44 FOR_ITER 54 (to 100)
46 STORE_FAST 3 (i)

9 48 LOAD_FAST 1 (cipher)
50 LOAD_CONST 4 (2)
52 LOAD_FAST 3 (i)
54 BINARY_MULTIPLY
56 LOAD_CONST 5 (1)
58 BINARY_ADD
60 BINARY_SUBSCR cipher[2i+1]
62 LOAD_FAST 1 (cipher)
64 LOAD_CONST 4 (2)
66 LOAD_FAST 3 (i)
68 BINARY_MULTIPLY
70 BINARY_SUBSCR cipher[2i]
72 ROT_TWO
74 LOAD_FAST 1 (cipher)
76 LOAD_CONST 4 (2)
78 LOAD_FAST 3 (i)
80 BINARY_MULTIPLY
82 STORE_SUBSCR
84 LOAD_FAST 1 (cipher)
86 LOAD_CONST 4 (2)
88 LOAD_FAST 3 (i)
90 BINARY_MULTIPLY
92 LOAD_CONST 5 (1)
94 BINARY_ADD
96 STORE_SUBSCR 这一段就是x,y=y,x
98 JUMP_ABSOLUTE 44 交换了cipher[2i+1]和cipher[2i]

12 >> 100 BUILD_LIST 0
102 STORE_FAST 4 (res) #创建一个list

13 104 LOAD_GLOBAL 3 (range)
106 LOAD_FAST 2 (length)
108 CALL_FUNCTION 1
110 GET_ITER
>> 112 FOR_ITER 26 (to 140)
114 STORE_FAST 3 (i)

14 116 LOAD_FAST 4 (res)
118 LOAD_METHOD 4 (append)
120 LOAD_GLOBAL 5 (ord)
122 LOAD_FAST 1 (cipher)
124 LOAD_FAST 3 (i)
126 BINARY_SUBSCR
128 CALL_FUNCTION 1
130 LOAD_FAST 3 (i)
132 BINARY_XOR res.append(ord(cipher[i])^i)
134 CALL_METHOD 1
136 POP_TOP
138 JUMP_ABSOLUTE 112

15 >> 140 LOAD_GLOBAL 6 (bytes)
142 LOAD_FAST 4 (res)
144 CALL_FUNCTION 1
146 LOAD_METHOD 7 (hex)
148 CALL_METHOD 0
150 STORE_FAST 4 (res) 把res里的数据转成16进制

16 152 LOAD_GLOBAL 8 (print)
154 LOAD_CONST 6 ('your flag: ')
156 LOAD_FAST 4 (res)
158 BINARY_ADD #输出res
160 CALL_FUNCTION 1
162 POP_TOP
164 LOAD_CONST 0 (None)
166 RETURN_VALUE

# your flag: 30466633346f59213b4139794520572b45514d61583151576638643a

其实就几行代码,因本废物只能看懂一点python但不会写,所以还是用的C++写脚本

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

int main()
{
int cipher[28] = { 0x30,0x46,0x66,0x33,0x34,0x6f,0x59,0x21,0x3b,0x41,0x39,0x79,0x45,0x20,
0x57,0x2b,0x45,0x51,0x4d,0x61,0x58,0x31,0x51,0x57,0x66,0x38,0x64,0x3a };
int raw_flag[20] = { };
char flag1[28] = {};
//char temp;
for (int i = 0; i < 28; i++)
{
flag1[i] = char(cipher[i] ^ i);
}
for (int i = 0; i < 17; i++)
{
swap(flag1[2 * i], flag1[2 * i + 1]);
}
for (int i = 0; i < 28; i++)
{
printf("%c", flag1[i]);
}
return 0;
}

在这里插入图片描述
hgame{}包上,提交~(讲真这个flag有点,,不好看,我一直以为自己哪里写错了还

Day 3 apacha

压轴,对于我这种废物小白,这道题确实有一丢丢难

其实就是个xxtea加密,但也是看了好多篇wp加之超级好的aa的帮助下才做完的
在这里插入图片描述

再把dword_5020里的数据转换成16进制数
在这里插入图片描述

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
void hex()
{
uint32_t v[] = { 35, 179, 78, 231, 54, 40, 167, 183, 226, 111,
202, 89, 193, 197, 124, 150, 116, 38, 128, 231,
230, 84, 45, 61, 86, 3, 157, 138, 156, 195,
220, 153, 237, 216, 38, 112, 173, 253, 51, 106,
10, 85, 150, 244, 158, 111, 156, 92, 76, 208,
229, 27, 23, 174, 35, 103, 194, 165, 112, 82,
10, 19, 66, 172, 178, 103, 190, 132, 121, 199,
92, 112, 152, 61, 81, 92, 45, 218, 54, 251,
69, 150, 23, 34, 157, 82, 227, 92, 251, 225,
137, 209, 137, 212, 91, 232, 31, 209, 200, 115,
150, 193, 181, 84, 144, 180, 124, 182, 202, 228,
23, 33, 148, 249, 227, 157, 170, 161, 90, 47,
253, 1, 232, 167, 171, 110, 13, 195, 156, 220,
173, 27, 74, 176, 83, 52, 249, 6, 164, 146, };
for (int i = 1; i <= 35; i++)
{
printf("0x");
for (int j = i * 4 - 1; j > (i - 1) * 4 - 1; j--)
if (v[j] < 16)
{
printf("0%x", v[j]);
}
else printf("%x", v[j]);
printf(", ");
}

}

对了,密钥的位置传入的是&v6,所以密钥就是1,2,3,4
在这里插入图片描述
上网搜解密脚本套用即可

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
#include <stdio.h>
#include <stdint.h>
#include<iostream>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
using namespace std;

uint32_t v3[] = { 0xe74eb323, 0xb7a72836, 0x59ca6fe2, 0x967cc5c1, 0xe7802674,
0x3d2d54e6, 0x8a9d0356,0x99dcc39c, 0x7026d8ed, 0x6a33fdad, 0xf496550a, 0x5c9c6f9e,
0x1be5d04c, 0x6723ae17, 0x5270a5c2, 0xac42130a,
0x84be67b2, 0x705cc779, 0x5c513d98, 0xfb36da2d, 0x22179645, 0x5ce3529d, 0xd189e1fb,
0xe85bd489, 0x73c8d11f,
0x54b5c196, 0xb67cb490, 0x2117e4ca, 0x9de3f994, 0x2f5aa1aa, 0xa7e801fd, 0xc30d6eab,
0x1baddc9c, 0x3453b04a, 0x92a406f9, };


void btea(uint32_t* v, int n, uint32_t const key[4])
{
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) /* Coding Part */
{
rounds = 3;
sum = 0;
z = v[n - 1];
do
{
sum += DELTA;
e = (sum >> 2) & 3;
for (p = 0; p < n - 1; p++)
{
y = v[p + 1];
z = v[p] += MX;
}
y = v[0];
z = v[n - 1] += MX;
} while (--rounds);
}
else if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 6 + 52 / n;
sum = rounds * DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p = n - 1; p > 0; p--)
{
z = v[p - 1];
y = v[p] -= MX;
}
z = v[n - 1];
y = v[0] -= MX;
sum -= DELTA;
} while (--rounds);
}
}



int main()
{

uint32_t const k[4] = { 1,2,3,4 };

int n = 35; //n的绝对值表示v的长度,取正表示加密,取负表示解密
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
//printf("加密前原始数据:%u %u\n", v[0], v[1]);
//btea(v, n, k);
// printf("加密后的数据:%u %u\n", v[0], v[1]);
btea(v3, -n, k);
for (int i = 0; i < 35; i++)
{
printf("%c", v3[i]);
}

return 0;
}

在这里插入图片描述

WEEK 2

Day 1 fake_debugger

这道题原理不难,就是题目出得。。。比较新颖?
在这里插入图片描述
大致就是把我们的输入和第一步ebx中存储的值进行某种运算,得到的值跟下一步中ebx的值比较,相等继续不相等报错

用开头hgame来看它做的是什么运算,h (104)和 23 和 127.。。。
盲猜异或,诶~对了,出题师傅真友好!(而且众所周知异或是可逆的。。

那接下来神仙可以写脚本爆破了,我这种废物只能一步步用给出的两个值推
例如,第二位就是

1
74^45=103   //g

顺便用我少得可怜python知识。。。给自己写个打空格的脚本。。。
(每次回来加一位flag,然后改变空格数

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

p=remote("101.132.177.131",9999)

a='aaaaaa'

payload='hgame{You_Kn0w_debuG'+a

p.sendline(payload)

p.recvuntil("OK,let's debug it! You can 'Step' by 'Space'!")

space=(' '+'\n')*0x29

p.sendline(space)

p.interactive()

不得不说这方法很笨。。。但。。我是废物(心安理得

Day 2 helloRE 2

第一部分的password
可以断在cmp比较的地方,直接是明文
在这里插入图片描述
然后我就被一堆一堆的函数搞蒙了
看了大佬的wp知道了是AES加密

第一部分的输入按位与1-15异或后传入password2进程,作密钥
(也可以理解为iv是1-15.。。。。
在这里插入图片描述
好心的lmy学长给了脚本来着
在这里插入图片描述