checkpoint-restore / checkpointctl

A tool for in-depth analysis of container checkpoints
Apache License 2.0
87 stars 15 forks source link

feat: add `memparse` sub-command #95

Closed behouba closed 10 months ago

behouba commented 11 months ago

This PR introduces a new sub-command memparse , which allows analyzing processes memory pages. This new feature was discussed here #69.

When used without any arguments, the command displays a table showing the memory sizes of processes. Here's an example:

$ checkpointctl memparse /path/to/checkpoints/jira.tar.gz 

Displaying processes memory sizes from /home/behouba/checkpoints/jira.tar.gz

+-----+--------------+-------------+
| PID | PROCESS NAME | MEMORY SIZE |
+-----+--------------+-------------+
|   1 | tini         | 100.0 KiB   |
+-----+--------------+-------------+
|   2 | java         | 553.5 MiB   |
+-----+--------------+-------------+

If a process ID (pid) is provided, the command prints the memory pages of that specific process in a hexdump-like format. For instance:

$ checkpointctl memparse /path/to/checkpoints/jira.tar.gz  --pid=1 | less

Displaying memory pages content for Process ID 1 from checkpoint: /home/behouba/checkpoints/jira.tar.gz

Address           Hexadecimal                                       ASCII            
-------------------------------------------------------------------------------------
00005633bb080000  f3 0f 1e fa 48 83 ec 08 48 8b 05 d1 4f 00 00 48  |....H...H...O..H|
00005633bb080010  85 c0 74 02 ff d0 48 83 c4 08 c3 00 00 00 00 00  |..t...H.........|
00005633bb080020  ff 35 b2 4e 00 00 f2 ff 25 b3 4e 00 00 0f 1f 00  |.5.N....%.N.....|
00005633bb080030  f3 0f 1e fa 68 00 00 00 00 f2 e9 e1 ff ff ff 90  |....h...........|
*
00005633bb0800a0  f3 0f 1e fa 68 07 00 00 00 f2 e9 71 ff ff ff 90  |....h......q....|
00005633bb0800b0  f3 0f 1e fa 68 08 00 00 00 f2 e9 61 ff ff ff 90  |....h......a....|
00005633bb0800c0  f3 0f 1e fa 68 09 00 00 00 f2 e9 51 ff ff ff 90  |....h......Q....|
00005633bb0800d0  f3 0f 1e fa 68 0a 00 00 00 f2 e9 41 ff ff ff 90  |....h......A....|
00005633bb0800e0  f3 0f 1e fa 68 0b 00 00 00 f2 e9 31 ff ff ff 90  |....h......1....|

This output can be written to a file instead of stdout using the --output flag.

@rst0git, @adrianreber, could you please take a look?

codecov-commenter commented 11 months ago

Codecov Report

Patch coverage: 85.38% and project coverage change: +0.55% :tada:

Comparison is base (8e4f577) 82.78% compared to head (7e107e2) 83.33%.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #95 +/- ## ========================================== + Coverage 82.78% 83.33% +0.55% ========================================== Files 4 5 +1 Lines 633 804 +171 ========================================== + Hits 524 670 +146 - Misses 80 99 +19 - Partials 29 35 +6 ``` | [Files Changed](https://app.codecov.io/gh/checkpoint-restore/checkpointctl/pull/95?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | | |---|---|---| | [memparse.go](https://app.codecov.io/gh/checkpoint-restore/checkpointctl/pull/95?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-bWVtcGFyc2UuZ28=) | `81.96% <81.96%> (ø)` | | | [checkpointctl.go](https://app.codecov.io/gh/checkpoint-restore/checkpointctl/pull/95?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-Y2hlY2twb2ludGN0bC5nbw==) | `93.22% <93.87%> (+0.15%)` | :arrow_up: |

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

github-actions[bot] commented 11 months ago

Test Results

46 tests  +4   46 :heavy_check_mark: +4   1s :stopwatch: ±0s   1 suites ±0     0 :zzz: ±0    1 files   ±0     0 :x: ±0 

Results for commit d9e57423. ± Comparison against base commit 23dc8ace.

:recycle: This comment has been updated with latest results.

rst0git commented 11 months ago

Great work @behouba! It might be useful to extend memparse with support for shared memory in a subsequent pull request. For example, it could be an additional column in the table generated with checkpointctl memparse <checkpoint>.tar and perhaps a new option that shows only the content of pagemap-shmem-{}.img when --pid is used.

rst0git commented 11 months ago

@behouba Would it be possible to update go-criu in a separate pull request?

rst0git commented 11 months ago

@behouba Could you add a section about memory analysis to the README file? It might be good to describe how users can use checkpointctl memparse with an example:

$ sudo podman run --name postgres -e POSTGRES_PASSWORD=mysecret -d postgres
$ sudo podman container checkpoint -l --export=/tmp/postgres.tar.gz
$ sudo checkpointctl memparse --pid 1 /tmp/postgres.tar.gz | grep mysecret
000055f9deed8e70  44 3d 6d 79 73 65 63 72 65 74 00 00 00 00 00 00  |D=mysecret......|
# Start vulnerable web application
$ sudo podman run --name dsvw -p 1234:8000 -d quay.io/rst0git/dsvw

# Perform arbitrary code execution attack: $(echo secret)
$ curl "http://localhost:1234/?domain=www.google.com%3B%20echo%20secret"
nslookup: can't resolve '(null)': Name does not resolve

Name:      www.google.com
Address 1: 142.250.187.228 lhr25s34-in-f4.1e100.net
Address 2: 2a00:1450:4009:820::2004 lhr25s34-in-x04.1e100.net
secret
(reverse-i-search)`': ^C

# Create a checkpoint for forensic analysis and leave the container running
$ sudo podman container checkpoint --leave-running -l -e /tmp/dsvw.tar

# Analyse checkpoint memory to identify the attacker's injected code
$ sudo checkpointctl memparse --pid 1 /tmp/dsvw.tar | grep 'echo secret'
00007faac5711f60  6f 6d 3b 20 65 63 68 6f 20 73 65 63 72 65 74 00  |om; echo secret.|
behouba commented 11 months ago

@behouba Could you add a section about memory analysis to the README file?

@rst0git PTAL, and thank you for providing such good examples.