Skip to content

Commit

Permalink
Created test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
p0dalirius committed Jul 10, 2024
1 parent 33b0b0f commit e448fc7
Show file tree
Hide file tree
Showing 55 changed files with 1,189 additions and 32 deletions.
3 changes: 2 additions & 1 deletion smbclientng/core/CommandCompleter.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,8 @@ def print_help(self, command=None):

if command is not None:
if command not in list(self.commands.keys())+["format"]:
command = None
self.logger.error("Help for command '%s' does not exist." % command)
return

# Print help for a specific command
if command is not None:
Expand Down
9 changes: 6 additions & 3 deletions smbclientng/core/InteractiveShell.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def wrapper(*args, **kwargs):
if self.sessionsManager.current_session.connected:
return func(*args, **kwargs)
else:
print("[!] SMB Session is disconnected.")
self.logger.error("SMB Session is disconnected.")
return None
return wrapper

Expand All @@ -53,7 +53,7 @@ def wrapper(*args, **kwargs):
if self.sessionsManager.current_session.smb_share is not None:
return func(*args, **kwargs)
else:
print("[!] You must open a share first, try the 'use <share>' command.")
self.logger.error("You must open a share first, try the 'use <share>' command.")
return None
return wrapper

Expand Down Expand Up @@ -459,6 +459,9 @@ def command_info(self, arguments, command):
print_server_info = False
print_share_info = False
if len(arguments) != 0:
if arguments[0].lower() not in ["server", "share"]:
self.logger.error("'%s' is not a valid parameter. Use 'server' or 'share'." % arguments[0])
return None
print_server_info = (arguments[0].lower() == "server")
print_share_info = (arguments[0].lower() == "share")
else:
Expand All @@ -471,7 +474,7 @@ def command_info(self, arguments, command):
server=print_server_info
)
except impacket.smbconnection.SessionError as e:
self.logger.error("[!] SMB Error: %s" % e)
self.logger.error("SMB Error: %s" % e)

@command_arguments_required
def command_lbat(self, arguments, command):
Expand Down
62 changes: 39 additions & 23 deletions testing/core/Check.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,47 @@ def __init__(self, logger, options, test_case):

def run(self):
data = self.exec()
parsed = parseLogfileContents(data)
last_line = parsed[-1]

check_passed = True
for expectedMessage in self.test_case["expected_output"]["messages"]:
if expectedMessage not in ''.join(last_line["output"]):
check_passed = False
else:
self.logger.debug("'%s' is not present in output" % expectedMessage)

# Error output is matching what is expected
if self.test_case["expected_output"]["error"] != last_line["error"]:
self.logger.debug("Error output is not matching what is expected.")
check_passed = False

# Traceback output is matching what is expected
if self.test_case["expected_output"]["traceback"] != last_line["traceback"]:
self.logger.debug("Traceback output is not matching what is expected.")
if data is None:
check_passed = False
return check_passed

# Final print of check
if check_passed:
self.__print_passed()
else:
self.__print_failed()
parsed = parseLogfileContents(data)

if len(parsed) != 0:
last_line = parsed[-1]

check_passed = True
for expectedMessage in self.test_case["expected_output"]["messages"]:
if expectedMessage not in ''.join(last_line["output"]):
check_passed = False
else:
self.logger.debug("'%s' is not present in output" % expectedMessage)

# Error output is matching what is expected
if self.test_case["expected_output"]["error"] != last_line["error"]:
self.logger.debug("Error output is not matching what is expected.")
self.logger.debug("=[Output]====================================")
self.logger.debug('\n'.join(last_line["output"]))
self.logger.debug("=============================================")
check_passed = False

# Traceback output is matching what is expected
if self.test_case["expected_output"]["traceback"] != last_line["traceback"]:
self.logger.debug("Traceback output is not matching what is expected.")
self.logger.debug("=[Output]====================================")
self.logger.debug('\n'.join(last_line["output"]))
self.logger.debug("=============================================")
check_passed = False

# Final print of check
if check_passed:
self.__print_passed()
return True
else:
self.__print_failed()
return False

def exec(self):
# Create scriptfile
Expand Down Expand Up @@ -95,10 +111,10 @@ def exec(self):
return None

def __print_passed(self):
title = (self.test_case["title"]+" ").ljust(60,'─')
title = (self.test_case["title"]+" ").ljust(80,'─')
self.logger.print("├───┼───┼── %s \x1b[1;48;2;83;170;51;97m PASSED \x1b[0m" % title)

def __print_failed(self):
title = (self.test_case["title"]+" ").ljust(60,'─')
title = (self.test_case["title"]+" ").ljust(80,'─')
self.logger.print("├───┼───┼── %s \x1b[1;48;2;233;61;3;97m FAILED \x1b[0m" % title)

2 changes: 1 addition & 1 deletion testing/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def parseLogfileContents(contents):
parsed.append({
"command": command,
"output": buffer,
"error": any(["[error]" in l.startswith() for l in buffer]),
"error": any([l.startswith("[error]") for l in buffer]),
"traceback": any([l.startswith("Traceback") for l in buffer]),
})
command = None
Expand Down
18 changes: 14 additions & 4 deletions testing/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,25 @@ def parseArgs():
nb_testcases += len(testCases[category][subcategory].keys())
logger.info("Registered %d tests." % nb_testcases)


tests_passed = 0
tests_failed = 0
for category in sorted(testCases.keys()):
logger.print("\x1b[1;48;2;170;170;170;30m├──[+] Category: %-64s\x1b[0m" % category)
logger.print("\x1b[1;48;2;170;170;170;30m├──[+] Category: %-84s\x1b[0m" % category)

for subcategory in sorted(testCases[category].keys()):
logger.print("\x1b[1;48;2;200;200;200;30m├───┼──[+] Subcategory: %-57s\x1b[0m" % subcategory)
logger.print("\x1b[1;48;2;200;200;200;30m├───┼──[+] Subcategory: %-77s\x1b[0m" % subcategory)

for pathToTestCase, testCase in testCases[category][subcategory].items():
logger.debug("Testing: %s" % testCase["title"])
c = Check(logger=logger, options=options, test_case=testCase)
c.run()

if c.run() == True:
tests_passed += 1
else:
tests_failed += 1

logger.info("Finished tests.")
logger.print("\x1b[1;48;2;170;170;170;30m[+] %-96s \x1b[0m" % "All done!")
logger.info("Finished tests.")
logger.info("Tests PASSED: (%d/%d) %d%%" % (tests_passed, nb_testcases, (tests_passed / nb_testcases)*100))
logger.info("Tests FAILED: (%d/%d) %d%%" % (tests_failed, nb_testcases, (tests_failed / nb_testcases)*100))
23 changes: 23 additions & 0 deletions testing/tests/commands/bat/bat_existing_file.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"title": "Command 'bat': of an existing remote file",
"category": "commands",
"subcategory": "bat",
"parameters": {
"-d": "{auth_domain}",
"-u": "{auth_username}",
"-p": "{auth_password}",
"--host": "{target_host}"
},
"smbclientng_commands": [
"use 'C$'",
"bat './Users/John/Documents/file.txt'"
],
"expected_output": {
"messages": [
"Contents of './Users/John/Documents/file.txt':",
"This is a test file."
],
"error": false,
"traceback": false
}
}
22 changes: 22 additions & 0 deletions testing/tests/commands/bat/bat_insufficient_permissions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"title": "Command 'bat': of a remote file with insufficient permissions",
"category": "commands",
"subcategory": "bat",
"parameters": {
"-d": "{auth_domain}",
"-u": "{auth_username}",
"-p": "{auth_password}",
"--host": "{target_host}"
},
"smbclientng_commands": [
"use 'C$'",
"bat './Windows/System32/protected_file.txt'"
],
"expected_output": {
"messages": [
"Error: Permission denied for './Windows/System32/protected_file.txt'."
],
"error": true,
"traceback": false
}
}
22 changes: 22 additions & 0 deletions testing/tests/commands/bat/bat_no_file_specified.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"title": "Command 'bat': without specifying a file",
"category": "commands",
"subcategory": "bat",
"parameters": {
"-d": "{auth_domain}",
"-u": "{auth_username}",
"-p": "{auth_password}",
"--host": "{target_host}"
},
"smbclientng_commands": [
"use 'C$'",
"bat"
],
"expected_output": {
"messages": [
"Error: No file specified."
],
"error": true,
"traceback": false
}
}
22 changes: 22 additions & 0 deletions testing/tests/commands/bat/bat_non_existing_file.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"title": "Command 'bat': of a non-existing remote file",
"category": "commands",
"subcategory": "bat",
"parameters": {
"-d": "{auth_domain}",
"-u": "{auth_username}",
"-p": "{auth_password}",
"--host": "{target_host}"
},
"smbclientng_commands": [
"use 'C$'",
"bat './Users/John/Documents/non_existing_file.txt'"
],
"expected_output": {
"messages": [
"Error: File './Users/John/Documents/non_existing_file.txt' not found."
],
"error": true,
"traceback": false
}
}
22 changes: 22 additions & 0 deletions testing/tests/commands/cat/cat_existing_file.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"title": "Command 'cat': of an existing remote file",
"category": "commands",
"subcategory": "cat",
"parameters": {
"-d": "{auth_domain}",
"-u": "{auth_username}",
"-p": "{auth_password}",
"--host": "{target_host}"
},
"smbclientng_commands": [
"use 'C$'",
"cat './Users/John/Documents/file.txt'"
],
"expected_output": {
"messages": [
"This is a test file."
],
"error": false,
"traceback": false
}
}
22 changes: 22 additions & 0 deletions testing/tests/commands/cat/cat_insufficient_permissions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"title": "Command 'cat': of a remote file with insufficient permissions",
"category": "commands",
"subcategory": "cat",
"parameters": {
"-d": "{auth_domain}",
"-u": "{auth_username}",
"-p": "{auth_password}",
"--host": "{target_host}"
},
"smbclientng_commands": [
"use 'C$'",
"cat './Windows/System32/protected_file.txt'"
],
"expected_output": {
"messages": [
"Error: Permission denied for './Windows/System32/protected_file.txt'."
],
"error": true,
"traceback": false
}
}
22 changes: 22 additions & 0 deletions testing/tests/commands/cat/cat_no_file_specified.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"title": "Command 'cat': without specifying a file",
"category": "commands",
"subcategory": "cat",
"parameters": {
"-d": "{auth_domain}",
"-u": "{auth_username}",
"-p": "{auth_password}",
"--host": "{target_host}"
},
"smbclientng_commands": [
"use 'C$'",
"cat"
],
"expected_output": {
"messages": [
"Error: No file specified."
],
"error": true,
"traceback": false
}
}
22 changes: 22 additions & 0 deletions testing/tests/commands/cat/cat_non_existing_file.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"title": "Command 'cat': attempts to get the contents of a non-existing remote file",
"category": "commands",
"subcategory": "cat",
"parameters": {
"-d": "{auth_domain}",
"-u": "{auth_username}",
"-p": "{auth_password}",
"--host": "{target_host}"
},
"smbclientng_commands": [
"use 'C$'",
"cat './Users/John/Documents/non_existing_file.txt'"
],
"expected_output": {
"messages": [
"Error: File './Users/John/Documents/non_existing_file.txt' not found."
],
"error": true,
"traceback": false
}
}
20 changes: 20 additions & 0 deletions testing/tests/commands/cd/cd_a_non_existing_directory_in_cwd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "Command 'cd': with a non-existing directory in CWD",
"category": "commands",
"subcategory": "cd",
"parameters": {
"-d": "{auth_domain}",
"-u": "{auth_username}",
"-p": "{auth_password}",
"--host": "{target_host}"
},
"smbclientng_commands": [
"use 'C$'",
"cd './{random_string_8}/'"
],
"expected_output": {
"messages": ["[error] Remote directory '", "' does not exist."],
"error": true,
"traceback": false
}
}
Loading

0 comments on commit e448fc7

Please sign in to comment.