nkctf 逆向wp

First Post:

Last Update:

PMKF

可以看到一开始在c盘下创建一个nk.ctf文件(我当时做的时候并没有看到,只是静调做的)

image-20230331184500704

主代码:

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
int sub_9B1090()
{
int v1; // [esp+20h] [ebp-140h]
int v2; // [esp+24h] [ebp-13Ch]
int k; // [esp+2Ch] [ebp-134h]
int i; // [esp+30h] [ebp-130h]
int v5; // [esp+30h] [ebp-130h]
int j; // [esp+30h] [ebp-130h]
int v7; // [esp+30h] [ebp-130h]
char v8; // [esp+34h] [ebp-12Ch]
DWORD NumberOfBytesRead; // [esp+3Ch] [ebp-124h] BYREF
unsigned __int8 Buffer; // [esp+43h] [ebp-11Dh] BYREF
char v11[16]; // [esp+44h] [ebp-11Ch] BYREF
char v12[256]; // [esp+54h] [ebp-10Ch] BYREF

memset(v12, 0, sizeof(v12));
ReadFile(hObject, &Buffer, 1u, &NumberOfBytesRead, 0);
if ( Buffer != 5 )
{
sub_9B1690("Wrong!\n");
CloseHandle(hObject);
exit(0);
}
ReadFile(hObject, v12, Buffer, &NumberOfBytesRead, 0);
for ( i = 0; i < Buffer; ++i )
{
if ( v12[i] != byte_9B5100[i] )
{
sub_9B1690("Wrong!\n");
CloseHandle(hObject);
exit(0);
}
}
v5 = 0;
v8 = 0;
while ( v5 < Buffer )
v8 += v12[v5++];
ReadFile(hObject, v11, 0x10u, &NumberOfBytesRead, 0);
v2 = 18;
for ( j = 0; j < 16; ++j )
v11[j] ^= v8;
v7 = 0;
v1 = 1;
while ( v7 < 16 )
{
for ( k = 6; k >= 0; k -= 2 )
{
switch ( ((unsigned __int8)v11[v7] >> k) & 3 )
{
case 0:
v2 -= 18;
break;
case 1:
++v2;
break;
case 2:
v2 += 18;
break;
case 3:
--v2;
break;
default:
break;
}
if ( aN[v2] == 42 || aN[v2] == 32 )
{
v1 = 0;
break;
}
if ( aN[v2] == 75 )
{
sub_9B1690("Congratulations! you found it!\n");
break;
}
}
++v7;
}
CloseHandle(hObject);
return v1;
}

总体就是个迷宫题,先手动走走迷宫(复杂的话就上dfs,这个还好),得到路径:

1
1,1,2,2,3,3,2,2,1,2,2,3,2,2,1,1,0,1,1,1,1,1,0,1,0,0,0,0,0,1,0,1,1,2,1,1,0,1,1,1,2,2,2,3,2,3,3,0,3,3,2,3,2,2,1,1,1,1,1,2,2,3,3,3 

​ 官方题解是说这个就是输入值的四进制表示了,哼….看不出来

一个字符控制四步,直接暴力跑:

image-20230331185304578

(好抽象的代码)

跑出来的结果就是10进制下的步数。(杜师傅说有个地方是有两个解,我这个脚本出了结果就break了,导致没跑出第二个解,幸好flag用的是第一个解)

最后交flag需要转16进制……(肯定是出题人没说明白),这个是要每个字符转成对应的16进制,我直接把这一串数字当成一个大数转了,导致一直提交失败

not_a_like

010打开,发现是python打包的exeimage-20230331194354075

使用 PyInstaller Extractor 解包

使用方法:

  • 安装

下载v2.0版本的PyInstaller Extractor

github: https://github.com/extremecoders-re/pyinstxtractor

  • 使用
  1. 将需解包的exe与下载的pyinstxtractor.py存入同级文件夹

  2. 使用命令行输入如下指令, 得到exe的解包文件夹.

1
2
python pyinstxtractor.py {exe路径}
示例: python pyinstxtractor.py CreatFoder.exe

然后网上找个在线的pyc转py网站

结果:

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
# uncompyle6 version 3.9.0
# Python bytecode version base 3.8.0 (3413)
# Decompiled from: Python 3.6.12 (default, Feb 9 2021, 09:19:15)
# [GCC 8.3.0]
# Embedded file name: not_a_like.py
import libnum, base64, hashlib
from ctypes import *

def encrypt(text):
data_xor_iv = bytearray()
sbox = []
j = 0
x = y = k = 0
key = '911dcd09ad021d68780e3efed1aa8549'
for i in range(256):
sbox.append(i)
else:
for i in range(256):
j = j + sbox[i] + ord(key[i % len(key)]) & 255
sbox[i], sbox[j] = sbox[j], sbox[i]
else:
for idx in text:
x = x + 1 & 255
y = y + sbox[x] & 255
sbox[x], sbox[y] = sbox[y], sbox[x]
k = sbox[sbox[x] + sbox[y] & 255]
data_xor_iv.append(idx ^ k)
else:
return data_xor_iv


if __name__ == '__main__':
flag = input('请输入flag> ')
pub_key = [19252067118061066631831653736874168743759225404757996498452383337816071866700225650384181012362739758314516273574942119597579042209488383895276825193118297972030907899188520426741919737573230050112614350868516818112742663713344658825493377512886311960823584992531185444207705213109184076273376878524090762327, 76230002233243117494160925838103007078059987783012242668154928419914737829063294895922280964326704163760912076151634681903538211391318232043295054505369037037489356790665952040424073700340441976087746298068796807069622346676856605244662923296325332812844754859450419515772460413762564695491785275009170060931]
m = libnum.s2n(flag)
c = str(pow(m, pub_key[0], pub_key[1]))#这个e挺大的
q = b'EeJWrgtF+5ue9MRiq7drUAFPtrLATlBZMBW2CdWHRN73Hek7DPVIYDHtMIAfTcYiEV87W7poChqpyUXYI3+/zf5yyDOyE9ARLfa5qilXggu60lmQzFqvFv+1uOaeI2hs2wx+QZtxqGZzC0VCVWvbTQ52nA2UdUtnk8VezRMPMfmf7rOqPxDTv/aacLnI3RdLG2TbT52qtN4+naejI7Xe8HLOL765OZKdDBERKwd5ARQ3UL6YPbuOKOQahIFddnIX6rZ7dTNqCUDOjfJbMdrzJVDNjmNlkLNtYFo7M65Wfwj6PV5vvtT33FsmH50/YLEasnlCiJujYOgi2KCdf5msz1dPEvrXDDL6Csnjo+6m/44RzlluzcqMS5ZJFdrHEh68LIqtu+HCO+69Dyq4e22APq8wgN9kU6R8kikXSn/Ej0N/jOvomFCbkHskRl8xP1KgWFW0SMVDlaDCM4EKG812VgDWgSYOUnVhVpz65uOtg4Z8PrPI+BW4398dQYhD24D9EIPgvtmhNrHiEHouB46ElTGQgZBhtn6y9tL1sw=='
v = encrypt(base64.b64encode(c.encode('utf-8')))
v = base64.b64encode(v)
if v == q:
print('You are right!')
input('')
else:
print('winer winer winnie dinner')
print('Do you think the encryption and decryption are the same?')

大概加密流程就是先rsa加密,再转为base64进行rc4加密,与已知的q进行比较

rsa解密:(已知e,n,c,求明文m)