105 lines
2.9 KiB
Ruby
105 lines
2.9 KiB
Ruby
# -*- coding: binary -*-
|
|
|
|
module Rex
|
|
module Post
|
|
module Meterpreter
|
|
module Extensions
|
|
module Extapi
|
|
module Service
|
|
|
|
###
|
|
#
|
|
# This meterpreter extension contains extended API functions for
|
|
# querying and managing Windows services.
|
|
#
|
|
###
|
|
class Service
|
|
|
|
SERVICE_OP_START = 1
|
|
SERVICE_OP_PAUSE = 2
|
|
SERVICE_OP_RESUME = 3
|
|
SERVICE_OP_STOP = 4
|
|
SERVICE_OP_RESTART = 5
|
|
|
|
def initialize(client)
|
|
@client = client
|
|
end
|
|
|
|
#
|
|
# Enumerate all the services on the target.
|
|
#
|
|
def enumerate
|
|
request = Packet.create_request(COMMAND_ID_EXTAPI_SERVICE_ENUM)
|
|
response = client.send_request(request)
|
|
|
|
services = []
|
|
|
|
response.each(TLV_TYPE_EXT_SERVICE_ENUM_GROUP) do |s|
|
|
services << {
|
|
:name => s.get_tlv_value(TLV_TYPE_EXT_SERVICE_ENUM_NAME),
|
|
:display => s.get_tlv_value(TLV_TYPE_EXT_SERVICE_ENUM_DISPLAYNAME),
|
|
:pid => s.get_tlv_value(TLV_TYPE_EXT_SERVICE_ENUM_PID),
|
|
:status => s.get_tlv_value(TLV_TYPE_EXT_SERVICE_ENUM_STATUS),
|
|
:interactive => s.get_tlv_value(TLV_TYPE_EXT_SERVICE_ENUM_INTERACTIVE)
|
|
}
|
|
end
|
|
|
|
services.sort_by { |s| s[:name].upcase }
|
|
end
|
|
|
|
#
|
|
# Query some detailed parameters about a particular service.
|
|
#
|
|
def query(service_name)
|
|
request = Packet.create_request(COMMAND_ID_EXTAPI_SERVICE_QUERY)
|
|
request.add_tlv(TLV_TYPE_EXT_SERVICE_ENUM_NAME, service_name)
|
|
|
|
response = client.send_request(request)
|
|
|
|
{
|
|
:starttype => response.get_tlv_value(TLV_TYPE_EXT_SERVICE_QUERY_STARTTYPE),
|
|
:display => response.get_tlv_value(TLV_TYPE_EXT_SERVICE_QUERY_DISPLAYNAME),
|
|
:startname => response.get_tlv_value(TLV_TYPE_EXT_SERVICE_QUERY_STARTNAME),
|
|
:path => response.get_tlv_value(TLV_TYPE_EXT_SERVICE_QUERY_PATH),
|
|
:logroup => response.get_tlv_value(TLV_TYPE_EXT_SERVICE_QUERY_LOADORDERGROUP),
|
|
:interactive => response.get_tlv_value(TLV_TYPE_EXT_SERVICE_QUERY_INTERACTIVE),
|
|
:dacl => response.get_tlv_value(TLV_TYPE_EXT_SERVICE_QUERY_DACL),
|
|
:status => response.get_tlv_value(TLV_TYPE_EXT_SERVICE_QUERY_STATUS)
|
|
}
|
|
end
|
|
|
|
#
|
|
# Control a single service
|
|
#
|
|
def control(service_name, op)
|
|
if op.is_a? String
|
|
case op.strip.downcase
|
|
when "start"
|
|
op = SERVICE_OP_START
|
|
when "pause"
|
|
op = SERVICE_OP_PAUSE
|
|
when "resume"
|
|
op = SERVICE_OP_RESUME
|
|
when "stop"
|
|
op = SERVICE_OP_STOP
|
|
when "restart"
|
|
op = SERVICE_OP_RESTART
|
|
end
|
|
end
|
|
|
|
unless (op.is_a? Integer) && op >= SERVICE_OP_START && op <= SERVICE_OP_RESTART
|
|
raise ArgumentError, "Invalid operation: #{op}"
|
|
end
|
|
|
|
request = Packet.create_request(COMMAND_ID_EXTAPI_SERVICE_CONTROL)
|
|
request.add_tlv(TLV_TYPE_EXT_SERVICE_CTRL_NAME, service_name)
|
|
request.add_tlv(TLV_TYPE_EXT_SERVICE_CTRL_OP, op)
|
|
client.send_request(request)
|
|
end
|
|
|
|
attr_accessor :client
|
|
|
|
end
|
|
|
|
end; end; end; end; end; end
|