Conversation
Rustdesk doesn't support Mac as a server and the original android path was not supported as a relative path.
|
IDK, what happened with the checks, but this is a complete disaster and i barely know what exactly went wrong. Although linting should make some sort of indication. |
|
|
||
|
|
||
| RemoteAccessLogRecord = create_extended_descriptor([UserRecordDescriptorExtension])( | ||
| "remoteaccess/restdesk/log", GENERIC_LOG_RECORD_FIELDS |
There was a problem hiding this comment.
Typo here on the record descriptor, should be remoteaccess/rustdesk/log
|
@Peter-The-Great Should also use pep8 for formatting as the linter is expecting blank lines and some lines are too long. Have reformatted and attached the two code files here if you like |
|
Alright i have just added the PEP 8 code Style to the code and fixed the typo. |
| @@ -0,0 +1,115 @@ | |||
| import logging | |||
There was a problem hiding this comment.
| import logging | |
| from __future__ import annotations | |
|
|
||
| log = logging.getLogger(__name__) |
There was a problem hiding this comment.
| log = logging.getLogger(__name__) |
| SERVER_GLOBS = [ | ||
| # Windows >= Windows 7 | ||
| "sysvol/Windows/ServiceProfiles/LocalService/AppData/Roaming/RustDesk/log/server/*.log", | ||
|
|
| USER_GLOBS = [ | ||
| # Windows | ||
| "AppData/Roaming/Rustdesk/log/*.log", | ||
|
|
||
| # Linux | ||
| ".local/share/logs/RustDesk/server/*.log", | ||
|
|
||
| # Android | ||
| "storage/emulated/0/RustDesk/logs/*.log", | ||
|
|
||
| # Mac | ||
| "Library/Logs/RustDesk/*.log", |
There was a problem hiding this comment.
| USER_GLOBS = [ | |
| # Windows | |
| "AppData/Roaming/Rustdesk/log/*.log", | |
| # Linux | |
| ".local/share/logs/RustDesk/server/*.log", | |
| # Android | |
| "storage/emulated/0/RustDesk/logs/*.log", | |
| # Mac | |
| "Library/Logs/RustDesk/*.log", | |
| USER_GLOBS = [ | |
| # Windows | |
| "AppData/Roaming/Rustdesk/log/*.log", | |
| # Linux | |
| ".local/share/logs/RustDesk/server/*.log", | |
| # Android | |
| "storage/emulated/0/RustDesk/logs/*.log", | |
| # Mac | |
| "Library/Logs/RustDesk/*.log", |
|
|
||
| assert records[0].ts == datetime(2025, 1, 1, 13, 4, 8, 350802, tzinfo=timezone.utc) | ||
| assert records[0].message == "DEBUG src\\server\\connection.rs:983 #1362 Connection opened from REDACTED IP:6074." | ||
| assert records[0].source == "sysvol/Windows/ServiceProfiles/LocalService/AppData/Roaming/RustDesk/log/server/TestRustdesk.log" |
There was a problem hiding this comment.
| assert records[0].source == "sysvol/Windows/ServiceProfiles/LocalService/AppData/Roaming/RustDesk/log/server/TestRustdesk.log" | |
| assert ( | |
| records[0].source | |
| == "sysvol/Windows/ServiceProfiles/LocalService/AppData/Roaming/RustDesk/log/server/TestRustdesk.log" | |
| ) |
| user = None | ||
| for log_glob in self.SERVER_GLOBS: | ||
| for log_file in self.target.fs.path().glob(log_glob): | ||
| self.log_files.add((log_file, user)) |
There was a problem hiding this comment.
| user = None | |
| for log_glob in self.SERVER_GLOBS: | |
| for log_file in self.target.fs.path().glob(log_glob): | |
| self.log_files.add((log_file, user)) | |
| for log_glob in self.SERVER_GLOBS: | |
| for log_file in self.target.fs.path().glob(log_glob): | |
| self.log_files.add((log_file, None)) |
| def __init__(self, target): | ||
| super().__init__(target) | ||
|
|
||
| self.log_files: set[tuple[TargetPath, UserDetails]] = set() |
There was a problem hiding this comment.
| self.log_files: set[tuple[TargetPath, UserDetails]] = set() | |
| self.log_files: set[tuple[TargetPath, UserDetails | None]] = set() |
|
|
||
| def test_rustdesk_plugin_log(target_win_users: Target, fs_win: VirtualFilesystem) -> None: | ||
| fs_win.map_file( | ||
| "sysvol/Windows/ServiceProfiles/LocalService/AppData/Roaming/RustDesk/log/server/TestRustdesk.log", |
There was a problem hiding this comment.
| "sysvol/Windows/ServiceProfiles/LocalService/AppData/Roaming/RustDesk/log/server/TestRustdesk.log", | |
| "Windows/ServiceProfiles/LocalService/AppData/Roaming/RustDesk/log/server/TestRustdesk.log", |
|
|
||
| ts, level, source, message = match.groups() | ||
|
|
||
| timestamp = datetime.fromisoformat(ts) |
There was a problem hiding this comment.
It looks like the ts parsed from the log file is not a valid ISO format timestamp because of the space between the timestamp and +01:00. This causes the tests to fail currently.
| line = line.strip() | ||
|
|
||
| try: | ||
| # Still needs to be checked for Rustdesk implementation | ||
| match = re.match(r"\[(.*?)\] (\w+) \[(.*?)\] (.*)", line) | ||
| if not match: | ||
| raise ValueError("Line does not match expected format") | ||
|
|
||
| ts, level, source, message = match.groups() | ||
|
|
||
| timestamp = datetime.fromisoformat(ts) | ||
| message = re.sub(r"\s\s+", " ", f"{level} {source} {message}") | ||
|
|
||
| yield self.RemoteAccessLogRecord( | ||
| ts=timestamp, | ||
| message=message, | ||
| source=log_file, | ||
| _target=self.target, | ||
| _user=user, | ||
| ) | ||
|
|
||
| except ValueError as e: | ||
| self.target.log.warning("Could not parse log line in file %s: '%s'", log_file, line) | ||
| self.target.log.debug("", exc_info=e) |
There was a problem hiding this comment.
| line = line.strip() | |
| try: | |
| # Still needs to be checked for Rustdesk implementation | |
| match = re.match(r"\[(.*?)\] (\w+) \[(.*?)\] (.*)", line) | |
| if not match: | |
| raise ValueError("Line does not match expected format") | |
| ts, level, source, message = match.groups() | |
| timestamp = datetime.fromisoformat(ts) | |
| message = re.sub(r"\s\s+", " ", f"{level} {source} {message}") | |
| yield self.RemoteAccessLogRecord( | |
| ts=timestamp, | |
| message=message, | |
| source=log_file, | |
| _target=self.target, | |
| _user=user, | |
| ) | |
| except ValueError as e: | |
| self.target.log.warning("Could not parse log line in file %s: '%s'", log_file, line) | |
| self.target.log.debug("", exc_info=e) | |
| if line := line.strip(): | |
| try: | |
| # Still needs to be checked for Rustdesk implementation | |
| match = re.match(r"\[(.*?)\] (\w+) \[(.*?)\] (.*)", line) | |
| if not match: | |
| raise ValueError("Line does not match expected format") | |
| ts, level, source, message = match.groups() | |
| timestamp = datetime.fromisoformat(ts) | |
| message = re.sub(r"\s\s+", " ", f"{level} {source} {message}") | |
| yield self.RemoteAccessLogRecord( | |
| ts=timestamp, | |
| message=message, | |
| source=log_file, | |
| _target=self.target, | |
| _user=user, | |
| ) | |
| except ValueError as e: | |
| self.target.log.warning("Could not parse log line in file %s: '%s'", log_file, line) | |
| self.target.log.debug("", exc_info=e) |
|
|
||
| @export(record=RemoteAccessLogRecord) | ||
| def logs(self) -> Iterator[RemoteAccessLogRecord]: | ||
| """Parse Rustdesk log files. |
There was a problem hiding this comment.
| """Parse Rustdesk log files. | |
| """Parse RustDesk log files. |
| def logs(self) -> Iterator[RemoteAccessLogRecord]: | ||
| """Parse Rustdesk log files. | ||
|
|
||
| Rustdesk is remote access software that allows users to connect to a remote computer. |
There was a problem hiding this comment.
| Rustdesk is remote access software that allows users to connect to a remote computer. | |
| RustDesk is a remote desktop application can be used by adversaries to get (persistent) access to a machine. |
| The project is open source and can be found at: https://github.com/rustdesk/rustdesk/ | ||
|
|
||
| The log files are stored in different locations, based on the Target OS and client type. | ||
| Unlike Anydesk, Rustdesk does have a carry a time zone designator (TZD). |
There was a problem hiding this comment.
| Unlike Anydesk, Rustdesk does have a carry a time zone designator (TZD). | |
| Unlike AnyDesk, RustDesk does carry a time zone designator (TZD). |
|
Looks cool guys, thanks for adding this to the main branch. Havent really been up to date with the pull request, but cool to see the progress being made on it. |
@Peter-The-Great this PR is not merged into main yet. I have requested some changes for the code in this PR that can work into this PR. After everything is reviewed and approved, this PR will be merged into main. |
|
Created a new PR with these suggested changes: #1104 |
This PR adds support to inspect
Rustdesklogs on supported targets (#983). I have tested the Plugin on a both a Linux and Windows machine and they do appear to work. However, if there is any issue with the plugin, just let me know right away and I will try to look in to it.