Pinguw
Articles10
Tags3
Categories2

Categories

Archive

HASHCTF2024-Reverse题解

HASHCTF2024-Reverse题解

校赛也是ak re了,总排名第二,一等奖+Reverse单项最佳。

HASHCTF2024

一人干活,七人围观!

主要逻辑在这里:

8w1 8w2

是个多线程代码,线程影响v3的取值和异或的对象,直接上代码:

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
#include <cstdio>

void dec(unsigned char* enc)
{
char key[] = "HASH2024";

for(int round = 1; round <= 8; round++)
{
for(int count = 8; count >= 1;)
{
int v4 = 8 - count;
int v3 = ((4 * round) | round) ^ key[8 - count--];
for(int i = 0; i < 8; i++)
enc[v4 * 8 + i] ^= v3;
}
}

for(int i = 0; i < 64; i++)
printf("%c", enc[i]);
}

int main()
{
unsigned char enc_flag[] =
{
0x60, 0x69, 0x7B, 0x60, 0x6B, 0x7C, 0x6E, 0x53, 0x66, 0x18,
0x5F, 0x77, 0x7D, 0x77, 0x40, 0x1C, 0x5E, 0x1B, 0x77, 0x1B,
0x50, 0x58, 0x44, 0x18, 0x5A, 0x1B, 0x4C, 0x77, 0x1F, 0x40,
0x1B, 0x77, 0x4B, 0x18, 0x46, 0x4B, 0x7D, 0x5A, 0x02, 0x1A,
0x4D, 0x46, 0x4B, 0x51, 0x77, 0x18, 0x4E, 0x77, 0x1F, 0x40,
0x1B, 0x77, 0x6B, 0x77, 0x44, 0x1C, 0x46, 0x4F, 0x5D, 0x1C,
0x4F, 0x1B, 0x09, 0x55
};

dec((unsigned char*)enc_flag);

return 0;
}
8w3

HASHCTF{N1w_U_h4v3_3xpl0r3d_7h3_c0ncUr*2ency_0f_7h3_c_l4ngu4g3!}

解完之后想起来,既然加密是异或,大概率调试的时候把密文输入,那么最后判断时的结果就是flag,出题人的回答印证了我的猜想,不过是一血,没什么影响。

HEYGAP

Teaflower

十分钟秒杀题。

有壳去壳,有花去花,

壳是简单的upx一键去,花是简单的跳转全nop,

TEA的delta魔改了一下,直接写解密代码:

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
#include <iostream>
#include <cstdio>

void decrypt (uint32_t* v, uint32_t* k)
{
uint32_t v0 = v[0], v1 = v[1], sum = 0xBABEEAEA * 32;
uint32_t delta = 0xBABEEAEA;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for(int i = 0; i < 32; i++)
{
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
}
v[0] = v0;
v[1] = v1;
}

int main()
{
unsigned char enc_flag[] =
{
0x32, 0x31, 0x75, 0x08, 0x27, 0x72, 0xD5, 0x62, 0xE9, 0x2C,
0xA5, 0xAE, 0x98, 0x03, 0x5E, 0x4F, 0xEB, 0x25, 0xC3, 0xAD,
0xBB, 0x25, 0x49, 0x7D, 0x88, 0xAE, 0x9C, 0x73, 0x21, 0x37,
0xAA, 0x4D, 0x77, 0xA1, 0xBA, 0x08, 0xE9, 0xBB, 0x28, 0x29,
};
unsigned char key[32] = "HASH2024HASH2024";

for(int i = 0; i < 40; i += 8)
decrypt((unsigned int*)&enc_flag[i], (unsigned int*)key);

for(int i = 0; i < 40; i++)
printf("%c", enc_flag[i]);

return 0;
}
flower

HASHCTF{W0o0w_U_cAn_r3@11y_r3v3r53_14!!}

babycode

我忘了是怎么知道的以太坊虚拟机(大概是拷打GPT的时候它招的供词),找一个能把字节码还原成汇编的网站https://ethervm.io/decompile:

code1

发现有两处位置一直在push数据,将两块数据扒下来,后面还有XOR指令加上出题人提示,将两块数据异或,得到flag:

1
2
3
4
5
6
data1 = [0x1b, 0x24, 0x30, 0x3d, 0x31, 0x31, 0x0d, 0x3e, 0x0a, 0x0a, 0x4f, 0x67, 0x3a, 0x09, 0x51, 0x30, 0x08, 0x13, 0x32, 0x2b, 0x0d, 0x26, 0x3c, 0x24, 0x30, 0x78, 0x27, 0x67, 0x19, 0x2d, 0x57, 0x46, 0x57, 0x46, 0x2c, 0x07, 0x7e, 0x10, 0x4e]
data2 = [0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x4b, 0x45, 0x59, 0x3a, 0x20, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x43, 0x54, 0x46, 0x5f, 0x32, 0x30, 0x32, 0x34, 0x5f, 0x34, 0x5f, 0x31, 0x33]

for i in range(len(data1)):
print(chr(data1[i] ^ data2[i]), end = '')

codeflag

HASHCTF{S0o0_e2_evm_bytec0d3_revers3!!}

高速龙车驾驶员

直接运行报错需要支持库,走出题人不建议的路线loongarch交叉编译工具链(因为建议的路我不会走)

安装后里面有loongarch64-objdump,用他dump出文件的汇编代码和数据段:

Dragon1 Dragon2 Dragon3

对照出题人给的文档,分析汇编:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
sp -= 32
sp[8] = s1
sp[16] = s0
sp[24] = ra
a1 += 7612
t0 += 171
xr1 = a1
xr0 = a1[32]
t1 += 160
xr2 = t0
for (int i = 0; i < 4; i++)
xr0 ^= xr2
xr0 = a1[32]
xr3 = t1
a0 = 8
a0 = 152
for (int i = 0; i < 4; i++)
xr1 ^= xr3
a1[0] = xr1
...

关键部分如上:异或加密。

从扒出的数据段中做尝试,最终试出将data段与rodata段异或得到flag。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
data1 = [0x5e, 0x7f, 0xec, 0x4f, 0x32, 0x30, 0xbb, 0x6c, 0x6b, 0xd7, 0x69, 0x70, 0xd7, 0xba, 0x53, 0x37]
data2 = [0x80, 0Xef, 0X4c, 0X69, 0X92, 0X9c, 0X38, 0X91, 0X92, 0Xb6, 0X38, 0Xde, 0X28, 0X0e, 0Xcd, 0X63]
data3 = [0xcd, 0xa2, 0xc1, 0x23, 0xbd, 0x30, 0xf5, 0x3a, 0x26, 0x33, 0xda, 0xfc, 0xaf, 0xad, 0xfa, 0x2d]
data4 = [0x8d, 0x20, 0x54, 0x2b, 0x37, 0x91, 0x5e, 0xad, 0xd0, 0xf8, 0xb2, 0xe7, 0xea, 0xfe, 0xc1, 0xc7]

key1 = [0x16, 0x3e, 0xbf, 0x07, 0x71, 0x64, 0xfd, 0x17, 0x32, 0xb8, 0x1c, 0x2f, 0x88, 0xd1, 0x3d, 0x58]
key2 = [0xf7, 0xb0, 0x13, 0x36, 0xde, 0xf3, 0x08, 0xfe, 0xfd, 0x86, 0x57, 0xb1, 0x18, 0x60, 0xaa, 0x22]
key3 = [0xbf, 0xc1, 0xa9, 0x7c, 0xe2, 0x6f, 0xb9, 0x7b, 0x75, 0x6b, 0x85, 0xa3, 0xfc, 0xc2, 0xca, 0x42]
key4 = [0xe2, 0x10, 0x3b, 0x44, 0x07, 0xce, 0x01, 0xf2, 0x87, 0x9d, 0xde, 0x8b, 0xcb, 0xdf, 0xbc, 0xc7]

for i in range(len(data1)):
print(chr(data1[i] ^ key1[i]), end = '')
for i in range(len(data1)):
print(chr(data2[i] ^ key2[i]), end = '')
for i in range(len(data1)):
print(chr(data3[i] ^ key3[i]), end = '')
for i in range(len(data1)):
print(chr(data4[i] ^ key4[i]), end = '')
Dragonflag

HASHCTF{You__ know__ _ Lo0oo0oo0ngArch___ LASX_ _So0oo0oo0___Well!!}

xorust

简单恢复一下符号表:

go1

在func函数中找到关键部分:

go2

扒取数据:

go3

发现这些数据比input少一位,试着在最前面加 H或者在最后面加 }

写出解密代码:

1
2
3
4
5
6
7
8
9
10
11
data = [0x09, 0x12, 0x1B, 0x0B, 0x17, 0x12, 0x3D, 0x2C, 0x32, 0x54, 0x52, 0x53, 0x5D, 0x08, 0x3A, 0x10, 0x3A, 0x07, 0x2D, 0x0D, 0x27, 0x06, 0x27, 0x0B, 0x12, 0x0D, 0x33, 0x07, 0x47, 0x41, 0x2D, 0x6B, 0x5B, 0x30, 0x15, 0x7A, 0x59, 0x07, 0x31, 0x2B, 0x3C, 0x2D, 0x26, 0x2C, 0x22, 0x3D, 0x0D]

data[0] ^= ord('H')
print('H', end = '')

for i in range(1, len(data)):
data[i] ^= data[i - 1]

for i in data:
print(chr(i), end = '')

goflag

HASHCTF{We1c0me_Our_RusT_M@st3r_4o_J0in_tHeCoMp}

Author:Pinguw
Link:https://pinguw.github.io/2024/06/05/%E6%AF%94%E8%B5%9BWP/HASHCTF2024/
看完了吗,再去看看博主的其他文章叭:)