Skip to content

Developer Guidelines

Chakshu Gupta edited this page Aug 26, 2020 · 7 revisions

Configuration File

Framework Configurationconfig.py

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('MONGODB_DOCKER_ENV') == "true":
        db_url = "mongodb://mongodb:27017/"
    else:
        db_url = "mongodb://127.0.0.1:27017/"

    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"
        },
        # mongodb://user:password@127.0.0.1:27017/
        "api_database": db_url,
        "api_database_connection_timeout": 2000,  # miliseconds
        "api_database_name": "ohp_events"
    }


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",
        "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
    }

Modules Configuration

Category Configuration modules\ftp\__init__.py

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
    }

Module Configuration modules\ftp\weak_password\__init__.py

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()
    }

Use Multiple Module in the Same Category

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
    }

Copy a File To Docker Image

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 your all of files in modules/protocol/moduleOrType/files.

# copy vsftpd.conf to /etc/vsftpd.conf
COPY files/vsftpd.conf /etc/vsftpd.conf

Use Docker Options in Module Configuration

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()
    }

ModuleProcessor class for some modules if required

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.

Clone this wiki locally