Skip to content

Commit

Permalink
tweak tests and add local windows tests
Browse files Browse the repository at this point in the history
Windows tests dont work in Github actions because of localhost weird binding issues, but work fine in the docker image
  • Loading branch information
SimonGurney authored Jul 18, 2022
1 parent 7491fd6 commit 3b1c50f
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 51 deletions.
36 changes: 12 additions & 24 deletions .github/workflows/build_preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ jobs:
with:
name: linux-arm
path: packages/linux/arm64/*
- name: install test dependencies
run: |
sudo pip install impacket pytest
- name: copy beagle into path
run: |
sudo cp packages/linux/amd64/SMBeagle /bin/smbeagle
sudo chmod +x /bin/smbeagle
sudo mkdir /empty_dir
- name: run pytest
run: |
cd tests
sudo ROOTDIR=/ pytest -v -k "not on_windows"
build_windows:
runs-on: windows-2019
steps:
Expand Down Expand Up @@ -71,27 +83,3 @@ jobs:
with:
name: windows-x64
path: packages\windows/x64\*
test_on_linux:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build linux x64
run: dotnet publish -c Release --self-contained -r linux-x64 -o packages/linux/amd64 -p:PublishSingleFile=true -p:PublishTrimmed=true -p:InvariantGlobalization=true -p:DebugType=None -p:DebugSymbols=false -p:VersionSuffix=pr$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')
- name: install test dependencies
run: |
sudo pip install impacket pytest
- run: |
sudo cp packages/linux/amd64/SMBeagle /bin/smbeagle
sudo chmod +x /bin/smbeagle
sudo mkdir /empty_dir
- name: run pytest
run: |
cd tests
sudo pytest -v
9 changes: 9 additions & 0 deletions tests/Dockerfile.Linux
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM punksecurity/smbeagle
RUN apt update && apt install python3 python3-pip -y
RUN pip install impacket pytest
RUN mkdir /empty_dir
WORKDIR /tests/
COPY tests/* .
ENTRYPOINT [ "" ]
ENV ROOTDIR "/"
CMD pytest -v -k 'not on_windows'
23 changes: 23 additions & 0 deletions tests/Dockerfile.Windows
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM mcr.microsoft.com/windows:20H2
ENV PYTHON_VERSION 3.10.5
ENV PYTHON_GET_PIP_URL https://bootstrap.pypa.io/get-pip.py

COPY windows_scripts/* /
RUN "powershell -noprofile -executionpolicy bypass -file .\install_python.ps1"

RUN "pip install impacket pytest"

ENV ROOTDIR "C:\\"
WORKDIR "C:\\"
RUN mkdir empty_dir tests
COPY tests tests
COPY x64 "C:\\windows\\system32\\."
WORKDIR tests
CMD pytest -v -k "not on_linux"

# Cant test native auth as windows auth broken in containers... tried this hacky fix but no good
#RUN net user /add test
#RUN net localgroup administrators test /add
#USER test
#ENV NATIVE_AUTH=1
#RUN net user test goose; pytest -k test_fifty_files_in_the_root
14 changes: 11 additions & 3 deletions tests/tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@


def __setupSMB(address, dir, SMB2 = True):
os.chdir("/empty_dir")
os.chdir(f"{os.environ['ROOTDIR']}empty_dir")
server = smbserver.SimpleSMBServer(listenAddress=address, listenPort=445)
server.addShare("share", dir, "")
server.addCredential("test", 1200, "9FD78381EC915F1AAAD3B435B51404EE", "25EDEDFF26CB970623DDA4733227A3F7")
server.setSMB2Support(SMB2)
server.setLogFile('')
server.start()

def setupSMB(address, dir):
Expand All @@ -25,7 +26,7 @@ class SMB(object):
def __init__(self, address = "0.0.0.0", dir_structure = ["fileA", "fileB"]):
self.address = address
self.dir_structure = dir_structure
self.dir = f"/{uuid.uuid4().hex}"
self.dir = f"{os.environ['ROOTDIR']}{uuid.uuid4().hex}"
def __enter__(self):
self.smb = setupSMB(self.address, self.dir)
os.mkdir(self.dir)
Expand Down Expand Up @@ -57,8 +58,15 @@ def runSMBeagle(*args, print_out=True):
def runSMBeagleToCSV(*args):
return runSMBeagle("-c","out.csv",*args)

def runSMBeagleQuick(*args):
return runSMBeagleToCSV("-D",*args)

def runSMBeagleToCSVWithAuth(*args):
return runSMBeagleToCSV("-u","test", "-p", "goose", *args)
try:
os.environ["NATIVE_AUTH"]
return runSMBeagleToCSV(*args)
except:
return runSMBeagleToCSV("-u","test", "-p", "goose", *args)

def runSMBeagleToCSVWithAuthAndReturnResults(*args):
print(runSMBeagleToCSVWithAuth(*args))
Expand Down
30 changes: 16 additions & 14 deletions tests/tests/test_010_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,42 @@

username_or_password_missing_error = "ERROR: Username and Password required on none Windows platforms"
def test_username_and_password_required_on_linux():
assert username_or_password_missing_error in runSMBeagleToCSV()
assert username_or_password_missing_error in runSMBeagleQuick()
def test_password_required_on_linux():
assert username_or_password_missing_error in runSMBeagleToCSV("-p","goose")
assert username_or_password_missing_error in runSMBeagleQuick("-p","goose")
def test_username_required_on_linux():
assert username_or_password_missing_error in runSMBeagleToCSV("-u","goose")
assert username_or_password_missing_error in runSMBeagleQuick("-u","goose")
def test_username_and_password_not_required_on_windows():
assert username_or_password_missing_error not in runSMBeagleQuick()
def test_username_and_password_accepted():
assert username_or_password_missing_error not in runSMBeagleToCSV("-u","goose", "-p", "goose")
assert username_or_password_missing_error not in runSMBeagleQuick("-u","goose", "-p", "goose")
def test_long_username_accepted():
assert username_or_password_missing_error not in runSMBeagleToCSV("--username","goose", "-p", "goose")
assert username_or_password_missing_error not in runSMBeagleQuick("--username","goose", "-p", "goose")
def test_long_password_accepted():
assert username_or_password_missing_error not in runSMBeagleToCSV("-u","goose", "--password", "goose")
assert username_or_password_missing_error not in runSMBeagleQuick("-u","goose", "--password", "goose")

output_required_error = "At least one option from group 'output' (c, csv-file, e, elasticsearch-host)"
def test_csv_or_elasticsearch_required():
assert output_required_error in runSMBeagle()
def test_short_csv_accepted():
assert output_required_error not in runSMBeagle("-c","out.csv")
assert output_required_error not in runSMBeagleQuick("-c","out.csv")
def test_long_csv_accepted():
assert output_required_error not in runSMBeagle("--csv-file","out.csv")
assert output_required_error not in runSMBeagleQuick("--csv-file","out.csv")
def test_short_elasticsearch_accepted():
assert output_required_error not in runSMBeagle("-e","elasticsearch")
assert output_required_error not in runSMBeagleQuick("-e","elasticsearch")
def test_long_elasticsearch_accepted():
assert output_required_error not in runSMBeagle("--elasticsearch-host","elasticsearch")
assert output_required_error not in runSMBeagleQuick("--elasticsearch-host","elasticsearch")


def test_manual_host_accepted():
assert "127.0.0.2" in runSMBeagleToCSVWithAuth("-h", "127.0.0.2")
assert "127.0.0.2" in runSMBeagleToCSVWithAuth("-D","-h", "127.0.0.2")
def test_multiple_manual_host_accepted():
output = runSMBeagleToCSVWithAuth("-h", "127.0.0.2", "127.0.0.3")
output = runSMBeagleToCSVWithAuth("-D","-h", "127.0.0.2", "127.0.0.3")
assert "127.0.0.2" in output and "127.0.0.3" in output

def test_manual_network_accepted():
output = runSMBeagleToCSVWithAuth("-n", "127.0.0.0/24")
output = runSMBeagleToCSVWithAuth("-D", "-n", "127.0.0.0/24")
assert "127.0.0.0/24" in output
def test_multiple_manual_network_accepted():
output = runSMBeagleToCSVWithAuth("-n", "127.0.0.0/24", "127.0.1.0/24")
output = runSMBeagleToCSVWithAuth("-D","-n", "127.0.0.0/24", "127.0.1.0/24")
assert "127.0.0.0/24" in output and "127.0.1.0/24" in output
20 changes: 10 additions & 10 deletions tests/tests/test_020_tcp_scans.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,51 +10,51 @@

def test_one_manual_host_tcp_success():
with SMB():
assert one_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-h", "127.0.0.2")
assert one_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-D", "-h", "127.0.0.2")

def test_one_manual_host_tcp_fail_if_not_listening():
with SMB("127.0.0.2"):
assert no_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-h", "127.0.0.3")
assert no_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-D", "-h", "127.0.0.3")

def test_two_manual_host_tcp_success():
with SMB("127.0.0.2"):
with SMB("127.0.0.3"):
assert two_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-h", "127.0.0.2", "127.0.0.3")
assert two_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-D", "-h", "127.0.0.2", "127.0.0.3")

def test_one_manual_host_tcp_success_and_not_two_if_second_not_listening():
with SMB("127.0.0.2"):
assert one_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-h", "127.0.0.2", "127.0.0.3")
assert one_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-D", "-h", "127.0.0.2", "127.0.0.3")

def test_one_discovered_host_tcp_success():
with SMB("127.0.0.2"):
assert one_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-n", "127.0.0.0/24")
assert one_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-D", "-n", "127.0.0.0/24")

def test_no_discovered_host_when_filtered():
with SMB("127.0.0.2"):
assert no_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-n", "127.0.0.0/24","-H","127.0.0.2" )
assert no_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-D", "-n", "127.0.0.0/24","-H","127.0.0.2" )

def test_one_discovered_host_when_one_filtered():
with SMB("127.0.0.2"):
with SMB("127.0.0.3"):
assert one_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-n", "127.0.0.0/24","-H","127.0.0.2" )
assert one_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-D", "-n", "127.0.0.0/24","-H","127.0.0.2" )

def test_two_discovered_host_tcp_success():
with SMB("127.0.0.2"):
with SMB("127.0.0.3"):
assert two_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-n", "127.0.0.0/24")
assert two_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-D", "-n", "127.0.0.0/24")

def test_three_discovered_host_tcp_success():
with SMB("127.0.0.2"):
with SMB("127.0.0.3"):
with SMB("127.0.0.4"):
assert three_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-n", "127.0.0.0/24")
assert three_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-D", "-n", "127.0.0.0/24")

def test_four_discovered_host_tcp_success():
with SMB("127.0.0.2"):
with SMB("127.0.0.3"):
with SMB("127.0.0.4"):
with SMB("127.0.0.5"):
assert four_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-n", "127.0.0.0/24")
assert four_smb_service_discovered_message in runSMBeagleToCSVWithAuth("-D", "-n", "127.0.0.0/24")

def test_disable_network_discovery():
no_networks_to_scan_message = "there are no networks or hosts to scan"
Expand Down
16 changes: 16 additions & 0 deletions tests/windows_scripts/install_python.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
$url = ('https://www.python.org/ftp/python/{0}/python-{0}-amd64.exe' -f $env:PYTHON_VERSION)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri $url -OutFile 'python.exe';
# https://docs.python.org/3.7/using/windows.html#installing-without-ui
Start-Process python.exe -Wait -ArgumentList @(
'/quiet',
'InstallAllUsers=1',
'TargetDir=C:\Python',
'PrependPath=1',
'Shortcuts=0',
'Include_doc=0',
'Include_pip=1',
'Include_test=0'
);
#the installer updated PATH, so we should refresh our local value
Remove-Item python.exe -Force

0 comments on commit 3b1c50f

Please sign in to comment.