diff --git a/.github/workflows/build_release.yml b/.github/workflows/build_release.yml index 5999c8b..5a85016 100644 --- a/.github/workflows/build_release.yml +++ b/.github/workflows/build_release.yml @@ -20,9 +20,11 @@ jobs: - name: execute py script # run file run: | python JsonOutput/JsonOutput.py + python SigmaOutput/SigmaOutput.py + zip -r ./ci-output/sigma_rules.zip ./ci-output/sigma - name: create release run: | - gh release create $TITLE ./ci-output/rmms.json -F CHANGELOG.md + gh release create $TITLE ./ci-output/rmms.json ./ci-output/sigma_rules.zip -F CHANGELOG.md env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} TITLE: ${{ github.ref_name }} diff --git a/README.md b/README.md index 76ffebe..4d72f9a 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,13 @@ NetConn: Ports: - 443 - 8080 +Meta: + ID: + Description: A description of the RMM/access tool + Date: YYYY-MM-DD + Modified: YYYY-MM-DD + References: + - https://Some_Link.com ``` Example (from `./RMMs/TeamViewer.yml`): @@ -73,6 +80,13 @@ NetConn: - '*.teamviewer.com' Ports: - 5938 +Meta: + ID: 85F6550F-8693-4B68-A081-5DBDA0913014 + Description: Teamviewer allows for remote connections to a machine + Date: 2023-11-18 + Modified: 2023-11-18 + References: + - 'https://www.teamviewer.com/en-us/' ``` A blank to make life easy for creating PRs: @@ -92,4 +106,11 @@ NetConn: - Ports: - 443 +Meta: + ID: + Description: + Date: + Modified: + References: + - '' ``` diff --git a/RMMs/AnyDesk.yml b/RMMs/AnyDesk.yml index 0bbd66c..b3bf25a 100644 --- a/RMMs/AnyDesk.yml +++ b/RMMs/AnyDesk.yml @@ -18,3 +18,10 @@ NetConn: - 50001 - 50002 - 50003 +Meta: + ID: de7dd0b8-b924-4a6a-b433-3428b529119a + Description: AnyDesk is a remote desktop tool + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://anydesk.com' diff --git a/RMMs/Atera.yml b/RMMs/Atera.yml index 668dd38..b182d0b 100644 --- a/RMMs/Atera.yml +++ b/RMMs/Atera.yml @@ -33,3 +33,10 @@ NetConn: - a32dl55qcodech-ats.iot.eu-west-1.amazonaws.com Ports: - 443 +Meta: + ID: 8A1D7AE2-4613-49DB-B7DC-B6BCD88F48C7 + Description: Atera is a RMM solution + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://www.atera.com' diff --git a/RMMs/ChromeRemoteDesktop.yml b/RMMs/ChromeRemoteDesktop.yml index 3d3af92..08902c3 100644 --- a/RMMs/ChromeRemoteDesktop.yml +++ b/RMMs/ChromeRemoteDesktop.yml @@ -35,4 +35,11 @@ NetConn: - remotedesktop.google.com Ports: - 443 - - 3478 \ No newline at end of file + - 3478 +Meta: + ID: 69c85e30-48c9-4072-937a-c467e2511eeb + Description: Chrome Remote Desktop is a chrome plugin that provides remote access + Date: 2024-10-21 + Modified: 2024-10-21 + References: + - 'https://chromewebstore.google.com/detail/chrome-remote-desktop/inomeogfingihgjfjlpeplalcfajhgai?hl=en' \ No newline at end of file diff --git a/RMMs/FleetDeck.yml b/RMMs/FleetDeck.yml index 8135ab1..0b9418a 100644 --- a/RMMs/FleetDeck.yml +++ b/RMMs/FleetDeck.yml @@ -17,3 +17,10 @@ NetConn: - fleetdm.com Ports: - 443 +Meta: + ID: 64B024F1-C219-497D-98E0-F2DD198B32F3 + Description: FleetDeck is a remote desktop and remote terminal solution + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://fleetdeck.io' diff --git a/RMMs/GoToMyPC.yml b/RMMs/GoToMyPC.yml index ddb00a0..d92f821 100644 --- a/RMMs/GoToMyPC.yml +++ b/RMMs/GoToMyPC.yml @@ -22,3 +22,10 @@ NetConn: Ports: - 80 - 443 +Meta: + ID: 48D7D443-787B-431C-A528-5BA5C2C75301 + Description: GoToMyPC is a remote desktop solution + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://get.gotomypc.com/' diff --git a/RMMs/GoToResolve.yml b/RMMs/GoToResolve.yml index fee264d..3a886f0 100644 --- a/RMMs/GoToResolve.yml +++ b/RMMs/GoToResolve.yml @@ -32,3 +32,10 @@ NetConn: Ports: - 3489 - 443 +Meta: + ID: CCE2B119-8CBB-45CE-AFE8-5BA4D7057E3D + Description: GoToResolve is an RMM from goto + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://www.goto.com/it-management/resolve' diff --git a/RMMs/Level.io.yml b/RMMs/Level.io.yml index 48001c0..bc1a3d9 100644 --- a/RMMs/Level.io.yml +++ b/RMMs/Level.io.yml @@ -18,3 +18,10 @@ NetConn: - 80 - 3478 - 5349 +Meta: + ID: D3ABD31D-D490-474B-B62A-625906037A6C + Description: Level.io is an RMM + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'level.io' diff --git a/RMMs/MeshCentral.yml b/RMMs/MeshCentral.yml index 061b691..5efc9c1 100644 --- a/RMMs/MeshCentral.yml +++ b/RMMs/MeshCentral.yml @@ -10,3 +10,10 @@ Executables: NetConn: Domains: Ports: +Meta: + ID: 55EC5C27-A1C8-473F-BE51-4979EC10A7DA + Description: MeshCentral allows for 'full computer management' + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://github.com/Ylianst/MeshCentral' diff --git a/RMMs/N-Able.yml b/RMMs/N-Able.yml index 37687a6..bd2f64e 100644 --- a/RMMs/N-Able.yml +++ b/RMMs/N-Able.yml @@ -36,3 +36,10 @@ NetConn: - 443 - 20 - 21 +Meta: + ID: E37B1F63-542E-46EF-965C-92189AFFEA71 + Description: N-Able is an RMM + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://www.n-able.com/' diff --git a/RMMs/NetSupport.yml b/RMMs/NetSupport.yml index 2a1903e..86cd7df 100644 --- a/RMMs/NetSupport.yml +++ b/RMMs/NetSupport.yml @@ -14,3 +14,10 @@ NetConn: Domains: null Ports: - 443 +Meta: + ID: 9B9E5782-E7CC-4525-A933-427030E1725E + Description: NetSupport is an RMM + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://www.netsupportsoftware.com/' diff --git a/RMMs/NinjaRMM.yml b/RMMs/NinjaRMM.yml index faec0aa..8acbea8 100644 --- a/RMMs/NinjaRMM.yml +++ b/RMMs/NinjaRMM.yml @@ -18,3 +18,10 @@ NetConn: Ports: - 80 - 443 +Meta: + ID: 3507D8B2-6C1B-4468-9057-6F17703EE0D4 + Description: NinjaRMM is a RMM + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://www.ninjaone.com/' diff --git a/RMMs/NoMachine.yml b/RMMs/NoMachine.yml index 1eadff5..dcbf5de 100644 --- a/RMMs/NoMachine.yml +++ b/RMMs/NoMachine.yml @@ -77,3 +77,10 @@ NetConn: - 4022 - 4080 - 4443 +Meta: + ID: 68305084-9944-462C-B3BF-ACD17D235EEB + Description: NoMachine is a remote desktop tool + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'www.nomachine.com' diff --git a/RMMs/Pulseway.yml b/RMMs/Pulseway.yml index 1414868..8987f44 100644 --- a/RMMs/Pulseway.yml +++ b/RMMs/Pulseway.yml @@ -13,3 +13,11 @@ NetConn: - pulseway.com Ports: - 443 +Meta: + ID: 436E7F78-12D3-4379-A6E6-870671F95590 + Description: Pulseway is a RMM + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://www.pulseway.com/' + \ No newline at end of file diff --git a/RMMs/QuickAssist.yml b/RMMs/QuickAssist.yml index 8ea5f15..995a433 100644 --- a/RMMs/QuickAssist.yml +++ b/RMMs/QuickAssist.yml @@ -13,3 +13,10 @@ NetConn: - remoteassistanceprodacs* Ports: - 443 +Meta: + ID: 1E21B1CA-DD6D-4505-9018-C9F8C3F40ACC + Description: quickassist is a tool from microsoft that can be used for remote control + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://support.microsoft.com/en-us/windows/install-quick-assist-c17479b7-a49d-4d12-938c-dbfb97c88bca' diff --git a/RMMs/RustDesk.yml b/RMMs/RustDesk.yml index 627fe1a..ccf4e73 100644 --- a/RMMs/RustDesk.yml +++ b/RMMs/RustDesk.yml @@ -18,3 +18,10 @@ NetConn: - 21117 - 21118 - 21119 +Meta: + ID: 074EC611-F61F-4C12-8404-DEADE627F490 + Description: RustDesk is an open source remote access tool + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://rustdesk.com/' diff --git a/RMMs/ScreenConnect.yml b/RMMs/ScreenConnect.yml index 3577360..6b00c15 100644 --- a/RMMs/ScreenConnect.yml +++ b/RMMs/ScreenConnect.yml @@ -22,3 +22,10 @@ NetConn: - 80 - 443 - 8041 +Meta: + ID: 0B1D916C-A462-4BC9-A0D7-B416DF45E8A6 + Description: Screenconnect is a remote access tool from connectwise + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://screenconnect.connectwise.com/' diff --git a/RMMs/SimpleHelp.yml b/RMMs/SimpleHelp.yml index 1d76923..2f62e95 100644 --- a/RMMs/SimpleHelp.yml +++ b/RMMs/SimpleHelp.yml @@ -14,3 +14,10 @@ Executables: NetConn: Domains: Ports: +Meta: + ID: E3CF0B3A-E263-41FA-8D14-BF10CA721A06 + Description: Simplehelp is a remote access tool + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'simple-help.com' diff --git a/RMMs/Splashtop.yml b/RMMs/Splashtop.yml index 4eae186..81cc5ab 100644 --- a/RMMs/Splashtop.yml +++ b/RMMs/Splashtop.yml @@ -21,3 +21,10 @@ NetConn: - '*.splashtop.eu' Ports: - 443 +Meta: + ID: 532F8698-8390-4A8E-B9E6-DA244BEF341C + Description: Splashtop is a remote access tool + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'splashtop.com' diff --git a/RMMs/Supremo.yml b/RMMs/Supremo.yml index b2849ea..8ade944 100644 --- a/RMMs/Supremo.yml +++ b/RMMs/Supremo.yml @@ -19,3 +19,10 @@ NetConn: - 80 - 443 - 5938 +Meta: + ID: 506CBD0D-4A9C-43D6-AE13-301CA4E0EF49 + Description: Supremo is a remote access tool + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'https://www.supremocontrol.com/' diff --git a/RMMs/TacticalRMM.yml b/RMMs/TacticalRMM.yml index 5abcbdd..a599300 100644 --- a/RMMs/TacticalRMM.yml +++ b/RMMs/TacticalRMM.yml @@ -11,3 +11,10 @@ NetConn: Domains: null Ports: - 443 +Meta: + ID: 47B135F7-39E8-4916-8793-ACC1160EC6E4 + Description: Tactical RMM is a free RMM utility + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'tacticalrmm.com' diff --git a/RMMs/Tailscale.yml b/RMMs/Tailscale.yml index 44e0776..66228e8 100644 --- a/RMMs/Tailscale.yml +++ b/RMMs/Tailscale.yml @@ -21,3 +21,11 @@ NetConn: UDPPorts: - 41641 - 3478 +Meta: + ID: F5B51A06-5803-4AAF-AE63-CEAB89238BD7 + Description: Tailscale is a VPN provider + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'tailscale.com' + diff --git a/RMMs/TeamViewer.yml b/RMMs/TeamViewer.yml index adec29b..64a9904 100644 --- a/RMMs/TeamViewer.yml +++ b/RMMs/TeamViewer.yml @@ -13,3 +13,10 @@ NetConn: - '*.teamviewer.com' Ports: - 5938 +Meta: + ID: 85F6550F-8693-4B68-A081-5DBDA0913014 + Description: Teamviewer allows for remote connections to a machine + Date: 2023-11-18 + Modified: 2023-11-18 + References: + - 'https://www.teamviewer.com/en-us/' diff --git a/RMMs/VSCodeTunnel.yml b/RMMs/VSCodeTunnel.yml index e31a359..26653c3 100644 --- a/RMMs/VSCodeTunnel.yml +++ b/RMMs/VSCodeTunnel.yml @@ -14,3 +14,10 @@ NetConn: - '*.devtunnels.ms' Ports: - 443 +Meta: + ID: 088B75D2-9CC5-4288-A695-2B05B46DCC72 + Description: VSCode tunnels allow connection from remote hosts + Date: 2024-09-10 + Modified: 2024-09-10 + References: + - 'https://code.visualstudio.com/docs/remote/tunnels' diff --git a/RMMs/ZohoAssist.yml b/RMMs/ZohoAssist.yml index 8385445..b84a458 100644 --- a/RMMs/ZohoAssist.yml +++ b/RMMs/ZohoAssist.yml @@ -28,3 +28,10 @@ NetConn: Ports: - 80 - 443 +Meta: + ID: 4D4BB5A6-CA27-499A-A6B4-3C7BE4971525 + Description: Zoho assist is free remote assistance tool + Date: 2023-11-18 + Modified: 2023-11-18 + References: + - 'https://www.zoho.com/assist/' diff --git a/RMMs/ngrok.yml b/RMMs/ngrok.yml index ad94917..e154f0d 100644 --- a/RMMs/ngrok.yml +++ b/RMMs/ngrok.yml @@ -16,3 +16,10 @@ NetConn: - 'tunnel.*.ngrok.com' Ports: - 443 +Meta: + ID: 71D2CA02-3905-4DD7-AD0E-C5443F5AC81B + Description: ngrok is a tunneling tool + Date: 2024-09-19 + Modified: 2024-09-19 + References: + - 'ngrok.com' diff --git a/SigmaOutput/SigmaOutput.py b/SigmaOutput/SigmaOutput.py new file mode 100644 index 0000000..af9d166 --- /dev/null +++ b/SigmaOutput/SigmaOutput.py @@ -0,0 +1,114 @@ +import yaml +import json +import os +import logging +import copy + +RMMDIR = './RMMs' +OUTDIR = './ci-output/sigma' +# ensure we don't get references in output yaml +yaml.Dumper.ignore_aliases = lambda *args : True + + +sigma_template = { + "title": "", + "id": "", # guid + "status": "experimental", + "related": [ + # { + # "id": "065b00ca-5d5c-4557-ac95-64a6d0b64d86", + # "type": "similar" + # } + ], + "description": "", + "references": [ + "" + ], + "author": "RMML Authors", + "date": '', # YYYY-MM-DD + "modified": '', # YYYY-MM-DD + "tags": [ + "attack.command-and-control", + "attack.t1219" + ], + "logsource": { + "category": "process_creation", + "product": "windows" + }, + "detection": None, + # { + # "selection": [ + # {"Image|endswith": "\\AnyDesk.exe"}, + # {"Description": "AnyDesk"}, + # {"Product": "AnyDesk"}, + # {"Company": "AnyDesk Software GmbH"}, + # ], + # "condition": "selection", + # }, + "falsepositives": ["Legitimate use"], + "level": "medium", +} + +def generate_sigma(eos, filename): + try: + file = os.path.join(RMMDIR, filename) + if os.path.isfile(file): + with open(file, 'r') as f: + rmm = yaml.safe_load(f) + if eos not in rmm['Executables'] or not rmm['Executables'][eos]: + logging.info('RMM %s doesn\'t have OS: %s', filename, eos) + return + rmm_sigma = copy.deepcopy(sigma_template) + rmm_name = file.removeprefix(RMMDIR).removesuffix('.yml').removesuffix('.yaml')[1:] + rmm_sigma['title'] = f'RMML-{rmm_name}-{eos}' + rmm_sigma['id'] = f"{rmm['Meta']['ID']}-{eos.lower()}" + # add to a list of IDs so that we can add it to all of them when + # we're done building the base ('related') + ids.append(rmm_sigma['id']) + rmm_sigma['description'] = rmm['Meta']['Description'] + rmm_sigma['references'] = rmm['Meta']['References'] + rmm_sigma['date'] = rmm['Meta']['Date'] + rmm_sigma['modified'] = rmm['Meta']['Modified'] + # no change to tags, maybe later + rmm_sigma['logsource']['product'] = eos.lower() + # detection is next + no_wildcards = [] + has_wildcards = [] + for exe in rmm['Executables'][eos]: + if '*' not in exe: + no_wildcards.append(exe) + else: + has_wildcards.append(exe) + rmm_sigma['detection'] = {} + rmm_sigma['detection']['selection1'] = {"Image|endswith": no_wildcards} + if len(has_wildcards) == 0: + rmm_sigma['detection']['condition'] = 'selection1' + else: + rmm_sigma['detection']['selection2'] = {"Image": has_wildcards} + rmm_sigma['detection']['condition'] = 'selection1 or selection2' + # no change to falsepositives + # no change to level + + # add to the output + return rmm_sigma + + except Exception as e: + logging.warning("Error transforming %s. Error: %s", filename, e) + return None + + +sigmas = [] +ids = [] +for filename in os.listdir(RMMDIR): + for eos in ['Windows', 'MacOS', 'Linux']: + rmm_sigma = generate_sigma(eos, filename) + if rmm_sigma: + sigmas.append(rmm_sigma) + +if not os.path.exists(OUTDIR): + os.mkdir(OUTDIR) +for s in sigmas: + outfile = os.path.join(OUTDIR, s['title']) + outfile = outfile + '.yml' + with open(outfile, 'w') as f: + f.write(yaml.dump(s)) \ No newline at end of file diff --git a/SigmaOutput/_sample b/SigmaOutput/_sample new file mode 100644 index 0000000..7337019 --- /dev/null +++ b/SigmaOutput/_sample @@ -0,0 +1,33 @@ +# https://github.com/SigmaHQ/sigma/blob/master/rules/windows/process_creation/proc_creation_win_remote_access_tools_anydesk.yml + +title: Remote Access Tool - AnyDesk Execution +id: b52e84a3-029e-4529-b09b-71d19dd27e94 +status: test +related: + - id: 065b00ca-5d5c-4557-ac95-64a6d0b64d86 + type: similar +description: | + An adversary may use legitimate desktop support and remote access software, such as Team Viewer, Go2Assist, LogMein, AmmyyAdmin, etc, to establish an interactive command and control channel to target systems within networks. + These services are commonly used as legitimate technical support software, and may be allowed by application control within a target environment. + Remote access tools like VNC, Ammyy, and Teamviewer are used frequently when compared with other legitimate software commonly used by adversaries. (Citation: Symantec Living off the Land) +references: + - https://github.com/redcanaryco/atomic-red-team/blob/f339e7da7d05f6057fdfcdd3742bfcf365fee2a9/atomics/T1219/T1219.md#atomic-test-2---anydesk-files-detected-test-on-windows +author: frack113 +date: 2022-02-11 +modified: 2023-03-05 +tags: + - attack.command-and-control + - attack.t1219 +logsource: + category: process_creation + product: windows +detection: + selection: + - Image|endswith: '\AnyDesk.exe' + - Description: AnyDesk + - Product: AnyDesk + - Company: AnyDesk Software GmbH + condition: selection +falsepositives: + - Legitimate use +level: medium diff --git a/Validator/_validate_yml.py b/Validator/_validate_yml.py index 5958441..64b3b76 100644 --- a/Validator/_validate_yml.py +++ b/Validator/_validate_yml.py @@ -1,6 +1,7 @@ import yaml import sys import os +import datetime RMMDIR = './RMMs' OSES = ['Windows','MacOS','Linux'] @@ -57,6 +58,24 @@ def check_netconn(r, nc): if not isinstance(p, (int)): ERRORS.append(f'Found a non-int in {r} Ports. Value: {p}') +def check_meta(r, meta): + keys = ['ID', 'Description', 'Date', 'Modified', 'References'] + for k in keys: + if k not in meta: + ERRORS.append(f'Missing key {k} in Meta on {r}') + if len(ERRORS) > 0: + return + if not isinstance(meta['Description'], str): + ERRORS.append(f"Description on {r} isn't a string") + if not isinstance(meta['Date'], datetime.date): + ERRORS.append(f"Date on {r} isn't a date") + if not isinstance(meta['Modified'], datetime.date): + ERRORS.append(f"Modified on {r} isn't a date") + if not isinstance(meta['References'], list): + ERRORS.append(f"References on {r} isn't a list") + + +IDs = set() for filename in os.listdir(RMMDIR): file = os.path.join(RMMDIR, filename) # checking if it is a file @@ -73,8 +92,21 @@ def check_netconn(r, nc): if 'NetConn' not in rmm: print(f'NetConn not defined in {rmm_name}') sys.exit(1) + if 'Meta' not in rmm: + print(f'Meta not defined in {rmm_name}') + sys.exit(1) + # check the IDs + if 'ID' not in rmm['Meta']: + print(f'ID not defined in {rmm_name}, meta section') + sys.exit(1) + if rmm['Meta']['ID'] not in IDs: + IDs.add(rmm['Meta']['ID']) + else: + print(f'DUPLICATE ID defined in {rmm_name}, meta section') + sys.exit(1) check_executables(rmm_name, rmm['Executables']) check_netconn(rmm_name, rmm['NetConn']) + check_meta(rmm_name, rmm['Meta']) if len(ERRORS) == 0: sys.exit(0) else: