Honeycomb Plugins¶
This is the plugin repository for Honeycomb, the honeypot framework by Cymmetria.
Service API Reference¶
honeycomb.servicemanager.base_service module¶
Custom Service implementation from MazeRunner.
-
class
honeycomb.servicemanager.base_service.
DockerService
(*args, **kwargs)[source]¶ Bases:
honeycomb.servicemanager.base_service.ServerCustomService
Provides an ability to run a Docker container that will be monitored for events.
-
docker_image_name
¶ Return docker image name.
-
docker_params
¶ Return a dictionary of docker run parameters.
See also
Docker run: https://docs.docker.com/engine/reference/run/
Returns: Dictionary, e.g., dict(ports={80: 80})
-
-
class
honeycomb.servicemanager.base_service.
ServerCustomService
(alert_types: list, service_args: dict = {})[source]¶ Bases:
multiprocessing.context.Process
Custom Service Class.
This class provides a basic wrapper for honeycomb (and mazerunner) services.
-
alert_types
= None¶ List of alert types, parsed from config.json
-
alerts_queue
= None¶
-
emit
(**kwargs)[source]¶ Send alerts to logfile.
Parameters: kwargs – Fields to pass to honeycomb.decoymanager.models.Alert
-
logger
= <Logger honeycomb.servicemanager.base_service (DEBUG)>¶ Logger to be used by plugins and collected by main logger.
-
on_server_shutdown
()[source]¶ Shutdown function of the server.
Override this and take care to gracefully shut down your service (e.g., close files)
-
on_server_start
()[source]¶ Service run loop function.
The service manager will call this function in a new thread.
Note
Must call
signal_ready()
after finishing configuration
-
run_service
()[source]¶ Run the service and start an alert processing queue.
See also
Use
on_server_start()
andon_server_shutdown()
for starting and shutting down your service
-
service_args
= None¶ Validated dictionary of service arguments (see:
honeycomb.utils.plugin_utils.parse_plugin_args()
)
-
thread_server
= None¶
-
Integration API Reference¶
honeycomb.integrationmanager.integration_utils module¶
Honeycomb Integration Manager.
-
class
honeycomb.integrationmanager.integration_utils.
BaseIntegration
(integration_data)[source]¶ Bases:
object
Base Output Integration Class.
-
format_output_data
(output_data)[source]¶ Process and format the output_data returned by
send_event()
before display.This is currently only relevant for MazeRunner, if you don’t return an output this should return output_data without change.
Parameters: output_data – As returned by send_event()
Return type: dict Returns: MazeRunner compatible UI output. Raises: IntegrationOutputFormatError – If there’s a problem formatting the output data.
-
poll_for_updates
(integration_output_data)[source]¶ Poll external service for updates.
If service has enabled polling, this method will be called periodically and should act like
send_event()
Parameters: integration_output_data – Output data returned by previous send_event()
orpoll_for_updates()
Returns: See send_event()
Raises: IntegrationPollEventError – If there’s a problem polling for updates.
-
send_event
(alert_dict)[source]¶ Send alert event to external integration.
Parameters: alert_dict – A dictionary with all the alert fields.
Return type: tuple(dict(output_data), object(output_file))
Raises: - IntegrationSendEventError – If there’s a problem sending the event.
- IntegrationMissingRequiredFieldError – If a required field is missing.
Returns: A tuple where the first value is a dictionary with information to display in the UI, and the second is an optional file to be attached. If polling is enabled, the returned output_data will be passed to
poll_for_updates()
. If your integration returns nothing, you should return ({}, None).
-
Honeycomb Commands Reference¶
Honeycomb¶
Honeycomb is a honeypot framework.
Honeycomb [OPTIONS] COMMAND [ARGS]...
Options
-
-H
,
--home
<home>
¶ Honeycomb home path [default: /home/docs/.config/honeycomb]
-
--iamroot
¶
Force run as root (NOT RECOMMENDED!)
-
-c
,
--config
<config>
¶ Path to a honeycomb.yml file that provides instructions
-
-v
,
--verbose
¶
Enable verbose logging
-
--version
¶
Show the version and exit.
Environment variables
-
DEBUG
- Provide a default for
--verbose
integration¶
Honeycomb integration commands.
Honeycomb integration [OPTIONS] COMMAND [ARGS]...
configure¶
Configure an integration with default parameters.
You can still provide one-off integration arguments to honeycomb.commands.service.run()
if required.
Honeycomb integration configure [OPTIONS] INTEGRATION [ARGS]...
Options
-
-e
,
--editable
¶
Load integration directly from unspecified path without installing (mainly for dev)
-
-a
,
--show_args
¶
Show available integration arguments
Arguments
-
INTEGRATION
¶
Required argument
-
ARGS
¶
Optional argument(s)
install¶
Install a honeycomb integration from the online library, local path or zipfile.
Honeycomb integration install [OPTIONS] [INTEGRATIONS]...
Arguments
-
INTEGRATIONS
¶
Optional argument(s)
list¶
List integrations.
Honeycomb integration list [OPTIONS]
Options
-
-r
,
--remote
¶
Include available integrations from online repository
show¶
Show detailed information about a package.
Honeycomb integration show [OPTIONS] INTEGRATION
Options
-
-r
,
--remote
¶
Show information only from remote repository
Arguments
-
INTEGRATION
¶
Required argument
service¶
Honeycomb service commands.
Honeycomb service [OPTIONS] COMMAND [ARGS]...
install¶
Install a honeypot service from the online library, local path or zipfile.
Honeycomb service install [OPTIONS] [SERVICES]...
Arguments
-
SERVICES
¶
Optional argument(s)
list¶
List services.
Honeycomb service list [OPTIONS]
Options
-
-r
,
--remote
¶
Include available services from online repository
logs¶
Show logs of daemonized service.
Honeycomb service logs [OPTIONS] SERVICES...
Options
-
-n
,
--num
<num>
¶ Number of lines to read from end of file [default: 10]
-
-f
,
--follow
¶
Follow log output
Arguments
-
SERVICES
¶
Required argument(s)
run¶
Load and run a specific service.
Honeycomb service run [OPTIONS] SERVICE [ARGS]...
Options
-
-d
,
--daemon
¶
Run service in daemon mode
-
-e
,
--editable
¶
Load service directly from specified path without installing (mainly for dev)
-
-a
,
--show-args
¶
Show available service arguments
-
-i
,
--integration
<integration>
¶ Enable an integration
Arguments
-
SERVICE
¶
Required argument
-
ARGS
¶
Optional argument(s)
show¶
Show detailed information about a package.
Honeycomb service show [OPTIONS] SERVICE
Options
-
-r
,
--remote
¶
Show information only from remote repository
Arguments
-
SERVICE
¶
Required argument
status¶
Show status of installed service(s).
Honeycomb service status [OPTIONS] [SERVICES]...
Options
-
-a
,
--show-all
¶
Show status for all services
Arguments
-
SERVICES
¶
Optional argument(s)
stop¶
Stop a running service daemon.
Honeycomb service stop [OPTIONS] SERVICE
Options
-
-e
,
--editable
¶
Load service directly from specified path without installing (mainly for dev)
Arguments
-
SERVICE
¶
Required argument
test¶
Execute the service’s internal test method to verify it’s working as intended.
If there’s no such method, honeycomb will attempt to connect to the port listed in config.json
Honeycomb service test [OPTIONS] [SERVICES]...
Options
-
-f
,
--force
¶
Do not check if service is running before testing
-
-e
,
--editable
¶
Run service directly from specified path (main for dev)
Arguments
-
SERVICES
¶
Optional argument(s)
Services¶
Banner¶
services.banner.banner_service module¶
Honeycomb Banner Service.
Bases:
socketserver.StreamRequestHandler
Request handler for banner service.
Handle all requests by sending out our banner.
Bases:
base_service.ServerCustomService
Simple service that will print out banner and hang.
Stop banner service.
Start banner service.
Test service alerts and return a list of triggered event types.
Drupal¶
services.drupal.drupal_server module¶
A Drupal CMS server based on Python’s HTTPServer.
-
class
services.drupal.drupal_server.
DrupalServer
(logger, alert)[source]¶ Bases:
object
Drupal CMS honeypot.
services.drupal.drupal_service module¶
HP Officejet¶
services.hp_officejet.hp_officejet_server module¶
HP OfficeJet Server Module.
services.hp_officejet.hp_officejet_service module¶
Intel AMT¶
services.intel_amt.intel_amt_service module¶
Intel AMT Honeycomb Service.
-
class
services.intel_amt.intel_amt_service.
AMTServerHandler
(*args, directory=None, **kwargs)[source]¶ Bases:
http.server.SimpleHTTPRequestHandler
Intel AMT Request Handler.
-
server_version
= 'Intel(R) Active Management Technology 2.6.3'¶
-
-
class
services.intel_amt.intel_amt_service.
AMTService
(*args, **kwargs)[source]¶ Bases:
base_service.ServerCustomService
Intel AMT Honeycomb Service.
-
services.intel_amt.intel_amt_service.
service_class
¶
Micros¶
services.micros.micros_server module¶
Micros honeycomb server module.
-
class
services.micros.micros_server.
MicrosHandler
(*args, directory=None, **kwargs)[source]¶ Bases:
http.server.SimpleHTTPRequestHandler
Micros Request Handler.
-
alert_function
= None¶
-
db_info
= '0a10000000100018000000a073713349713550547466326b427353486170706c69636174696f6e2f6f637465742d73747265616d01e11e02000000360000003c00530049002d00530065006300750072006900740079002000560065007200730069006f006e003d0022003200220020002f003e00bd8c0000000000000000000001c11c0100000001d11d88960000355300000100000000000000000000001e000000240000000d004462496e666f5265717565737401000000010006006d5370617265080000000000001dd1021cc1021ee102'¶
-
do_POST
()[source]¶ Process POST request.
Examine the request to ensure it follows expected protocol answer predefined queries.
-
listening_port
= None¶
-
log_list
= '0c200000001000290000013872663850506e79467478667275366577687474703a2f2f736368656d61732e786d6c736f61702e6f72672f736f61702f656e76656c6f70652f0000003c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d227574662d38223f3e3c736f61703a456e76656c6f706520786d6c6e733a736f61703d22687474703a2f2f736368656d61732e786d6c736f61702e6f72672f736f61702f656e76656c6f70652f2220786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e63652220786d6c6e733a7873643d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d61223e3c736f61703a426f64793e3c50726f6365737344696d655265717565737420786d6c6e733d22687474703a2f2f6d6963726f732d686f7374696e672e636f6d2f45476174657761792f22202f3e3c2f736f61703a426f64793e3c2f736f61703a456e76656c6f70653e0a100000001000180000008e72663850506e794674786672753665776170706c69636174696f6e2f6f637465742d73747265616d01e11e02000000360000003c00530049002d00530065006300750072006900740079002000560065007200730069006f006e003d0022003200220020002f003e00a5980000000000000000000001c11c0100000001d11d98a20000b13600000100000000000000000000001e00000012000000050000000a000000240024006c006f0067001dd1021cc1021ee1020000'¶
-
logger
= None¶
-
micros_info
= '0a1000000010001800000084555651507039787a66697056536e4c756170706c69636174696f6e2f6f637465742d73747265616d01e11e02000000360000003c00530049002d00530065006300750072006900740079002000560065007200730069006f006e003d0022003200220020002f003e0058520000000000000000000001c11c0100000001d11db8580000b13600000100000000000000000000001e0000000800000000000000000000001dd1021cc1021ee102'¶
-
poc_suf2
= '001dd1021cc1021ee102'¶
-
poc_suf_1_1
= '0A100000001000180000'¶
-
poc_suf_1_2
= '6170706C69636174696F6E2F6F637465742D73747265616D01E11E02000000360000003C00530049002D00530065006300750072006900740079002000560065007200730069006F006E003D0022003200220020002F003E00C2AF0000000000000000000001C11C0100000001D11D8EBA0000B13600000100000000000000000000001E000000'¶
-
poc_suf_1_3
= '00000006000000'¶
-
poc_suf_1_4
= '000000240024'¶
-
poc_suf_1_ses
= '66497a3263516c56444c35305045356e'¶
-
protocol_version
= 'HTTP/1.1'¶
-
services.micros.micros_service module¶
Mirai Worm Monitor¶
services.mirai_worm_monitor.custom_pool module¶
Mirai Worm Gevent Pool.
services.mirai_worm_monitor.mirai_worm_monitor_service module¶
Simple HTTP¶
services.simple_http.simple_http_service module¶
Simple HTTP Honeycomb Service.
-
class
services.simple_http.simple_http_service.
HoneyHTTPRequestHandler
(*args, directory=None, **kwargs)[source]¶ Bases:
http.server.SimpleHTTPRequestHandler
,object
Simple HTTP Request Handler.
-
server_version
= 'nginx'¶
-
-
class
services.simple_http.simple_http_service.
SimpleHTTPService
(*args, **kwargs)[source]¶ Bases:
base_service.ServerCustomService
Simple HTTP Honeycomb Service.
-
httpd
= None¶
-
-
class
services.simple_http.simple_http_service.
ThreadingHTTPServer
(server_address, RequestHandlerClass, bind_and_activate=True)[source]¶ Bases:
socketserver.ThreadingMixIn
,http.server.HTTPServer
Threading HTTP Server stub class.
-
services.simple_http.simple_http_service.
service_class
¶ alias of
services.simple_http.simple_http_service.SimpleHTTPService
WebLogic¶
services.weblogic.weblogic_server module¶
Oracle WebLogic Honeycomb Module.
-
class
services.weblogic.weblogic_server.
WebLogicHandler
(*args, directory=None, **kwargs)[source]¶ Bases:
http.server.SimpleHTTPRequestHandler
Oracle WebLogic Request Handler.
-
EXPLOIT_STRING
= b'</void>'¶
-
GENERIC_RESPONSE
= '<?xml version=\'1.0\' encoding=\'UTF-8\'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope"><faultcode>S:Server</faultcode><faultstring>The current event is not START_ELEMENT but 2</faultstring></S:Fault></S:Body></S:Envelope>'¶
-
PATCHED_RESPONSE
= '<?xml version=\'1.0\' encoding=\'UTF-8\'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope"><faultcode>S:Server</faultcode><faultstring>Invalid attribute for element void:class</faultstring></S:Fault></S:Body></S:Envelope>'¶
-
alert_function
= None¶
-
basepath
= '/home/docs/checkouts/readthedocs.org/user_builds/honeycomb-plugins/checkouts/latest/services/weblogic'¶
-
logger
= None¶
-
protocol_version
= 'HTTP/1.1'¶
-
services.weblogic.weblogic_service module¶
Integrations¶
Cuckoo¶
JSON File¶
integrations.json_file.integration module¶
Honeycomb JSON integration.
-
integrations.json_file.integration.
IntegrationActionsClass
¶
MISP¶
integrations.misp.integration module¶
Honeycomb MISP integration.
-
integrations.misp.integration.
IntegrationActionsClass
¶
-
class
integrations.misp.integration.
MISPIntegration
(integration_data)[source]¶ Bases:
integrationmanager.integration_utils.BaseIntegration
Honeycomb MISP integration.
-
misp
= None¶ MISP instance.
-
misp_dict
= {'MD5': [('add_hashes', 'md5')], 'additional_fields': '', 'domain': ['add_domain'], 'image_path': [('add_filename', 'filename'), ('add_attachment', 'attachment')], 'image_sha256': [('add_hashes', 'sha256')], 'originating_hostname': [('add_hostname', 'hostname')], 'originating_ip': [('add_ipsrc', 'ipsrc')]}¶ A list of methods to call on event. Methods are tuples of (method_name, value_kwarg).
-
send_event
(alert_dict)[source]¶ Send MISP event.
PyMISP parameters are passed directly to requests. The ssl parameter can be either True/False to control requests.Session.verify, but can also be a path to CA cert file
-
test_connection
(data)[source]¶ Test connectivity to MISP and fetch details about server.
Parameters are passed directly to PyMISP which in turn passes them to requests. The ssl parameter can be either True/False to control verify_ssl but can also be a path to CA cert file .. seealso:: http://docs.python-requests.org/en/master/user/advanced/#ssl-cert-verification
-
Syslog¶
integrations.syslog.integration module¶
Honeycomb Syslog integration.
-
class
integrations.syslog.integration.
CEFCustomString
(field_name: str, field_label: str, field_label_text: str)[source]¶ Bases:
integrations.syslog.integration.CEFField
Custom CEF Field.
-
class
integrations.syslog.integration.
CEFField
(field_name: str)[source]¶ Bases:
object
Generic CEF Field.
-
integrations.syslog.integration.
IntegrationActionsClass
¶
-
class
integrations.syslog.integration.
MySysLogHandler
(address, facility=1, socktype=<SocketKind.SOCK_DGRAM: 2>, ssl_enabled=False)[source]¶ Bases:
logging.handlers.SysLogHandler
Custom Syslog logging handler that includes CEFEvent.
For some reason python SysLogHandler appends x00 byte to every record sent, This fixes it and replaces it with n.
Writing your first plugin¶
Using simple_http as an example to accompany this guide, we will describe the 4 steps necessary to write a plugin. Feel free to use the provided config.json as a base for your own, and modify fields as required. It is recommended, for the sake of organization, that you create a new directory and follow this guide inside your specific plugin’s directory.
Note
If you’re looking for the full documentation for Honeycomb API look at base_service
and
integration_utils
Plugin configuration - config.json¶
The config.json file describes the possible parameters your service can receive, and alerts it can emit. simple_http’s config.json looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | {
"event_types": [
{
"name": "simple_http",
"label": "HTTP Server Interaction",
"fields": ["originating_ip", "originating_port", "request"],
"policy": "Alert"
}
],
"service": {
"allow_many": false,
"supported_os_families": "All",
"ports": [
],
"name": "simple_http",
"label": "Simple HTTP Server",
"description": "Simple HTTP Server that alerts on every request",
"conflicts_with": []
},
"parameters": [
{
"type": "integer",
"value": "port",
"label": "Listening Port",
"required": true
},
{
"type": "text",
"value": "version",
"label": "Server version (header)",
"required": true,
"default": "nginx"
},
{
"type": "boolean",
"value": "threading",
"label": "Enable threading support",
"required": true,
"default": false
}
]
}
|
The event_types field describes alerts. This is the most important part of the configuration, as it’s the way Honeycomb detects and logs suspicious events. There can be multiple alerts for each honeypot, as long as each alert is described by this structure.
Let’s break down the structure:
name: | This is the internal identifier of the alert. Your python script should emit an alert matching name in order for it to be recognized and formatted. |
---|---|
label: | Human-readable name of the alert. This is the description of the alert. |
fields: | An alert can take any number of parameters and output them when it triggers. This describes the parameters it takes. |
policy: | This can be “Alert” or “Mute”, for future use. |
Next, we’ll look at the service field. It describes the service generally and is used to avoid conflicts between honeypots that run simultaneously:
allow_many: | Allow multiple instances of this honeypot? |
---|---|
supported_os_families: | |
This prevents OS-specific honeypots from being installed on the wrong system. Current valid values are “Linux”, “Windows”, “Darwin”, and “All”. | |
ports: | Any ports this honeypot uses. For simple_http, you would expect port 80, but the service actually takes its port as a parameter. |
name: | Internal service name. |
label: | Human readable name. |
description: | Full fledged description of the service. |
conflicts_with: | Specific honeypots that this one conflicts with for whatever reason. You don’t have to fill this field in, but if you know of conflicts you should. |
And finally, the parameters field describes optional and non-optional parameters that your service can receive. Each parameter is described as follows:
type: | The json type of the parameter. |
---|---|
value: | Parameter name. |
label: | Parameter description. |
required: | Set to true if parameter is mandatory, or false if optional. |
default: | Default value. |
Honeypot logic¶
Filename¶
Create a python file and name it (honeypot_name)_service.py. For example: simple_http_service.py.
Imports¶
Add the following import at the top of your service module:
from base_service import ServerCustomService
Plugin logic¶
Create your plugin by defining a class that inherits from base_service.ServerCustomService
, for example:
class SimpleHTTPService(ServerCustomService):
We will address most of ServerCustomService
’s API but make sure to also review its documentation for
additional help. For example, it contains its own logger which is configured to record logs accross the framework.
Entry and exit¶
Your entry point will be the on_server_start()
method. If you need an exit and cleanup point,
that’s on_server_shutdown()
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | def on_server_start(self):
"""Initialize Service."""
os.chdir(os.path.join(os.path.dirname(__file__), "www"))
requestHandler = HoneyHTTPRequestHandler
requestHandler.alert = self.alert
requestHandler.logger = self.logger
requestHandler.server_version = self.service_args.get("version", DEFAULT_SERVER_VERSION)
port = self.service_args.get("port", DEFAULT_PORT)
threading = self.service_args.get("threading", False)
if threading:
self.httpd = ThreadingHTTPServer(("", port), requestHandler)
else:
self.httpd = HTTPServer(("", port), requestHandler)
self.signal_ready()
self.logger.info("Starting {}Simple HTTP service on port: {}".format("Threading " if threading else "", port))
self.httpd.serve_forever()
|
1 2 3 4 5 6 | def on_server_shutdown(self):
"""Shut down gracefully."""
if self.httpd:
self.httpd.shutdown()
self.logger.info("Simple HTTP service stopped")
self.httpd = None
|
Note
on_server_start()
must call signal_ready()
to let the framework know it has successfully
initialized and started working.
In simple_http, once we call on_server_shutdown()
, execution flows into an infinite loop and so we must call
on_server_shutdown()
beforehand.
Parameters¶
If your service receives parameters, you can access them via service_args, supplying it with the parameter value from before. For example, in simple_http:
port = self.service_args.get('port', DEFAULT_PORT)
Connecting the plugin¶
Your __main__ should consist of only one line:
service_class = (your_plugin_class_name)
For example, in simple_http:
service_class = SimpleHTTPService
Reporting alerts¶
The last vital stage in writing a useful plugin for Honeycomb is making it actually trigger alerts in case something
bad happens. For this, add_alert_to_queue()
is your method of choice. Supply it with a single parameter,
a dictionary containing all the fields described in the alert as defined in your config.json, and event_name
should contain the alert name. For example, simple_http defined one alert called simple_http, containing three fields:
“originating_ip”, “originating_port”, and “request”. A matching alert may look like this:
self.add_alert_to_queue({
"event_type" : "simple_http",
"originating_ip" : client.ip,
"originating_port" : client.port,
"request" : request.content
})
Test your service¶
It is recommended you override the test()
method in your plugin class that returns triggers your alerts and
returns a list to verify. The framework will automatically execute your test method and make sure all the listed
alerts have been triggered successfully.
External Requirements¶
If your service depends on external modules, you can add them to a requirements.txt and the framework will install them in a virtual environment that will be loaded with you run the service.
It is recommended that you take simple_http as a skeleton of a service and modify it as necessary for your first honeypot. To install your new honeypot, ‘honeycomb service install (directoryname)’ on the chosen plugin directory, followed by ‘honeycomb service run (pluginname)’. For more commands, read http://honeycomb.cymmetria.com/en/latest/cli.html#honeycomb-service.
Have fun!