CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/shellcode/windows/x86/build.py
Views: 11784
1
#!/usr/bin/env python3
2
#=============================================================================#
3
# A simple python build script to build the singles/stages/stagers and
4
# some usefull information such as offsets and a hex dump. The binary output
5
# will be placed in the bin directory. A hex string and usefull comments will
6
# be printed to screen.
7
#
8
# Example:
9
# >python build.py stager_reverse_tcp_nx
10
#
11
# Example, to build everything:
12
# >python build.py all > build_output.txt
13
#
14
# Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
15
#=============================================================================#
16
import os
17
import sys
18
import time
19
from subprocess import Popen
20
from struct import pack
21
22
def clean(dir='./bin/'):
23
for root, dirs, files in os.walk(dir):
24
for name in files:
25
if name != '.keep':
26
os.remove(os.path.join(root, name))
27
28
def locate(src_file, dir='./src/'):
29
for root, dirs, files in os.walk(dir):
30
for name in files:
31
if src_file == name:
32
return root
33
return None
34
35
def build(name):
36
location = locate('%s.asm' % name)
37
if location:
38
input = os.path.normpath(os.path.join(location, name))
39
output = os.path.normpath(os.path.join('./bin/', name))
40
p = Popen(['nasm', '-f bin', '-O3', '-o %s.bin' %
41
output, '%s.asm' % input])
42
p.wait()
43
xmit(name)
44
else:
45
print("[-] Unable to locate '%s.asm' in the src directory" % name)
46
47
def xmit_dump_ruby(data, length=16):
48
dump = ''
49
for i in range(0, len(data), length):
50
bytes = data[i: i+length]
51
hex = "\"%s\"" % (''.join(['\\x%02X' % x for x in bytes]))
52
if i+length <= len(data):
53
hex += ' +'
54
dump += '%s\n' % (hex)
55
print(dump)
56
57
def xmit_offset(data, name, value, match_offset=0):
58
offset = data.find(value)
59
if offset != -1:
60
print('# %s Offset: %d' % (name, offset + match_offset))
61
62
def xmit(name, dump_ruby=True):
63
bin = os.path.normpath(os.path.join('./bin/', '%s.bin' % name))
64
f = open(bin, 'rb')
65
data = bytearray(f.read())
66
print('# Name: %s\n# Length: %d bytes' % (name, len(data)))
67
xmit_offset(data, 'Port', pack('>H', 4444)) # 4444
68
xmit_offset(data, 'LEPort', pack('<H', 4444)) # 4444
69
xmit_offset(data, 'Host', pack('>L', 0x7F000001)) # 127.0.0.1
70
xmit_offset(data, 'IPv6Host', pack(
71
'<Q', 0xBBBBBBBBBBBBBBB1)) # An IPv6 Address
72
xmit_offset(data, 'IPv6ScopeId', pack(
73
'<L', 0xAAAAAAA1)) # An IPv6 Scope ID
74
# hostname filler
75
xmit_offset(data, 'HostName',
76
b'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00')
77
xmit_offset(data, 'RetryCounter', b'\x6a\x05', 1) # socket retry
78
xmit_offset(data, 'CodeLen', pack('<L', 0x12345678)) # Filler
79
xmit_offset(data, 'Hostname', b'https')
80
# kernel32.dll!ExitThread
81
xmit_offset(data, 'ExitFunk', pack('<L', 0x0A2A1DE0))
82
# kernel32.dll!ExitProcess
83
xmit_offset(data, 'ExitFunk', pack('<L', 0x56A2B5F0))
84
# kernel32.dll!SetUnhandledExceptionFilter
85
xmit_offset(data, 'ExitFunk', pack('<L', 0xEA320EFE))
86
xmit_offset(data, 'ExitFunk', pack('<L', 0xE035F044)) # kernel32.dll!Sleep
87
xmit_offset(data, 'EggTag1', pack('<L', 0xDEADDEAD)) # Egg tag 1
88
xmit_offset(data, 'EggTag2', pack('<L', 0xC0DEC0DE)) # Egg tag 2
89
xmit_offset(data, 'EggTagSize', pack('>H', 0x1122)) # Egg tag size
90
xmit_offset(data, 'RC4Key', b'RC4KeyMetasploit') # RC4 key
91
xmit_offset(data, 'XORKey', b'XORK') # XOR key
92
if(name.find('egghunter') >= 0):
93
null_count = data.count('\x00')
94
if(null_count > 0):
95
print('# Note: %d NULL bytes found.' % (null_count))
96
if dump_ruby:
97
xmit_dump_ruby(data)
98
99
def main(argv=None):
100
if not argv:
101
argv = sys.argv
102
if len(argv) == 1:
103
print('Usage: build.py [clean|all|<name>]')
104
else:
105
print('# Built on %s\n' % (time.asctime(time.localtime())))
106
if argv[1] == 'clean':
107
clean()
108
elif argv[1] == 'all':
109
for root, dirs, files in os.walk('./src/egghunter/'):
110
for name in files:
111
build(name[:-4])
112
for root, dirs, files in os.walk('./src/migrate/'):
113
for name in files:
114
build(name[:-4])
115
for root, dirs, files in os.walk('./src/single/'):
116
for name in files:
117
build(name[:-4])
118
for root, dirs, files in os.walk('./src/stage/'):
119
for name in files:
120
build(name[:-4])
121
for root, dirs, files in os.walk('./src/stager/'):
122
for name in files:
123
build(name[:-4])
124
for root, dirs, files in os.walk('./src/kernel/'):
125
for name in files:
126
build(name[:-4])
127
else:
128
build(argv[1])
129
130
if __name__ == '__main__':
131
main()
132
133