mirror of
https://github.com/nmap/nmap.git
synced 2026-01-06 14:39:03 +00:00
o [NSE] Added the script redis-info that lists version and statistic information
gathered from the Redis network key-value store. [Patrik] o [NSE] Added the script redis-brute that performs brute force password guessing against the Redis network key-value store. [Patrik]
This commit is contained in:
142
nselib/redis.lua
Normal file
142
nselib/redis.lua
Normal file
@@ -0,0 +1,142 @@
|
||||
|
||||
|
||||
|
||||
module(... or "redis", package.seeall)
|
||||
|
||||
local match = require 'match'
|
||||
|
||||
|
||||
Request = {
|
||||
|
||||
new = function(self, cmd, ...)
|
||||
local o = { cmd = cmd, args = {...} }
|
||||
setmetatable (o,self)
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
__tostring = function(self)
|
||||
local output = ("*%s\r\n$%d\r\n%s\r\n"):format(#self.args + 1, #self.cmd, self.cmd)
|
||||
|
||||
for _, arg in ipairs(self.args) do
|
||||
arg = tostring(arg)
|
||||
output = output .. ("$%s\r\n%s\r\n"):format(#arg, arg)
|
||||
end
|
||||
|
||||
return output
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
|
||||
Response = {
|
||||
|
||||
Type = {
|
||||
STATUS = 0,
|
||||
ERROR = 1,
|
||||
INTEGER = 2,
|
||||
BULK = 3,
|
||||
MULTIBULK = 4,
|
||||
},
|
||||
|
||||
new = function(self, socket)
|
||||
local o = { socket = socket }
|
||||
setmetatable (o,self)
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
receive = function(self)
|
||||
local status, data = self.socket:receive_buf("\r\n")
|
||||
if ( not(status) ) then
|
||||
return false, "Failed to receive data from server"
|
||||
end
|
||||
|
||||
-- if we have a status, integer or error message
|
||||
if ( data:match("^[%-%+%:]") ) then
|
||||
local response = { data = data }
|
||||
local t = data:match("^([-+:])")
|
||||
if ( t == "-" ) then
|
||||
response.type = Response.Type.ERROR
|
||||
elseif ( t == "+" ) then
|
||||
response.type = Response.Type.STATUS
|
||||
elseif ( t == ":" ) then
|
||||
response.type = Response.Type.INTEGER
|
||||
end
|
||||
|
||||
return true, response
|
||||
end
|
||||
|
||||
-- process bulk reply
|
||||
if ( data:match("^%$") ) then
|
||||
-- non existing key
|
||||
if ( data == "$-1" ) then
|
||||
return true, nil
|
||||
end
|
||||
|
||||
local len = tonumber(data:match("^%$(%d*)"))
|
||||
-- we should only have a single line, so we can just peel of the length
|
||||
status, data = self.socket:receive_buf(match.numbytes(len))
|
||||
if( not(status) ) then
|
||||
return false, "Failed to receive data from server"
|
||||
end
|
||||
|
||||
return true, { data = data, type = Response.Type.BULK }
|
||||
end
|
||||
|
||||
-- process multi-bulk reply
|
||||
if ( data:match("^%*%d*") ) then
|
||||
local count = data:match("^%*(%d*)")
|
||||
local results = {}
|
||||
|
||||
for i=1, count do
|
||||
-- peel of the length
|
||||
local status = self.socket:receive_buf("\r\n")
|
||||
if( not(status) ) then
|
||||
return false, "Failed to receive data from server"
|
||||
end
|
||||
|
||||
status, data = self.socket:receive_buf("\r\n")
|
||||
if( not(status) ) then
|
||||
return false, "Failed to receive data from server"
|
||||
end
|
||||
table.insert(results, data)
|
||||
end
|
||||
return true, { data = results, type = MULTIBULK }
|
||||
end
|
||||
|
||||
return false, "Unsupported response"
|
||||
end,
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Helper = {
|
||||
|
||||
new = function(self, host, port)
|
||||
local o = { host = host, port = port }
|
||||
setmetatable (o,self)
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
connect = function(self)
|
||||
self.socket = nmap.new_socket()
|
||||
return self.socket:connect(self.host, self.port)
|
||||
end,
|
||||
|
||||
reqCmd = function(self, cmd, ...)
|
||||
local req = Request:new(cmd, ...)
|
||||
local status, err = self.socket:send(tostring(req))
|
||||
if (not(status)) then
|
||||
return false, "Failed to send command to server"
|
||||
end
|
||||
return Response:new(self.socket):receive()
|
||||
end,
|
||||
|
||||
close = function(self)
|
||||
return self.socket:close()
|
||||
end
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user