Skip to content

Conversation

SolitudePy
Copy link
Contributor

Hello, just playing with memory & OS internals.
apparently some legitimate processes do these techniques to have enriched information in their cmdline or so. here are some such processes:

PID     PPID    Exe_Basename    Cmdline_Basename        Comm    Notes

966     1       platform-python3.6      platform-python firewalld       ['Potential cmdline spoofing: exe_file=platform-python3.6;cmdline=platform-python', 'Potential comm spoofing: exe_file=platform-python3.6;comm=firewalld']
991     1       platform-python3.6      platform-python tuned   ['Potential cmdline spoofing: exe_file=platform-python3.6;cmdline=platform-python', 'Potential comm spoofing: exe_file=platform-python3.6;comm=tuned']
1257    1       login   login -- root   login   ['Potential cmdline spoofing: exe_file=login;cmdline=login -- root']
1923    1903    bash    bash    entrypoint.sh   ['Potential comm spoofing: exe_file=bash;comm=entrypoint.sh']
3475    3472    systemd (sd-pam)        (sd-pam)        ['Potential cmdline spoofing: exe_file=systemd;cmdline=(sd-pam)', 'Potential comm spoofing: exe_file=syst
(venv) ubuntu@ubuntuPC:~/Dev/volatility3$ vol -f ~/dumps/procspoof_dump_lin.raw -r json linux.process_spoofing | jq 'map(select(.Notes != "OK"))'
Volatility 3 Framework 2.26.2
Progress:  100.00               Stacking attempts finished           
[
  {
    "Cmdline_Basename": "[malwareX]",
    "Comm": "change_argv",
    "Exe_Basename": "change_argv",
    "Notes": "['Potential cmdline spoofing: exe_file=change_argv;cmdline=[malwareX]']",
    "PID": 6717,
    "PPID": 3482,
    "__children": []
  },
  {
    "Cmdline_Basename": "change_comm",
    "Comm": "malwareX",
    "Exe_Basename": "change_comm",
    "Notes": "['Potential comm spoofing: exe_file=change_comm;comm=malwareX']",
    "PID": 6727,
    "PPID": 3482,
    "__children": []
  }
]

@SolitudePy
Copy link
Contributor Author

(venv) ubuntu@ubuntuPC:~/Dev/volatility3$ vol -f ~/dumps/deleted_proc_dump.raw -r json linux.process_spoofing --pid 4868
Volatility 3 Framework 2.26.2
/home/ubuntu/Dev/volatility3/volatility3/framework/deprecation.py:105: FutureWarning: This plugin (PluginRequirement) has been renamed and will be removed in the first release after 2026-06-01. PluginRequirement is to be deprecated. Use VersionRequirement instead.
  warnings.warn(
Progress:  100.00               Stacking attempts finished           
[
  {
    "Cmdline_Basename": "copied_bash",
    "Comm": "copied_bash",
    "Exe_Basename": "copied_bash (deleted)",
    "Notes": "['Potential Process image deletion: exe_file=copied_bash (deleted)']",
    "PID": 4868,
    "PPID": 4633,
    "__children": []
  }
]

Copy link
Member

@ikelos ikelos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your submission and sorry it took so long to find time to review, this plugin looks fun! It's mostly fine, but it smushes the results together into a string, which is longwinded for humans to read and difficult for programs/plugins to parse. Hopefully this should be pretty straight forward to refactor into returning boolean values. It also feels like as number of the methods here may be useful for other plugins, so first check that other plugins don't already implement them and otherwise consider converting them into classmethods so that they can be called externally...

return None

try:
argv = proc_layer.read(start, size_to_read)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd check to see if existing argument handling isn't done somewhere else (either in another plugin or a task structure). It seems like it might be more useful exposed that way, just to avoid people rewriting it themselves each time and possibly making slight parsing differences each time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ikelos want me to use psaux.PsAux._get_command_line_args ? its not directly exposed as an external function but maybe I can refactor it. also in general I think its better that useful methods are exposed through a dedicated utilities class instead of other plugins?

1 for name in [exe_basename, cmdline_basename, comm] if name
)

is_deleted = exe_basename.endswith(self.deleted)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a good way of identifying this, it should be a separate boolean flag handed around. Stuffing it on the end of a string and then parsing it back out again feels very brittle. I'd make each of your three methods return a tuple (basename, deleted) and then process those, the other two methods can return None but you really should be loading up the basename, and certainly not at the end, because then you can't tell the difference between random file that's been deleted and random file (deleted), within your code the two are indistinguishable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, also I'd rather it depend on my other PR for the linuxutilities function instead of reusing the code here... I'm not sure about a boolean flag and also many gnu-utils already do that (appending (deleted) to a path).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I refactored it now, tell me what you think and if we should also implement it in my lsof PR?

notes.append(f"'Potential Process image deletion: exe_file={exe_basename}'")
exe_basename = exe_basename[: len(self.deleted) * -1]

if available_sources < 2:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely you'd want to highlight that the file was only present in one source? Seems like a sure fire sign that something unusual happened?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kernel threads dont have mm_struct, that means no cmdline and exe_file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose kernel threads can be "flagged" in the output as such?

@SolitudePy
Copy link
Contributor Author

(venv) ubuntu@ubuntuPC:~/Dev/volatility3$ vol -f ~/dumps/deleted_proc_dump.raw linux.malware.process_spoofing --pid 4868 
Volatility 3 Framework 2.26.2
Progress:  100.00               Stacking attempts finished           
PID     PPID    Exe_Basename    Cmdline_Basename        Comm    Cmdline_Spoofed Comm_Spoofed    Exe_Deleted

4868    4633    copied_bash (deleted)   copied_bash     copied_bash     False   False   True
(venv) ubuntu@ubuntuPC:~/Dev/volatility3$ vol -f ~/dumps/procspoof_dump_lin.raw -r json linux.malware.process_spoofing --pid 6727
Volatility 3 Framework 2.26.2
Progress:  100.00               Stacking attempts finished           
[
  {
    "Cmdline_Basename": "change_comm",
    "Cmdline_Spoofed": false,
    "Comm": "malwareX",
    "Comm_Spoofed": true,
    "Exe_Basename": "change_comm",
    "Exe_Deleted": false,
    "PID": 6727,
    "PPID": 3482,
    "__children": []
  }
]

@SolitudePy SolitudePy requested a review from ikelos June 25, 2025 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants