initial commit
This commit is contained in:
8
源码/source/clean.ps1
Normal file
8
源码/source/clean.ps1
Normal file
@@ -0,0 +1,8 @@
|
||||
# ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼Ϊ<C2BC>ű<EFBFBD><C5B1><EFBFBD><EFBFBD><EFBFBD>Ŀ¼
|
||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
Set-Location $scriptDir
|
||||
|
||||
Remove-Item "obfuscator/build" -Recurse -Force
|
||||
Remove-Item "task-src/pyhumor.py" -Force
|
||||
Remove-Item "task-src/pyhumor.pyc" -Force
|
||||
Remove-Item "task-src/pyhumor_runtime.cp310-win_amd64.pyd" -Force
|
63
源码/source/gen-attachment.ps1
Normal file
63
源码/source/gen-attachment.ps1
Normal file
@@ -0,0 +1,63 @@
|
||||
# ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼Ϊ<C2BC>ű<EFBFBD><C5B1><EFBFBD><EFBFBD><EFBFBD>Ŀ¼
|
||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
Set-Location $scriptDir
|
||||
|
||||
# ȷ<><C8B7> Python <20>汾Ϊ 3.10
|
||||
$pythonVersion = & python --version 2>&1
|
||||
if ($pythonVersion -notlike "Python 3.10*") {
|
||||
Write-Host "`n[!] Python <20>汾<EFBFBD><E6B1BE><EFBFBD><EFBFBD> 3.10<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>汾Ϊ $pythonVersion" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ
|
||||
Set-Location "obfuscator"
|
||||
Write-Host "`n[+] <20><><EFBFBD>ڱ<EFBFBD><DAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ...`n" -ForegroundColor Cyan
|
||||
$env:INCLUDE="$env:INCLUDE;C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared"
|
||||
$env:LIB="$env:LIB;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64"
|
||||
& python setup.py build
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "`n[!] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱʧ<CAB1>ܣ<EFBFBD>" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD> pycryptodome <20><>
|
||||
$pycryptodome = & pip list 2>&1 | Select-String "pycryptodome"
|
||||
if (-not $pycryptodome) {
|
||||
Write-Host "`n[!] pycryptodome <20><>δ<EFBFBD><CEB4>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD>װ..." -ForegroundColor Yellow
|
||||
& pip install pycryptodome
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "`n[!] <20><>װ pycryptodome <20><>ʧ<EFBFBD>ܣ<EFBFBD>" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# <20><><EFBFBD>ɻ<EFBFBD><C9BB><EFBFBD><EFBFBD>ű<EFBFBD>
|
||||
Set-Location "../task-src"
|
||||
Write-Host "`n[+] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɻ<EFBFBD><C9BB><EFBFBD><EFBFBD>ű<EFBFBD>..." -ForegroundColor Cyan
|
||||
& python get-obfuscated.py
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "`n[!] <20><><EFBFBD>ɻ<EFBFBD><C9BB><EFBFBD><EFBFBD>ű<EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD>" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# <20><><EFBFBD><EFBFBD> pyc <20><><EFBFBD><EFBFBD>
|
||||
& python get-task-pyc.py
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "`n[!] <20><><EFBFBD><EFBFBD> pyc <20><><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD>" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Write-Host "`n[+] <20><><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..." -ForegroundColor Cyan
|
||||
$zipFile = "../attachment.zip"
|
||||
if (Test-Path $zipFile) {
|
||||
Remove-Item $zipFile
|
||||
}
|
||||
Compress-Archive -Path pyhumor.pyc,pyhumor_runtime.cp310-win_amd64.pyd -DestinationPath $zipFile
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "`n[!] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD>" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "`n[+] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɳɹ<C9B3><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> clean.ps1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>" -ForegroundColor Green
|
||||
Set-Location $scriptDir
|
133
源码/source/obfuscator/pyhumor_runtime.c
Normal file
133
源码/source/obfuscator/pyhumor_runtime.c
Normal file
@@ -0,0 +1,133 @@
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#define Py_CPYTHON_FRAMEOBJECT_H
|
||||
#include "Python.h"
|
||||
#include "marshal.h"
|
||||
// #include "internal/pycore_frame.h"
|
||||
#include "cpython/frameobject.h"
|
||||
|
||||
#define ARGTYPE 1
|
||||
#include "libtomcrypt/headers/tomcrypt.h"
|
||||
|
||||
static const int MAJOR_VERSION = PY_MAJOR_VERSION;
|
||||
static const int MINOR_VERSION = PY_MINOR_VERSION;
|
||||
|
||||
const unsigned char *aes_key = "WAIT_TO_BE_FILLED";
|
||||
|
||||
// PyObject *CodeObject;
|
||||
|
||||
PyObject* PyHumorRuntime_HumorEnter(PyObject* self, PyObject* args) {
|
||||
PyFrameObject *frame = PyEval_GetFrame();
|
||||
PyCodeObject *f_code = frame->f_code;
|
||||
// PyCodeObject *f_code = PyFrame_GetCode(PyEval_GetFrame());
|
||||
PyObject *codearray = f_code->co_code;
|
||||
|
||||
Py_ssize_t size;
|
||||
unsigned char *data;
|
||||
PyBytes_AsStringAndSize(codearray, &data, &size);
|
||||
if (data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (size < 8 || size > 8192) {
|
||||
return NULL;
|
||||
}
|
||||
int use_size = (size - 8) - (size - 8) % 16;
|
||||
|
||||
symmetric_key skey;
|
||||
int err;
|
||||
if ((err = aes_setup(aes_key + 1, 16, 0, &skey)) != CRYPT_OK) {
|
||||
return NULL;
|
||||
}
|
||||
for (int i = 0; i < use_size; i += 16) {
|
||||
if ((err = aes_ecb_decrypt(data + i + 8, data + i + 8, &skey)) != CRYPT_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
aes_done(&skey);
|
||||
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject* PyHumorRuntime_RunCode(PyObject* self, PyObject* args) {
|
||||
PyObject* name;
|
||||
PyObject* file;
|
||||
char* bytecode;
|
||||
Py_ssize_t bytecodeSize;
|
||||
if (!PyArg_ParseTuple(args, "OOy#", &name, &file, &bytecode, &bytecodeSize)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Parse the code meta
|
||||
if (bytecodeSize < 16) {
|
||||
return NULL;
|
||||
}
|
||||
if (bytecode[9] != MAJOR_VERSION || bytecode[10] != MINOR_VERSION) {
|
||||
return NULL;
|
||||
}
|
||||
if (*(int*)(bytecode + 12) != bytecodeSize - 16) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Decrypt the bytecode
|
||||
symmetric_key skey;
|
||||
unsigned char *plaintext = malloc(bytecodeSize - 16);
|
||||
int err;
|
||||
if ((err = aes_setup(aes_key, 16, 0, &skey)) != CRYPT_OK) {
|
||||
return NULL;
|
||||
}
|
||||
for (int i = 0; i * 16 < bytecodeSize - 16; i++) {
|
||||
if ((err = aes_ecb_decrypt(bytecode + 16 + i * 16, plaintext + i * 16, &skey)) != CRYPT_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
aes_done(&skey);
|
||||
|
||||
// Load the code object
|
||||
PyObject *codeObject = PyMarshal_ReadObjectFromString(plaintext, bytecodeSize - 16);
|
||||
free(plaintext);
|
||||
if (codeObject == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Add __humor_enter__ function to the globals
|
||||
PyMethodDef humorEnterMethodDef =
|
||||
{"__humor_enter__", PyHumorRuntime_HumorEnter, METH_VARARGS, NULL};
|
||||
|
||||
PyObject* humorEnterFunc = PyCFunction_New(&humorEnterMethodDef, NULL);
|
||||
if (humorEnterFunc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject* globals = PyEval_GetGlobals();
|
||||
if (globals == NULL || PyDict_SetItemString(globals, "__humor_enter__", humorEnterFunc) < 0) {
|
||||
Py_DECREF(humorEnterFunc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_DECREF(humorEnterFunc); // Decrease reference count since it's now in the globals
|
||||
|
||||
// Run the code
|
||||
PyObject* result = PyImport_ExecCodeModuleObject(name, codeObject, file, NULL);
|
||||
Py_DECREF(codeObject);
|
||||
|
||||
// Remove __humor_enter__ function from the globals
|
||||
PyDict_DelItemString(globals, "__humor_enter__");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyMethodDef PyHumorRuntime_Methods[] = {
|
||||
{"__pyhumor__", PyHumorRuntime_RunCode, METH_VARARGS, NULL},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static struct PyModuleDef PyHumorRuntime_Module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"pyhumor_runtime",
|
||||
NULL,
|
||||
-1,
|
||||
PyHumorRuntime_Methods
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC PyInit_pyhumor_runtime(void) {
|
||||
return PyModule_Create(&PyHumorRuntime_Module);
|
||||
}
|
20
源码/source/obfuscator/setup.py
Normal file
20
源码/source/obfuscator/setup.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from distutils.core import setup, Extension
|
||||
|
||||
module1 = Extension('pyhumor_runtime',
|
||||
sources=[
|
||||
'pyhumor_runtime.c',
|
||||
'libtomcrypt/ciphers/aes/aes.c',
|
||||
'libtomcrypt/ciphers/aes/aes_desc.c',
|
||||
'libtomcrypt/ciphers/aes/aes_tab.c',
|
||||
# 'libtomcrypt/misc/crypt/crypt_argchk.c',
|
||||
'libtomcrypt/misc/zeromem.c',
|
||||
'libtomcrypt/misc/compare_testvector.c',
|
||||
],
|
||||
include_dirs=['libtomcrypt/headers'],
|
||||
define_macros=[('ARGTYPE', '1')],
|
||||
)
|
||||
|
||||
setup (name = 'pyhumor_runtime',
|
||||
version = '1.0',
|
||||
description = '',
|
||||
ext_modules = [module1])
|
7
源码/source/task-src/get-marshaled.py
Normal file
7
源码/source/task-src/get-marshaled.py
Normal file
@@ -0,0 +1,7 @@
|
||||
import marshal
|
||||
import dis
|
||||
|
||||
code = compile(open('plain.py').read(), "<frozen>", "exec")
|
||||
dis.dis(code)
|
||||
print(code.co_code, len(code.co_code))
|
||||
marshal.dump(code, open("plain.marshal", "wb"))
|
30
源码/source/task-src/get-obfuscated.py
Normal file
30
源码/source/task-src/get-obfuscated.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util.Padding import pad
|
||||
import marshal
|
||||
import os
|
||||
|
||||
aes_key = os.urandom(17)
|
||||
with open('../obfuscator/build/lib.win-amd64-cpython-310/pyhumor_runtime.cp310-win_amd64.pyd', 'rb') as fin:
|
||||
filled = fin.read().replace(b'WAIT_TO_BE_FILLED', aes_key)
|
||||
with open('pyhumor_runtime.cp310-win_amd64.pyd', 'wb') as fout:
|
||||
fout.write(filled)
|
||||
|
||||
code = compile(open('plain.py').read(), "<frozen>", "exec")
|
||||
raw = marshal.dumps(code)
|
||||
|
||||
code_len = len(code.co_code)
|
||||
encrypt_len = (code_len - 8) - (code_len - 8) % 16
|
||||
cipher = AES.new(aes_key[1:], AES.MODE_ECB)
|
||||
encrypted = cipher.encrypt(raw[38:38+encrypt_len])
|
||||
assert len(encrypted) == encrypt_len
|
||||
raw = raw[:38] + encrypted + raw[38+encrypt_len:]
|
||||
raw = pad(raw, 16)
|
||||
|
||||
cipher = AES.new(aes_key[:16], AES.MODE_ECB)
|
||||
encrypted = cipher.encrypt(raw)
|
||||
structured = b'PYHUMOR\x00\x00\x03\x0A\x00' + len(encrypted).to_bytes(4, 'little') + encrypted
|
||||
|
||||
open("pyhumor.py", "w").write(f'''from pyhumor_runtime import __pyhumor__
|
||||
|
||||
__pyhumor__(__name__, __file__, {repr(structured)})
|
||||
''')
|
3
源码/source/task-src/get-task-pyc.py
Normal file
3
源码/source/task-src/get-task-pyc.py
Normal file
@@ -0,0 +1,3 @@
|
||||
import py_compile
|
||||
|
||||
py_compile.compile('pyhumor.py', 'pyhumor.pyc')
|
35
源码/source/task-src/plain.py
Normal file
35
源码/source/task-src/plain.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# flag{9bc74ce3-a56d-467f-eb52-d5f3d8923c6f}
|
||||
|
||||
__humor_enter__()
|
||||
|
||||
try:
|
||||
from hashlib import sha256
|
||||
from functools import reduce
|
||||
|
||||
flag = input('Enter your flag: ')
|
||||
|
||||
group_1 = [
|
||||
int.from_bytes(flag[1::3].encode(), 'big') % 998244353 == 156881262,
|
||||
sha256(flag[-16:].encode()).hexdigest().endswith('dcf56476457880bf5b39b295416f267b7a636324baeae1fd'),
|
||||
reduce(lambda x, y: x ^ y, map(ord, flag)) == 2,
|
||||
]
|
||||
|
||||
if not all(group_1):
|
||||
print('Wrong')
|
||||
exit(1)
|
||||
|
||||
acc = 0
|
||||
for i in flag:
|
||||
i = ord(i) ^ 0x55
|
||||
acc |= i
|
||||
acc <<= (7 if i & 1 else 8)
|
||||
|
||||
if acc == 27473331342481820165679397757145329260017933200691317902624657196062576436414763023083043884214272:
|
||||
print('Right')
|
||||
else:
|
||||
print('Wrong')
|
||||
exit(1)
|
||||
|
||||
except:
|
||||
print('Stop reverse engineering me, enjoy your day :)')
|
||||
exit(1)
|
Reference in New Issue
Block a user