好友
阅读权限20
听众
最后登录1970-1-1
|
本帖最后由 max2012 于 2026-4-2 16:36 编辑
-
用Exeinfo PE 0.0.8.8查看是Nuitka onefile 打包的 python脚本
-
用 NuitkaExtractorPro和nuitkaExtractor解包, 都出现很多文件名第一个字母缺失
-
通过阅读Nuitka可知,不需要提取,直接获取运行时释放出的临时文件即可。
另外也定位到了文件名缺失的原因
没有开启_NUITKA_ONEFILE_TEMP_BOOL
#define _NUITKA_ONEFILE_TEMP_BOOL 1
多读了crc32字段,导致后续文件名都被吃掉 一个字母,只有第一个文件名正常
#if _NUITKA_ONEFILE_TEMP_BOOL == 0
uint32_t contained_file_checksum = readPayloadChecksumValue();
uint32_t existing_file_checksum = getFileCRC32(target_path);
-
真正的脚本内容在dll,写个加载器方便动态注入
// crackme_hard.dll
HINSTANCE hGetProcIDDLL = LoadLibraryExW(
dll_filename,
NULL,
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR |
LOAD_LIBRARY_SEARCH_SYSTEM32 |
LOAD_LIBRARY_SEARCH_USER_DIRS
);
// 代码入口
nuitka_dll_function_ptr nuitka_dll_function = (nuitka_dll_function_ptr) GetProcAddress(hGetProcIDDLL, "run_code");
// 安装hook
parseConstantsBlob(hGetProcIDDLL);
hookLoadConstantsBlob(hGetProcIDDLL);
hookNuitka_Function_New(hGetProcIDDLL);
// 执行脚本功能代码
result = nuitka_dll_function(argc, argv);
结合Nuitka源码和IDA分析可确定hook入口地址
// Nuitka_Function_New
BYTE* ida_addr = (BYTE*) 0x313410170;
// loadConstantsBlob
BYTE* ida_addr = (BYTE*) 0x3133F0880;
-
loadConstantsBlob中解析常量池的对象内容如下
[HOOK] loadConstantsBlob called name:[__main__] count:83
====================== Dumping name:[__main__] count:[83] ==========================
Address of array: 00007FFF63B78100
Sizeof(array): 664 bytes
------+--------------------+--------------------+-------+---------------------
Index | Address (hex) | Value (ptr) | Type | Value
------+--------------------+--------------------+-------+---------------------
0 | 0x00007FFF63B78100 | 0x000002293FC2DBC0 | list | [b'646321613b6062', b'11', b'63616367', b'2f', b'1965212128',
b'0e', b'1f6226', b'0e', b'08626523', b'707070']
1 | 0x00007FFF63B78108 | 0x000002293FC7D860 | str | _parts
2 | 0x00007FFF63B78110 | 0x00007FFF667DD3B8 | int | 81
3 | 0x00007FFF63B78118 | 0x000002293FC7D890 | str | _key
4 | 0x00007FFF63B78120 | 0x00007FFF667DCD58 | int | 30
5 | 0x00007FFF63B78128 | 0x000002293FD622B0 | str | _total_len
6 | 0x00007FFF63B78130 | 0x000002293FD643F0 | str | 解密单个字符
7 | 0x00007FFF63B78138 | 0x000002293FC7D8C0 | str | current
8 | 0x00007FFF63B78140 | 0x000002293FD622F0 | str | _decrypt_char
9 | 0x00007FFF63B78148 | 0x000002293FD64440 | str | 获取指定位置的字符
10 | 0x00007FFF63B78150 | 0x00007FFF667E9AE8 | str | self
11 | 0x00007FFF63B78158 | 0x000002293FD62330 | str | _get_char_at_position
12 | 0x00007FFF63B78160 | 0x000002293FD64490 | str | 验证用户输入
13 | 0x00007FFF63B78168 | 0x000002293FC7D8F0 | str | total
14 | 0x00007FFF63B78170 | 0x000002293FD644E0 | str | 计算校验和
15 | 0x00007FFF63B78178 | 0x00007FFF667E1D00 | str | ''
16 | 0x00007FFF63B78180 | 0x000002293FC7D920 | str | flag
17 | 0x00007FFF63B78188 | 0x000002293FD62370 | str | checksum
18 | 0x00007FFF63B78190 | 0x000002293FD64530 | str | 获取目标校验和
19 | 0x00007FFF63B78198 | 0x000002293FC7D950 | str | hashlib
20 | 0x00007FFF63B781A0 | 0x000002293FC7D980 | str | sha256
21 | 0x00007FFF63B781A8 | 0x00007FFF667E6628 | str | encode
22 | 0x00007FFF63B781B0 | 0x000002293FD623B0 | str | hexdigest
23 | 0x00007FFF63B781B8 | 0x000002293FC556C0 | slice | slice(None, 8, None)
24 | 0x00007FFF63B781C0 | 0x00007FFF667DCB98 | int | 16
25 | 0x00007FFF63B781C8 | 0x000002293FD64580 | str | 哈希函数
26 | 0x00007FFF63B781D0 | 0x000002293FB9B190 | int | 305419896
27 | 0x00007FFF63B781D8 | 0x000002293FC7D9E0 | int | 2882400001
28 | 0x00007FFF63B781E0 | 0x000002293FB9B1B0 | int | 1380994890
29 | 0x00007FFF63B781E8 | 0x000002293FD623F0 | str | hash_input
30 | 0x00007FFF63B781F0 | 0x000002293FD645D0 | str | 假检查
31 | 0x00007FFF63B781F8 | 0x00007FFF666E8BF8 | str | print
32 | 0x00007FFF63B78200 | 0x000002293FC6FAF0 | tuple | (==================================================)
33 | 0x00007FFF63B78208 | 0x000002293FC6FDC0 | tuple | ( CrackMe Challenge - Binary Edition)
34 | 0x00007FFF63B78210 | 0x000002293FC7C3A0 | tuple | (Keywords: 52pojie, 2026, Happy New Year)
35 | 0x00007FFF63B78218 | 0x000002293FC7C730 | tuple | (Hint: 1337 5p34k & 5ymb0l5!)
36 | 0x00007FFF63B78220 | 0x000002293FC7DA20 | tuple | ( Try to decompile this in IDA!)
37 | 0x00007FFF63B78228 | 0x000002293FC7DA50 | tuple | (--------------------------------------------------)
38 | 0x00007FFF63B78230 | 0x000002293FD62430 | str | CrackMeCore
39 | 0x00007FFF63B78238 | 0x000002293FD64760 | str |
[?] Enter the password:
40 | 0x00007FFF63B78240 | 0x000002293FD62470 | str | fake_check
41 | 0x00007FFF63B78248 | 0x000002293FC7DA80 | tuple | (
[!] Close, but not quite there...)
42 | 0x00007FFF63B78250 | 0x000002293FD624B0 | str |
Press Enter to exit...
43 | 0x00007FFF63B78258 | 0x000002293FC7DAA0 | str | verify
44 | 0x00007FFF63B78260 | 0x000002293FD624F0 | str | get_target_checksum
45 | 0x00007FFF63B78268 | 0x000002293FC7DAE0 | tuple | (
==================================================)
46 | 0x00007FFF63B78270 | 0x000002293FC7DB10 | tuple | ( *** SUCCESS! ***)
47 | 0x00007FFF63B78278 | 0x000002293FC7DB40 | tuple | ([+] L33T H4X0R!)
48 | 0x00007FFF63B78280 | 0x000002293FD62570 | str | [+] Your answer:
49 | 0x00007FFF63B78288 | 0x000002293FD64850 | str |
[!] Checksum mismatch:
50 | 0x00007FFF63B78290 | 0x000002293FC7DB60 | str | !=
51 | 0x00007FFF63B78298 | 0x000002293FC7DBA0 | tuple | (
[X] Access Denied!)
52 | 0x00007FFF63B782A0 | 0x000002293FC7DBD0 | tuple | ([X] Wrong password!)
53 | 0x00007FFF63B782A8 | 0x000002293FD648A0 | str | 主函数
54 | 0x00007FFF63B782B0 | 0x00007FFF667E2A50 | str | __doc__
55 | 0x00007FFF63B782B8 | 0x00007FFF667E2B20 | str | __file__
56 | 0x00007FFF63B782C0 | 0x00007FFF666DEE80 | str | __cached__
57 | 0x00007FFF63B782C8 | 0x00007FFF667E23D8 | str | __annotations__
58 | 0x00007FFF63B782D0 | 0x00007FFF66702D78 | str | sys
59 | 0x00007FFF63B782D8 | 0x00007FFF667E34E0 | str | __main__
60 | 0x00007FFF63B782E0 | 0x00007FFF667E35B8 | str | __module__
61 | 0x00007FFF63B782E8 | 0x000002293FBAEC70 | str | 核心验证类 - 将被编译成二进制
62 | 0x00007FFF63B782F0 | 0x00007FFF667E39E0 | str | __qualname__
63 | 0x00007FFF63B782F8 | 0x00007FFF667E3090 | str | __init__
64 | 0x00007FFF63B78300 | 0x000002293FD62630 | str | CrackMeCore.__init__
65 | 0x00007FFF63B78308 | 0x000002293FD648F0 | str | CrackMeCore._decrypt_char
66 | 0x00007FFF63B78310 | 0x000002293FD64940 | str | CrackMeCore._get_char_at_position
67 | 0x00007FFF63B78318 | 0x000002293FD62670 | str | CrackMeCore.verify
68 | 0x00007FFF63B78320 | 0x000002293FD626B0 | str | CrackMeCore.checksum
69 | 0x00007FFF63B78328 | 0x000002293FD64990 | str | CrackMeCore.get_target_checksum
70 | 0x00007FFF63B78330 | 0x00007FFF666DC300 | str | main
71 | 0x00007FFF63B78338 | 0x000002293FC7DC00 | tuple | (
[!] Interrupted)
72 | 0x00007FFF63B78340 | 0x000002293FD62730 | str | crackme_hard.py
73 | 0x00007FFF63B78348 | 0x000002293FD62770 | str | <module>
74 | 0x00007FFF63B78350 | 0x000002293FC7DC30 | tuple | (self)
75 | 0x00007FFF63B78358 | 0x000002293FC4F1F0 | tuple | (self, part_idx, char_idx, encrypted_byte)
76 | 0x00007FFF63B78360 | 0x000002293FC736A0 | tuple | (self, pos, current, part_idx, part)
77 | 0x00007FFF63B78368 | 0x000002293FD649F0 | tuple | (self, s, total, i, c)
78 | 0x00007FFF63B78370 | 0x000002293FD62880 | tuple | (user_input, fake_hashes, user_hash)
79 | 0x00007FFF63B78378 | 0x000002293FD62980 | tuple | (self, flag, i)
80 | 0x00007FFF63B78380 | 0x000002293FC7DC60 | tuple | (s)
81 | 0x00007FFF63B78388 | 0x000002293FC72930 | tuple | (core, user_input, cs, target)
82 | 0x00007FFF63B78390 | 0x000002293FC729D0 | tuple | (self, user_input, i, expected)
------+--------------------+--------------------+-------+---------------------
-
在Nuitka_Function_New的hook代码中,对c_code安装hook
static void* __fastcall fake_Nuitka_Function_New(
function_impl_code_t c_code,
PyObject *name,
PyObject *qualname,
PyCodeObject *code_object,
PyObject *defaults,
PyObject *kw_defaults,
PyObject *annotations,
PyObject *module,
PyObject *doc,
void **closure,
Py_ssize_t closure_given)
{
void* result = g_pOriginal_Nuitka_Function_New(
c_code, name, qualname, code_object,
defaults, kw_defaults, annotations, module, doc,
closure, closure_given
);
install_code_impl_hook(result, c_code);
return result;
}
-
code_impl_hook 中 强制修改verify结果为True
static PyObject* __fastcall fake_func_impl_code(PyThreadState *tstate,
struct Nuitka_FunctionObject const *self, PyObject **python_pars)
{
const char* func_name=get_callable_name((PyObject *)self);
PyObject* result = pOld_func_impl_code(tstate, self, python_pars);
if ( !strcmp(func_name,"verify") && result==Py_False)
{
Py_XDECREF(result);
result = Py_True;
Py_INCREF(Py_True);
}
return result;
}
随便输入一个字符1
... ...
[?] Enter the password:1
[HOOK] fake_check:
arg_0 (user_input):[1]
[HOOK] hash_input:
arg_0 (s):[1]
[HOOK] hash_input return: [1803989619]
[HOOK] fake_check return: [False]
[HOOK] verify:
arg_0 (self):[<__main__.CrackMeCore object at 0x000002294003ED20>]
arg_1 (user_input):[1]
[HOOK] verify return: [False]
[HOOK] verify hack return: [True]
[HOOK] checksum:
-
代码能继续走到checksum,能抓输出正确的password
... ...
[HOOK] _decrypt_char return: [!]
[HOOK] _get_char_at_position return: [!]
[HOOK] _get_char_at_position:
arg_0 (self):[<__main__.CrackMeCore object at 0x000002294003ED20>]
arg_1 (pos):[29]
[HOOK] _decrypt_char:
arg_0 (self):[<__main__.CrackMeCore object at 0x000002294003ED20>]
arg_1 (part_idx):[9]
arg_2 (char_idx):[2]
[HOOK] _decrypt_char return: [!]
[HOOK] _get_char_at_position return: [!]
[HOOK] checksum:
arg_0 (self):[<__main__.CrackMeCore object at 0x000002294003ED20>]
arg_1 (s):[52p0j13@2026~H4ppy_N3w_Y34r!!!]
[HOOK] checksum return: [33753]
[HOOK] get_target_checksum return: [33753]
[!] Checksum mismatch: 49 != 33753
Press Enter to exit...
52p0j13@2026~H4ppy_N3w_Y34r!!!
|
免费评分
-
查看全部评分
|