lib/rex/post/meterpreter/extensions/extapi/service/service.rb
# -*- 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