Skip to content

Commit

Permalink
Merge pull request #46 from Squiblydoo/Tkinter-NSIS-Improvements
Browse files Browse the repository at this point in the history
NSIS improvements + Use case
  • Loading branch information
Squiblydoo committed Jul 27, 2024
2 parents 796523e + 3ba794b commit 4cd2158
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 77 deletions.
7 changes: 7 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
1.6.0
- Improves NSIS Parser to handle an irregular NSIS format
- Adds solution for Use Case 17
- Attackers can include junk marked as the code signing signature. In previous versions, the certificate preservation would preserve the junk. Without certificate preservation, the junk would be removed but return a Result Code of "0 - No Solution Found" even though the file was deflated.
- Bug Fix
- Adds error handling to escape non-unicode PE section names

1.5.6.6
- Bug Fix
- Patches bug in Result-Code 4 where an excess could be removed.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "debloat"
version = "1.5.6.6"
version = "1.6.0"
authors = [
{ name="Squiblydoo", email="Squiblydoo@pm.me" },
]
Expand Down
14 changes: 10 additions & 4 deletions src/debloat/gui.spec
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,13 @@ pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
exclude_binaries=True,
name='gui',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
Expand All @@ -43,3 +40,12 @@ exe = EXE(
entitlements_file=None,
icon=['debloat.ico'],
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='gui',
)
43 changes: 29 additions & 14 deletions src/debloat/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import debloat.utilities.nsisParser as nsisParser
import debloat.utilities.rsrc as rsrc

DEBLOAT_VERSION = "1.5.6.6"
DEBLOAT_VERSION = "1.6.0"

RESULT_CODES = {
0: "No Solution found.",
Expand All @@ -41,6 +41,8 @@
13: "Random overlay with high compression",
14: "Junk interspersed with data",
15: "VMProtected junk",
16: "InnoSetup Installer",
17: "Junk in the certificate",
}


Expand Down Expand Up @@ -75,7 +77,6 @@ def write_multiple_files(out_path: str,
log_message("")
log_message("The user will need to determine which file is malicious if any.")
log_message("If a file is bloated: resubmit it through the tool to debloat it.")
log_message(f"Consider reviewing the 'setup.nsis' from the installer to determine how the files were meant to be used.")
return


Expand All @@ -94,7 +95,8 @@ def write_patched_file(out_path: str,

def handle_signature_abnormality(signature_address: int,
signature_size: int,
beginning_file_size: int) -> bool:
beginning_file_size: int,
data_to_delete: List) -> Tuple[bool, int]:
'''Remove all bytes after a PE signature'''
# If the signature_address is 0, there was no original signature.
# We are setting the signature address to the filesize in order to
Expand All @@ -103,9 +105,19 @@ def handle_signature_abnormality(signature_address: int,
signature_address = beginning_file_size
# Check to see if there is data after the signature; if so, it is
# junk data
if beginning_file_size > (signature_address + signature_size):
return True
return False
signature_abnormality = False
if signature_size > (beginning_file_size - signature_size):
result_code = 17
signature_abnormality = True
elif beginning_file_size > (signature_address + signature_size):
result_code = 1
signature_abnormality = True

if signature_abnormality is True:
data_to_delete.append((signature_address + signature_size, beginning_file_size))
else:
result_code = 0
return signature_abnormality, result_code

def check_and_extract_NSIS(possible_header: bytearray, pe: pefile.PE) -> list:
'''Check if the PE is an NSIS installer.'''
Expand Down Expand Up @@ -503,6 +515,7 @@ def process_pe(pe: pefile.PE, out_path: str, last_ditch_processing: bool,

# Remove Signature and modify size of Optional Header Security entry.
signature_address, signature_size = get_signature_info(pe, cert_preservation)

if cert_preservation == True:
cert = [(signature_address, signature_address + signature_size)]
certData = memoryview(pe.__data__)[signature_address:signature_address + signature_size]
Expand All @@ -512,13 +525,12 @@ def process_pe(pe: pefile.PE, out_path: str, last_ditch_processing: bool,
log_message("""A certificate is being removed from this file.\n-To preserve the certificate use the Cert Preservation option.""")
data_to_delete = [(signature_address, signature_address + signature_size)]

signature_abnormality = handle_signature_abnormality(signature_address,
signature_abnormality, result_code = handle_signature_abnormality(signature_address,
signature_size,
beginning_file_size)
if signature_abnormality:
data_to_delete.append((signature_address + signature_size, beginning_file_size))
result_code = 1 # Junk after signture

beginning_file_size,
data_to_delete)
if signature_abnormality is True:
pass
# Handle Overlays: this includes packers and overlays which are completely junk
elif pe.get_overlay_data_start_offset() and signature_size < len(pe.__data__) - pe.get_overlay_data_start_offset():
possible_header = pe.__data__[pe.get_overlay_data_start_offset():pe.get_overlay_data_start_offset() + 30]
Expand Down Expand Up @@ -595,8 +607,11 @@ def process_pe(pe: pefile.PE, out_path: str, last_ditch_processing: bool,
start = slice_end
pe_data += bytearray(pe.__data__[start:beginning_file_size])
if cert_preservation == True and signature_size > 0:
pe_data += certData
pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']].VirtualAddress = len(pe_data) - signature_size
if result_code == 17:
log_message("Certificate is being used for junk and will be removed.")
else:
pe_data += certData
pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']].VirtualAddress = len(pe_data) - signature_size

pe.__data__ = pe_data
final_filesize, new_pe_name = write_patched_file(out_path,
Expand Down
Loading

0 comments on commit 4cd2158

Please sign in to comment.