2021-04-10 21:52:47 +02:00
|
|
|
#!/usr/bin/env python3
|
2021-05-30 06:24:12 +02:00
|
|
|
import os
|
|
|
|
import time
|
2021-04-10 21:52:47 +02:00
|
|
|
import random
|
|
|
|
import socket
|
|
|
|
import string
|
2021-05-30 06:24:12 +02:00
|
|
|
import dataclasses
|
|
|
|
from io import StringIO
|
2021-04-10 21:52:47 +02:00
|
|
|
|
|
|
|
import pytest
|
2021-05-30 06:24:12 +02:00
|
|
|
from pwncat.channel import ChannelError
|
2021-04-10 21:52:47 +02:00
|
|
|
from Crypto.PublicKey import RSA
|
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
PLATFORM_MAP = {"ubuntu": "linux", "centos": "linux", "windows": "windows"}
|
2021-04-10 21:52:47 +02:00
|
|
|
|
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
def connection_details_for(name):
|
|
|
|
"""Get connection details from environment for the given
|
|
|
|
host type name (e.g. ubuntu, centos, windows)"""
|
2021-04-10 21:52:47 +02:00
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
if name not in PLATFORM_MAP:
|
|
|
|
pytest.skip(f"{name} is not a known target")
|
2021-04-10 21:52:47 +02:00
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
if (
|
|
|
|
f"{name.upper()}_HOST" not in os.environ
|
|
|
|
or f"{name.upper()}_BIND_PORT" not in os.environ
|
|
|
|
):
|
|
|
|
pytest.skip(f"{name} not available")
|
2021-04-10 21:52:47 +02:00
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
return {
|
|
|
|
"platform": PLATFORM_MAP[name],
|
|
|
|
"host": os.environ[f"{name.upper()}_HOST"],
|
|
|
|
"port": int(os.environ[f"{name.upper()}_BIND_PORT"]),
|
|
|
|
"protocol": "connect",
|
|
|
|
}
|
2021-04-10 21:52:47 +02:00
|
|
|
|
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
@pytest.fixture(params=["ubuntu", "centos"])
|
|
|
|
def linux_details(request):
|
|
|
|
""" Get available connection details for linux hosts """
|
|
|
|
return connection_details_for(request.param)
|
2021-04-10 21:52:47 +02:00
|
|
|
|
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
@pytest.fixture(params=["windows"])
|
|
|
|
def windows_details(request):
|
|
|
|
""" Get available connection details for windows hosts """
|
|
|
|
return connection_details_for(request.param)
|
2021-04-10 21:52:47 +02:00
|
|
|
|
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
def session_for(request):
|
2021-04-10 21:52:47 +02:00
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
# Grab details for this target
|
|
|
|
details = connection_details_for(request.param)
|
2021-04-10 21:52:47 +02:00
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
# Check if there are manager arguments
|
|
|
|
manager_args = getattr(
|
|
|
|
request.node.get_closest_marker("manager_config"), "args", {}
|
2021-04-10 21:52:47 +02:00
|
|
|
)
|
2021-05-30 06:24:12 +02:00
|
|
|
if not manager_args:
|
|
|
|
manager_args = {}
|
|
|
|
|
|
|
|
if "config" not in manager_args:
|
|
|
|
manager_args["config"] = StringIO(
|
|
|
|
"""
|
|
|
|
set -g db "memory://"
|
|
|
|
"""
|
2021-04-10 21:52:47 +02:00
|
|
|
)
|
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
import pwncat.manager
|
2021-04-10 21:52:47 +02:00
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
with pwncat.manager.Manager(**manager_args) as manager:
|
|
|
|
for i in range(3):
|
|
|
|
try:
|
|
|
|
session = manager.create_session(**details)
|
|
|
|
yield session
|
|
|
|
break
|
|
|
|
except ChannelError:
|
|
|
|
# This seems to be because of the contaiener setup, so we just add
|
|
|
|
# a little sleep in
|
|
|
|
time.sleep(2)
|
|
|
|
else:
|
|
|
|
raise Exception("failed to connect to container")
|
2021-04-10 21:52:47 +02:00
|
|
|
|
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
@pytest.fixture(params=["windows", "ubuntu", "centos"])
|
|
|
|
def session(request):
|
|
|
|
""" Start a session with any platform """
|
|
|
|
yield from session_for(request)
|
2021-04-10 21:52:47 +02:00
|
|
|
|
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
@pytest.fixture(params=["windows"])
|
|
|
|
def windows(request):
|
|
|
|
""" Start a windows session """
|
|
|
|
yield from session_for(request)
|
2021-04-10 21:52:47 +02:00
|
|
|
|
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
@pytest.fixture(params=["ubuntu", "centos"])
|
|
|
|
def linux(request):
|
|
|
|
""" Start a linux session """
|
2021-04-10 21:52:47 +02:00
|
|
|
|
2021-05-30 06:24:12 +02:00
|
|
|
yield from session_for(request)
|