Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux - Boottime support #1317

Open
wants to merge 17 commits into
base: develop
Choose a base branch
from

Conversation

gcmoreira
Copy link
Contributor

@gcmoreira gcmoreira commented Oct 18, 2024

In this PR we introduce the boot time support to the Volatility3 framework.

This enables other plugins to provide UTC datetime information based on the system boot time. A prime example is the linux.pslist plugin, which has been enhanced as part of this effort. Additionally, we have introduced a new linux.boottime plugin to retrieve the system boot time date, supporting also time namespaces (kernels >= 5.6). Both plugins offer support for the Timeliner.

linux.pslist

Note: The task creation time is seen from the root time namespece, which is what's expected.

6.8.0-41

$ ./vol.py \
    -r pretty \
    -f ./dump_ubuntu2404amd64_6.8.0-41-generic_clocks_ns.core \
    linux.pslist 
Volatility 3 Framework 2.11.0
  |     OFFSET (V) |  PID |  TID | PPID |            COMM |                  CREATION TIME | File output
* | 0x8a8881300000 |    1 |    1 |    0 |         systemd | 2024-10-17 09:17:39.056885 UTC |    Disabled
* | 0x8a8881305200 |    2 |    2 |    0 |        kthreadd | 2024-10-17 09:17:39.056885 UTC |    Disabled
* | 0x8a8881302900 |    3 |    3 |    2 | pool_workqueue_ | 2024-10-17 09:17:39.056885 UTC |    Disabled
...

4.4.0-142

$ ./vol.py \
    -r pretty \
    -f ./dump_ubuntu140464bit_4.4.0-142-generic_clocks.core \
    linux.pslist 
Volatility 3 Framework 2.11.0
  |     OFFSET (V) | PID | TID | PPID |            COMM |                  CREATION TIME | File output
* | 0x88001de40000 |   1 |   1 |    0 |            init | 2024-10-18 00:17:01.032000 UTC |    Disabled
* | 0x88001de40f00 |   2 |   2 |    0 |        kthreadd | 2024-10-18 00:17:01.032000 UTC |    Disabled
* | 0x88001de41e00 |   3 |   3 |    2 |     ksoftirqd/0 | 2024-10-18 00:17:01.036000 UTC |    Disabled
...

3.13.0-185

$ ./vol.py \
    -r pretty \
    -f ./dump_ubuntu120464bit_3.13.0-185-generic_clocks.core \
    linux.pslist 
Volatility 3 Framework 2.11.0
  |     OFFSET (V) |  PID |  TID | PPID |            COMM |                  CREATION TIME | File output
* | 0x88001d7b0000 |    1 |    1 |    0 |            init | 2024-10-17 08:54:37.044000 UTC |    Disabled
* | 0x88001d7b1800 |    2 |    2 |    0 |        kthreadd | 2024-10-17 08:54:37.044000 UTC |    Disabled
* | 0x88001d7b3000 |    3 |    3 |    2 |     ksoftirqd/0 | 2024-10-17 08:54:37.044000 UTC |    Disabled
* | 0x88001d7b4800 |    4 |    4 |    2 |     kworker/0:0 | 2024-10-17 08:54:37.044000 UTC |    Disabled

3.2.0-4

$ ./vol.py \
    -r pretty \
    -f ./dump_debian764bit_3.2.0-4-amd64_clocks2.core \
    linux.pslist 
Volatility 3 Framework 2.11.0
  |     OFFSET (V) |  PID |  TID | PPID |            COMM |                  CREATION TIME | File output
* | 0x88001f900740 |    1 |    1 |    0 |            init | 2024-10-16 23:18:24.016001 UTC |    Disabled
* | 0x88001f900040 |    2 |    2 |    0 |        kthreadd | 2024-10-16 23:18:24.016001 UTC |    Disabled
* | 0x88001f903780 |    3 |    3 |    2 |     ksoftirqd/0 | 2024-10-16 23:18:24.020001 UTC |    Disabled
* | 0x88001f9077c0 |    5 |    5 |    2 |     kworker/u:0 | 2024-10-16 23:18:24.020001 UTC |    Disabled
...

linux.boottime

In this first example, we will examine the boot time on a system with multiple time namespaces.

Let's start by inspecting the root time namespace.

$ date +"%z +%Z"
+0000 +UTC

$ readlink /proc/$$/ns/time
time:[4026531834]

$ uptime --since
2024-10-10 11:29:21

Next, let's create a new time namespace with a different boot time, -2days:

$ sudo unshare --time --mount-proc --pid --fork --boottime $((2*24*60*60)) bash

# readlink /proc/$$/ns/time
time:[4026532228]

# uptime --since
2024-10-08 11:29:21

It's time to examine a memory dump that includes the steps mentioned above.

$ ./vol.py \
    -r pretty \
    -f ./dump_ubuntu2404amd64_6.8.0-41-generic_clocks2.core  \
    linux.boottime 
Volatility 3 Framework 2.11.0
  |    TIME NS |                      Boot Time
* | 4026531834 | 2024-10-10 11:29:21.866469 UTC
* | 4026532228 | 2024-10-08 11:29:21.866469 UTC

Other kernels tests:

6.8.0-41

$ ./vol.py \
    -r pretty \
    -f ./dump_ubuntu2404amd64_6.8.0-41-generic_clocks_new_ns.core \
    linux.boottime 
Volatility 3 Framework 2.11.0
  |    TIME NS |                      Boot Time
* | 4026531834 | 2024-10-17 09:17:39.758709 UTC
* | 4026532227 | 2024-10-15 09:17:39.758709 UTC

4.4.0-142

$ ./vol.py \
    -r pretty \
    -f ./dump_ubuntu140464bit_4.4.0-142-generic_clocks.core \
    linux.boottime 
Volatility 3 Framework 2.11.0
  | TIME NS |                      Boot Time
* |       - | 2024-10-18 00:17:01.597735 UTC

3.13.0-185

$ ./vol.py \
    -r pretty \
    -f ./dump_ubuntu120464bit_3.13.0-185-generic_clocks.core \
    linux.boottime 
Volatility 3 Framework 2.11.0
  | TIME NS |                      Boot Time
* |       - | 2024-10-17 08:54:37.076344 UTC

3.2.0-4

$ ./vol.py \
    -r pretty \
    -f ./dump_debian764bit_3.2.0-4-amd64_clocks2.core \
    linux.boottime 
Volatility 3 Framework 2.11.0
  | TIME NS |                      Boot Time
* |       - | 2024-10-16 23:18:24.063932 UTC

Timeliner

 $ ./vol.py \
    -r pretty \
    -f ./dump_ubuntu2404amd64_6.8.0-41-generic_clocks2.core \
    timeliner.Timeliner \
    --plugin-filter linux.boottime linux.pslist
Volatility 3 Framework 2.11.0
  |   Plugin |                                       Description |                   Created Date | Modified Date | Accessed Date | Changed Date
* | Boottime |    System boot time for time namespace 4026532228 | 2024-10-08 11:29:21.866469 UTC |           N/A |           N/A |          N/A
* |   PsList |             Process 1/1 systemd (167256783890688) | 2024-10-10 11:29:21.055809 UTC |           N/A |           N/A |          N/A
* |   PsList |            Process 2/2 kthreadd (167256783880192) | 2024-10-10 11:29:21.055809 UTC |           N/A |           N/A |          N/A
* |   PsList |     Process 3/3 pool_workqueue_ (167256783901184) | 2024-10-10 11:29:21.055809 UTC |           N/A |           N/A |          N/A
...
* | Boottime |    System boot time for time namespace 4026531834 | 2024-10-10 11:29:21.866469 UTC |           N/A |           N/A |          N/A
* |   PsList | Process 167/167 kworker/R-raid5 (167257237148160) | 2024-10-10 11:29:21.963241 UTC |           N/A |           N/A |          N/A
* |   PsList |     Process 206/206 jbd2/dm-0-8 (167257237367040) | 2024-10-10 11:29:22.145494 UTC |           N/A |           N/A |          N/A
* |   PsList | Process 207/207 kworker/R-ext4- (167257237356544) | 2024-10-10 11:29:22.145652 UTC |           N/A |           N/A |          N/A

@gcmoreira
Copy link
Contributor Author

gcmoreira commented Oct 18, 2024

Hey @ikelos, the tests are failing because the ISF in linux.zip (linux-image-3.2.0-4-amd64-dbg_3.2.57-3+deb7u2_amd64.json.xz) doesn't contain the symbol types. So in this line the call to vmlinux.object_from_symbol() returns a void type which then fails in TimespecVol3.new_from_timespec() because it's the wrong type.

The ISF is circa 2018 and needs to be updated.

$ unzip -l linux.zip linux/linux-image-3.2.0-4-amd64-dbg_3.2.57-3+deb7u2_amd64.json.xz
Archive:  linux.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
   776408  2018-07-19 03:04   linux/linux-image-3.2.0-4-amd64-dbg_3.2.57-3+deb7u2_amd64.json.xz
---------                     -------
   776408                     1 file

Alternatively, this will be fixed once #1316 is merged. See the following using the same sample:

$ ./vol.py \
    --remote-isf-url 'https://github.com/Abyss-W4tcher/volatility3-symbols/raw/master/banners/banners.json' \
    -f ./linux-sample-1.bin \
    linux.pslist
Volatility 3 Framework 2.11.0
Progress:  100.00               Stacking attempts finished                 
OFFSET (V)      PID     TID     PPID    COMM    CREATION TIME   File output

0x88001f994740  1       1       0       init    2014-06-24 10:22:33.016001 UTC  Disabled
0x88001f994040  2       2       0       kthreadd        2014-06-24 10:22:33.016001 UTC  Disabled
0x88001f9a2780  3       3       2       ksoftirqd/0     2014-06-24 10:22:33.056003 UTC  Disabled
0x88001f9a67c0  5       5       2       kworker/u:0     2014-06-24 10:22:33.056003 UTC  Disabled

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.

Generally the plugin seems fine, we need to get the tests sorted as soon as possible. That's one for @npetroni . My worry with this is the deviation from a well known standard for seemingly little gain and the naming of one of the classes feels quite vague/rushed. Otherwise generally happy with it, like the comments detailing exactly which case is for which kernel version (down to the git commit in some places, I'm assuming?).

volatility3/framework/plugins/timeliner.py Outdated Show resolved Hide resolved
volatility3/framework/symbols/linux/__init__.py Outdated Show resolved Hide resolved
volatility3/framework/symbols/linux/__init__.py Outdated Show resolved Hide resolved
volatility3/framework/symbols/linux/__init__.py Outdated Show resolved Hide resolved
volatility3/framework/symbols/linux/__init__.py Outdated Show resolved Hide resolved
volatility3/framework/symbols/linux/__init__.py Outdated Show resolved Hide resolved
volatility3/framework/plugins/timeliner.py Outdated Show resolved Hide resolved
…use the created time for the boot time plugin
…object instead of modifying the original. It also normalizes its values, aligning with the behavior of the other addition and subtraction operators
Move TimespecVol3 methods to an abstract class Timespec64Abstract, which is now inherited by Timespec64 and Timespec64Concrete.
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.

Looks good, thanks! 5:)

@ikelos
Copy link
Member

ikelos commented Oct 30, 2024

Ok, this seems to be failing on boottime = Timespec64Concrete.new_from_timespec(wall_to_monotonic) which expects a Timespec64Abstract, but doesn't get one seemingly. Happy to merge this once we get the test passing/figure out what's going wrong.

@ikelos
Copy link
Member

ikelos commented Oct 30, 2024

It looks like wall_to_monotonic, which is made from n object_from_symbol call, isn't returning a timespec64 (or at least not something that looks like a Timespec64Abstract, which is what it needs)

@gcmoreira
Copy link
Contributor Author

@ikelos Alright, merge conflict resolved. It will be good to go once the ISF is fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants