Skip to content

Testing Framework & `tests ` Structure

Johnny Watts (aka., "Kaotick Jay") edited this page Jun 21, 2025 · 1 revision

πŸ§ͺ Testing Framework & tests/ Structure

NetSentinel is modular and written for testability. This guide covers the structure and examples of how to implement basic functional and unit tests using Python's built-in unittest framework.


πŸ“ Directory Structure


/NetSentinel
β”œβ”€β”€ core/
β”œβ”€β”€ utils/
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ **init**.py
β”‚   β”œβ”€β”€ test\_logger.py
β”‚   β”œβ”€β”€ test\_config.py
β”‚   β”œβ”€β”€ test\_smb\_enum.py
β”‚   β”œβ”€β”€ test\_kerberos\_enum.py
β”‚   └── test\_recon.py

All test modules should be placed under /tests, mirroring the structure of /core and /utils.


πŸ”§ Testing Requirements

All tests use Python’s standard library:

python -m unittest discover tests/

For test coverage reporting (optional):

pip install coverage
coverage run -m unittest discover tests/
coverage report -m

✍️ Sample Test: Logger (test_logger.py)

import unittest
from utils.logger import Logger

class TestLogger(unittest.TestCase):
    def test_info_output(self):
        logger = Logger()
        try:
            logger.info("Test log")
        except Exception as e:
            self.fail(f"Logger raised an exception: {e}")

✍️ Sample Test: Config (test_config.py)

import os
import unittest
from utils.config import Config

class TestConfig(unittest.TestCase):
    def test_env_override(self):
        os.environ['NetSentinel_DOMAIN'] = 'test.local'
        os.environ['NetSentinel_USER'] = 'testuser'
        os.environ['NetSentinel_PASS'] = 'pass123'
        os.environ['NetSentinel_DC'] = '192.168.1.1'

        config = Config()
        self.assertEqual(config.domain, 'test.local')
        self.assertEqual(config.username, 'testuser')

πŸ§ͺ Additional Ideas

  • Mocking Kerberos server responses (using unittest.mock)
  • Simulated SMB hosts with Metasploit’s auxiliary modules (manual or scripted)
  • Tests for valid/invalid CIDR ranges in NetworkScanner

πŸ“œ Guidelines

  • Always test modules in isolation
  • Avoid requiring live targets unless integration testing
  • Include exception-handling tests where external input is parsed (e.g. SMB/LDAP/KRB)

βœ… Test Naming Conventions

  • File: test_<module>.py
  • Class: Test<ClassName>
  • Method: test_<condition>_<expected_result>

🧠 TODO: CI/CD Integration

Future versions may include GitHub Actions support for:

  • Linting (flake8, black)
  • Automated tests on pull requests
  • Artifact generation (e.g., JSON diff or output logs)


---

## πŸ” Threat Modeling for New Modules (e.g., SNMP) (`Threat-Modeling.md`)

```markdown
# πŸ” Threat Modeling: Adding New Modules Safely

NetSentinel is used in red team and assessment environments where operational security (OPSEC), stealth, and safety are paramount. This document outlines how to evaluate and design new modules such as SNMP enumeration while minimizing detection and misuse risk.

---

## 🧭 Threat Model Goals

When adding a new module (e.g., `snmp_enum.py`), consider:

| Goal                         | Description                                    |
|------------------------------|------------------------------------------------|
| OPSEC safety                 | Avoid obvious or noisy traffic                 |
| Abuse resistance             | Prevent unauthorized misuse or abuse           |
| Controlled output            | Ensure all logs are sanitized and timestamped  |
| Fail gracefully              | Modules should not crash or hang               |
| Predictable behavior         | Avoid background threads or unbounded loops    |

---

## πŸ›  Module Threat Assessment Checklist

### 1. ❓ What Protocol Is Used?

- SNMP uses UDP/161
- Stateless and high-traffic probes may resemble scans or floods
- Detectable by NIDS/flow collectors

### 2. ❓ What Authentication Is Required?

- SNMPv1 and SNMPv2c use community strings (e.g., `public`)
- Avoid brute-forcing β€” default to common strings only
- Do not allow user-provided lists unless explicit

### 3. ❓ How Are Timeouts Handled?

- Use socket-level timeouts (UDP can "hang" in poor networks)
- Example:

```python
sock.settimeout(1.5)

4. ❓ What Gets Logged?

  • Only sanitized output (e.g., device name, sysDescr, OID list)
  • Avoid dumping full raw SNMP walks unless in verbose/debug mode

🧱 Safe SNMP Enum Blueprint

Goal: Create a module that scans for SNMP-capable hosts and extracts system name, description, and interface list (read-only).

class SNMPEnumerator:
    def __init__(self, logger, targets):
        self.logger = logger
        self.targets = targets
        self.community_strings = ['public', 'private']

    def enumerate(self):
        for host in self.targets:
            for community in self.community_strings:
                try:
                    # Issue SNMP GET
                    info = self.snmp_get(host, community)
                    self.logger.success(f"[{host}] SNMP sysDescr: {info}")
                except TimeoutError:
                    self.logger.warn(f"[{host}] No SNMP response")

πŸ›‘ Red Team Safeguards

Principle Application
Least privilege Only query public-readable SNMP OIDs
Rate limiting 1–2 queries per second
No storage of creds Do not cache community strings
Test mode flag Allow test runs with --dry-run
Target validation Ensure IPs are local or permitted subnets

βš–οΈ Ethics & Legal Reminder

Never use SNMP enumeration on external or unauthorized networks.

Only run this module under the following conditions:

  • Written Rules of Engagement
  • Explicit permission to query SNMP
  • Internal networks under authorized test scope

πŸ“˜ Reference OIDs for Safe Use

OID Description
1.3.6.1.2.1.1.1.0 sysDescr (OS Info)
1.3.6.1.2.1.1.5.0 sysName (Hostname)
1.3.6.1.2.1.2.2.1.2 Interface Names

Avoid full SNMP walks unless expressly approved.


βœ… Summary

Checklist Item Status
Safe OID targets βœ…
Community string whitelisting βœ…
Timeout enforcement βœ…
No credential storage βœ…
Output sanitation βœ…
OPSEC-conscious logging βœ…

By modeling each new module this way, NetSentinel stays safe, lean, and engagement-respectful.