/
safeheader.py
executable file
·114 lines (94 loc) · 3.84 KB
/
safeheader.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
109
110
111
112
113
114
#!/usr/bin/python3
"""
Add "safe header" to prevent accidental patching.
"""
import glob
import argparse
import sys
SAFE_HEADER = b'\xDE\xAD\xCA\xFE'
def write(fname, data):
'''
Purpose: write binary data to disk
Return: Boolean value indiciating success or false on IO failure
'''
try:
with open(fname, 'wb') as fout:
fout.write(data)
return True
except IOError as err:
print("[!] Error: %s" % (err))
return False
def recursive_check():
'''
perform recursive check for enduser input.
Return: Boolean for whether or not the user should continue..
'''
choice = input("Do you want to proceed? [Y/N]> ")
if choice.lower() not in ["y","n"]:
recursive_check()
elif choice.lower() == "y":
return True
else:
return False
def user_chk(samples):
'''
Check for user input prior to performing header patch.
Return: None
'''
print("safetyheader is about to be applied to the following files: ")
[print("\t" + x) for x in samples]
status = recursive_check()
if status is False:
print("[*] Quitting!")
sys.exit(0)
def header_manipulation(directory, patch=None, remove=None):
'''
Purpose: Add a fake header to a binary to prevent accidental execution in
the moving of malicious binaries.
Return: Boolean value.
'''
samples = glob.glob(directory)
user_chk(samples)
if patch is not None and remove is not None:
print("[!] Error, you cannot remove and patch the magicheader!")
return False
for sample in samples:
try:
with open(sample, "rb") as fin:
real_data = fin.read()
if real_data[0:4] == b'\xde\xad\xca\xfe' and remove is None:
print("[!] Safe header already exists within %s." % sample)
if real_data[0:4] == b'\xde\xad\xca\xfe' and remove is not None:
print("[*] Safe header identified in %s! Removing safe header!" % sample)
real_data = real_data[4:] # Remove safeheader
if write(sample, real_data):
print("[+] Successfully restored %s." % (sample))
else:
print("[!] Something went wrong restoring %s." % (sample))
if real_data[0:4] != b'\xde\xad\xca\xfe' and remove is not None:
print("[!] Magic header has already been removed")
if real_data[0:4] != b'\xde\xad\xca\xfe' and patch is not None:
new_binary = SAFE_HEADER + real_data
if write(sample, new_binary):
print("[+] Successfully patched %s with header %s" % (sample, SAFE_HEADER))
except IsADirectoryError:
print("[!] Error, specified directory forgot the '*'")
return False
return True
if __name__ == "__main__":
print("[--<Project Safe Header>--]")
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--dir", default="",
help="Specify directory to add safety header to.", required=True)
parser.add_argument("-r", "--remove", default=None, action="store_true",
help="Specify directory to remove safety header to.", required=False)
parser.add_argument("-p", "--patch", default=True, action="store_true",
help="Specify to patch binary or not.", required=False)
args = parser.parse_args()
if args.patch is not None and args.remove is not None:
print("[!!!] You cannot patch some binaries and remove the patch at the same time! [!!!]")
sys.exit(1)
if header_manipulation(args.dir, args.patch, args.remove):
print("[+] Successfully completed manipulation")
else:
print("[!] Something has gone horribly wrong with safeheader.")