From 658d40335a15bc40d2ecb5679198d759858492b5 Mon Sep 17 00:00:00 2001 From: Gustavo Moreira Date: Fri, 20 Dec 2024 13:06:14 +1100 Subject: [PATCH 1/5] testcases: Add basic volshell testcases for each OS image --- .github/workflows/test.yaml | 5 ++++ test/test_volatility.py | 51 +++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index dfc42499d..e07673175 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -42,6 +42,11 @@ jobs: - name: Testing... run: | + # VolShell + pytest ./test/test_volatility.py --volatility=volshell.py --image-dir=./test_images -k test_windows_volshell -v + pytest ./test/test_volatility.py --volatility=volshell.py --image-dir=./test_images -k test_linux_volshell -v + + # Volatility pytest ./test/test_volatility.py --volatility=vol.py --image-dir=./test_images -k test_windows -v pytest ./test/test_volatility.py --volatility=vol.py --image-dir=./test_images -k test_linux -v diff --git a/test/test_volatility.py b/test/test_volatility.py index 5bce07481..8ef6d8b70 100644 --- a/test/test_volatility.py +++ b/test/test_volatility.py @@ -54,13 +54,56 @@ def runvol_plugin(plugin, img, volatility, python, pluginargs=[], globalargs=[]) return runvol(args, volatility, python) +def runvolshell(img, volshell, python, volshellargs=[], globalargs=[]): + args = ( + globalargs + + [ + "--single-location", + img, + "-q", + ] + + volshellargs + ) + + return runvol(args, volshell, python) + + # # TESTS # + +def basic_volshell_test(image, volatility, python): + # Basic VolShell test to verify requirements and ensure VolShell runs without crashing + + # FIXME: When the minimum Python version includes 3.12, replace the following with: + # with tempfile.NamedTemporaryFile(delete_on_close=False) as fd: ... + fd, filename = tempfile.mkstemp(suffix=".txt") + try: + with os.fdopen(fd, "w") as f: + f.write("exit()") + + rc, out, _err = runvolshell( + img=image, + volshell=volatility, + python=python, + volshellargs=["--script", filename], + ) + finally: + with contextlib.suppress(FileNotFoundError): + os.remove(filename) + + assert rc == 0 + assert out.count(b"\n") >= 4 + + # WINDOWS +def test_windows_volshell(image, volatility, python): + basic_volshell_test(image, volatility, python) + + def test_windows_pslist(image, volatility, python): rc, out, _err = runvol_plugin("windows.pslist.PsList", image, volatility, python) out = out.lower() @@ -332,6 +375,10 @@ def test_windows_vadyarascan_yara_string(image, volatility, python): # LINUX +def test_linux_volshell(image, volatility, python): + basic_volshell_test(image, volatility, python) + + def test_linux_pslist(image, volatility, python): rc, out, _err = runvol_plugin("linux.pslist.PsList", image, volatility, python) @@ -770,6 +817,10 @@ def test_linux_hidden_modules(image, volatility, python): # MAC +def test_mac_volshell(image, volatility, python): + basic_volshell_test(image, volatility, python) + + def test_mac_pslist(image, volatility, python): rc, out, _err = runvol_plugin("mac.pslist.PsList", image, volatility, python) out = out.lower() From 90766f466f581561e17b2cc5e2c7d8eca56c56e6 Mon Sep 17 00:00:00 2001 From: Gustavo Moreira Date: Fri, 20 Dec 2024 13:21:24 +1100 Subject: [PATCH 2/5] testcases: exclude volshell test from the volatility set --- .github/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e07673175..ce2722457 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -47,8 +47,8 @@ jobs: pytest ./test/test_volatility.py --volatility=volshell.py --image-dir=./test_images -k test_linux_volshell -v # Volatility - pytest ./test/test_volatility.py --volatility=vol.py --image-dir=./test_images -k test_windows -v - pytest ./test/test_volatility.py --volatility=vol.py --image-dir=./test_images -k test_linux -v + pytest ./test/test_volatility.py --volatility=vol.py --image-dir=./test_images -k "test_windows and not test_windows_volshell" -v + pytest ./test/test_volatility.py --volatility=vol.py --image-dir=./test_images -k "test_linux and not test_linux_volshell" -v - name: Clean up post-test run: | From c317a45eb56a5da26ee50e2edc0d2e8c6821d262 Mon Sep 17 00:00:00 2001 From: Gustavo Moreira Date: Fri, 20 Dec 2024 14:31:40 +1100 Subject: [PATCH 3/5] testcases: Add missing operating system argument --- test/test_volatility.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/test_volatility.py b/test/test_volatility.py index 8ef6d8b70..f8a32fef3 100644 --- a/test/test_volatility.py +++ b/test/test_volatility.py @@ -73,7 +73,7 @@ def runvolshell(img, volshell, python, volshellargs=[], globalargs=[]): # -def basic_volshell_test(image, volatility, python): +def basic_volshell_test(image, volatility, python, globalargs): # Basic VolShell test to verify requirements and ensure VolShell runs without crashing # FIXME: When the minimum Python version includes 3.12, replace the following with: @@ -88,6 +88,7 @@ def basic_volshell_test(image, volatility, python): volshell=volatility, python=python, volshellargs=["--script", filename], + globalargs=globalargs, ) finally: with contextlib.suppress(FileNotFoundError): @@ -101,7 +102,7 @@ def basic_volshell_test(image, volatility, python): def test_windows_volshell(image, volatility, python): - basic_volshell_test(image, volatility, python) + basic_volshell_test(image, volatility, python, globalargs=["-w"]) def test_windows_pslist(image, volatility, python): @@ -376,7 +377,7 @@ def test_windows_vadyarascan_yara_string(image, volatility, python): def test_linux_volshell(image, volatility, python): - basic_volshell_test(image, volatility, python) + basic_volshell_test(image, volatility, python, globalargs=["-l"]) def test_linux_pslist(image, volatility, python): @@ -818,7 +819,7 @@ def test_linux_hidden_modules(image, volatility, python): def test_mac_volshell(image, volatility, python): - basic_volshell_test(image, volatility, python) + basic_volshell_test(image, volatility, python, globalargs=["-m"]) def test_mac_pslist(image, volatility, python): From d546c983f3012f3060aca2b2721fedcc48321370 Mon Sep 17 00:00:00 2001 From: Gustavo Moreira Date: Fri, 20 Dec 2024 14:33:36 +1100 Subject: [PATCH 4/5] testcases: Fix runvol* default list arguments --- test/test_volatility.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/test_volatility.py b/test/test_volatility.py index f8a32fef3..47ef9769f 100644 --- a/test/test_volatility.py +++ b/test/test_volatility.py @@ -39,7 +39,9 @@ def runvol(args, volatility, python): return p.returncode, stdout, stderr -def runvol_plugin(plugin, img, volatility, python, pluginargs=[], globalargs=[]): +def runvol_plugin(plugin, img, volatility, python, pluginargs=None, globalargs=None): + pluginargs = pluginargs or [] + globalargs = globalargs or [] args = ( globalargs + [ @@ -54,7 +56,9 @@ def runvol_plugin(plugin, img, volatility, python, pluginargs=[], globalargs=[]) return runvol(args, volatility, python) -def runvolshell(img, volshell, python, volshellargs=[], globalargs=[]): +def runvolshell(img, volshell, python, volshellargs=None, globalargs=None): + volshellargs = volshellargs or [] + globalargs = globalargs or [] args = ( globalargs + [ From ef977efe62af8e4cc5baa96e8a20fb713ee7494f Mon Sep 17 00:00:00 2001 From: Gustavo Moreira Date: Fri, 20 Dec 2024 14:50:35 +1100 Subject: [PATCH 5/5] testcases: Improve volshell basic testcase calling ps() on each of them --- test/test_volatility.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/test/test_volatility.py b/test/test_volatility.py index 47ef9769f..bb7c9a851 100644 --- a/test/test_volatility.py +++ b/test/test_volatility.py @@ -80,12 +80,18 @@ def runvolshell(img, volshell, python, volshellargs=None, globalargs=None): def basic_volshell_test(image, volatility, python, globalargs): # Basic VolShell test to verify requirements and ensure VolShell runs without crashing + volshell_commands = [ + "print(ps())", + "exit()", + ] + # FIXME: When the minimum Python version includes 3.12, replace the following with: # with tempfile.NamedTemporaryFile(delete_on_close=False) as fd: ... fd, filename = tempfile.mkstemp(suffix=".txt") try: + volshell_script = "\n".join(volshell_commands) with os.fdopen(fd, "w") as f: - f.write("exit()") + f.write(volshell_script) rc, out, _err = runvolshell( img=image, @@ -101,12 +107,15 @@ def basic_volshell_test(image, volatility, python, globalargs): assert rc == 0 assert out.count(b"\n") >= 4 + return out + # WINDOWS def test_windows_volshell(image, volatility, python): - basic_volshell_test(image, volatility, python, globalargs=["-w"]) + out = basic_volshell_test(image, volatility, python, globalargs=["-w"]) + assert out.count(b" 40 def test_windows_pslist(image, volatility, python): @@ -381,7 +390,8 @@ def test_windows_vadyarascan_yara_string(image, volatility, python): def test_linux_volshell(image, volatility, python): - basic_volshell_test(image, volatility, python, globalargs=["-l"]) + out = basic_volshell_test(image, volatility, python, globalargs=["-l"]) + assert out.count(b" 100 def test_linux_pslist(image, volatility, python):