-
-
Notifications
You must be signed in to change notification settings - Fork 139
Developer Guidelines
it contains framework default configs.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import socket
from core.time_helper import hours
from core.compatible import generate_token
# Protocol number to protocol string table
protocol_table = {
num: name[8:]
for name, num in vars(socket).items()
if name.startswith("IPPROTO")
}
real_machine_ip_address = socket.gethostbyname(socket.gethostname())
def api_configuration():
"""
API Config (could be modify by user)
Returns:
a JSON with API configuration
"""
# DOCKER_ENV variable is set in the docker-compose file.
if os.environ.get('ELASTICSEARCH_DOCKER_ENV') == "true":
db_url = "elasticsearch:9200"
else:
db_url = "127.0.0.1:9200"
return { # OWASP Honeypot API Default Configuration
"api_host": "0.0.0.0",
"api_port": 5000,
"api_debug_mode": False,
"api_access_without_key": True,
"api_access_key": generate_token(), # or any string, or None
"api_client_white_list": {
"enabled": False,
"ips": [
"127.0.0.1",
"10.0.0.1",
"192.168.1.1"
]
},
"api_access_log": {
"enabled": False,
"filename": "ohp_api_access.log"
},
"api_database": db_url,
"api_database_http_auth": ('elastic', 'changeme')
}
def network_configuration():
"""
network configuration
Returns:
JSON/Dict network configuration
"""
return {
"store_network_captured_files": False,
"real_machine_ip_address": real_machine_ip_address,
"ignore_real_machine_ip_address": True, # or if you want to simulate from local network, save as False
"ignore_virtual_machine_ip_addresses": True, # or if you want simulate from local network, save as False
"real_machine_identifier_name": "stockholm_server_1", # can be anything e.g. real_machine_ip_address, name, etc
"ignore_real_machine_ip_addresses": list(
{
real_machine_ip_address,
"127.0.0.1"
}
),
# e.g. ["10.0.0.1", "192.168.1.1"]
"ignore_real_machine_ports": [], # e.g. [22, 80, 5000]
"split_pcap_file_timeout": 3600 # Default value
}
def docker_configuration():
"""
docker configuration
Returns:
JSON/Dict docker configuration
"""
return {
"virtual_machine_storage_limit": 0.5, # Gigabyte
"virtual_machine_container_reset_factory_time_seconds": hours(-1), # -1 is equals to never reset!
}
def user_configuration():
"""
user configuration
Returns:
JSON/Dict user configuration
"""
return {
"language": "en_US",
"events_log_file": "tmp/ohp.log",
"default_selected_modules": "all", # or select one or multiple (e.g. ftp/strong_password,ssh/strong_password)
"default_excluded_modules": None # or any module name separated with comma
}
def sentry_configuration() -> dict:
"""
sentry configuration
Returns:
JSON/Dict sentry configuration
"""
return {
"sentry_monitoring": False,
# Enter your Sentry Project URL here.
"sentry_dsn_url": "",
# Enter Trace Rate Here.
"sentry_trace_rate": 1
# Set sentry_trace_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
# sentry_trace_rate is ratio of errors being
# reported to the number of issues which arise.
}
every category (e.g. ftp
, http
, ssh
) have their own configuration in __init__.py
. feel free to customize them.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def category_configuration():
"""
category configuration
Returns:
JSON/Dict category configuration
"""
return {
"virtual_machine_name": "ohp_ftpserver",
"virtual_machine_port_number": 21,
"virtual_machine_internet_access": True,
"real_machine_port_number": 21
}
every module (e.g. ftp/weak_password
) have their own configuration in __init__.py
. feel free to customize them.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def module_configuration():
"""
module configuration
Returns:
JSON/Dict module configuration
"""
return {
"username": "admin",
"password": "admin",
"extra_docker_options": ["--volume {0}/tmp/ohp_ftp_weak_container/:/root:z".format(os.getcwd())],
"module_processor": ModuleProcessor()
}
To use multiple modules in the same category and avoid ports confliction, you must replace
the real_machine_port_number
by adding them to modules. you can replace ANY category configuration by adding the
keys to the module configuration.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def module_configuration():
"""
module configuration
Returns:
JSON/Dict module configuration
"""
return {
"username": "admin",
"password": "admin",
"virtual_machine_port_number": 21
# you can add anything in here to avoid the default category configuration
# "virtual_machine_internet_access": False
}
Any module may require to copy a file/service/configuration in the image, the easiest way to do this in the framework,
you can use docker COPY
or ADD
command in Dockerfile, but you must locate all your files
in modules/protocol/moduleOrType/files
.
# copy vsftpd.conf to /etc/vsftpd.conf
COPY files/vsftpd.conf /etc/vsftpd.conf
To use extra docker options for each container of each module it is possible now using extra_docker_options in the module configuration for each module. For example, as shown --volume can be used to share the volume between docker container and docker host. The other options can also be specified in the extra_docker_options and the container would be built according to the options mentioned for each module.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def module_configuration():
"""
module configuration
Returns:
JSON/Dict module configuration
"""
return {
"username": "root",
"password": generate_token(16),
"extra_docker_options": ["--volume " + os.getcwd() + "/tmp/:/root/logs/"],
"module_processor": ModuleProcessor()
}
In the module configuration for each module, there is module processor class added which is used to grab the log the files obtained from the docker container or do some other needed process. Now it is being used to store the logs obtained from the docker container regarding the honeypot activities into the database.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import os
import json
from core.compatible import generate_token
from database.connector import insert_to_credential_events_collection
from database.datatypes import CredentialEvent
LOGFILE = 'tmp/ohp_ssh_strong_password_creds_logs.txt'
LOGFILE_DUMP = 'tmp/ohp_ssh_strong_password_creds_logs.json'
class ModuleProcessor:
"""
this is the processor to run after docker-machine is up to grab the
log files or do other needed process...
"""
def __init__(self):
self.kill_flag = False
def processor(self):
"""
processor function will be called as a new thread and will be
die when kill_flag is True
"""
if os.path.exists(LOGFILE):
os.remove(LOGFILE) # remove if exist from past
while not self.kill_flag:
if os.path.exists(LOGFILE):
os.rename(LOGFILE, LOGFILE_DUMP)
data_dump = open(LOGFILE_DUMP).readlines()
for data in data_dump:
data = json.loads(data)
insert_to_credential_events_collection(
CredentialEvent(
ip=data['ip'],
username=data['username'],
password=data['password'],
module_name=data['module_name'],
date=data['date']
)
)
os.remove(LOGFILE_DUMP)
time.sleep(0.1)
In this example it is copying the honeypot logs into another file, then inserts into the database and sleeps for 0.1s.
OWASP Python Honeypot currently supports multiple types of protocols with different types and modules for various purposes like getting credentials, network events, files, honeypot events, and custom data coming from each module.
To add a new protocol you should create a new folder inside the /OWASP-Honeypot/modules
directory of the project.
Each protocol has an __init__.py
file which has the category configuration, below shown is the template for the same.
def category_configuration():
"""
category configuration
Returns:
JSON/Dict category configuration
"""
return {
"virtual_machine_name": OHP_Module_name,
"virtual_machine_port_number": PORT_NUMBER,
"virtual_machine_internet_access": Bool,
"real_machine_port_number": DOCKER_HOST_PORT_NUMBER
}
Then if the protocol has modules like weak and strong password then two separate folders should be created. Inside the module folder there should be:
- files folder if the modules require some extra scripts/config files which need to be moved to the module containers.
__init__.py
contains module processor and module configuration
class ModuleProcessor:
"""
this is the processor to run after docker-machine is up to grab the
log files or do other needed process...
"""
def __init__(self):
self.kill_flag = False
def processor(self):
"""
processor function will be called as a new thread and will
be die when kill_flag is True
"""
while not self.kill_flag:
LOGGING
INSTRUCTIONS
go
here
time.sleep(0.1)
def module_configuration():
"""
module configuration
Returns:
JSON/Dict module configuration
"""
return {
"virtual_machine_port_number": PORT_NUMBER,
"real_machine_port_number": PORT_NUMBER_FOR_DOCKER_HOST,
"extra_docker_options": [""],
"module_processor": ModuleProcessor()
}
- readme.md: Describing the module
- Dockerfile: For setting up all the packages, libraries, scripts to run by the module.
For testing the module run the command
python3 ohp.py -m protocol/moduleOrType
Also one must make sure that the test for the module is passing.
python3 ohp.py -m protocol/moduleOrType --test