This commit is contained in:
Mariusz B
2018-02-02 22:22:43 +01:00
commit c08aa59f9a
65 changed files with 8281 additions and 0 deletions

9
others/README.md Normal file
View 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
View 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
View 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

View 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)