Skip to content

Commit

Permalink
readme: add examples for memparse usage
Browse files Browse the repository at this point in the history
This commit adds a new section to the README.md file that provides
an example of how to use the memparse sub-command.

Signed-off-by: Kouame Behouba Manasse <behouba@gmail.com>
  • Loading branch information
behouba committed Aug 8, 2023
1 parent 770e424 commit a2884de
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Details on how to create checkpoints with the help of [CRIU][criu] can be found

## Usage

### `show` sub-command

To display an overview of a checkpoint archive you can just use
`checkpointctl show`:

Expand All @@ -41,6 +43,8 @@ $ checkpointctl show /var/lib/kubelet/checkpoints/checkpoint-counters_default-co
+-----------+------------------------------------+--------------+---------+--------------------------------+--------+------------+------------+
```

### `inspect` sub-command

To retrieve low-level information about a container checkpoint, use the `checkpointctl inspect` command:

```console
Expand All @@ -64,6 +68,91 @@ awesome_booth

For a complete list of flags supported, use `checkpointctl inspect --help`.

### `memparse` sub-command

To perform memory analysis of container checkpoints, you can use the `checkpointctl memparse` command.

```console
$ 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....|
```

Here's an example of memory analysis of a PostgreSQL container. In this case, we start a PostgreSQL container with a password set to 'mysecret'. Then, we create a checkpoint of the container and use the `memparse` to find the stored password.

```console
$ 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 -B 1 -A 1 mysecret
000055dd725c1e60 50 4f 53 54 47 52 45 53 5f 50 41 53 53 57 4f 52 |POSTGRES_PASSWOR|
000055dd725c1e70 44 3d 6d 79 73 65 63 72 65 74 00 00 00 00 00 00 |D=mysecret......|
000055dd725c1e80 00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00 |........1.......|
```

Here's another scenario, of memory analysis for a web application container. We start a vulnerable web application container, perform an arbitrary code execution attack, create a checkpoint for forensic analysis while leaving the container running, and finally analyze the checkpoint memory to identify the injected code.

```console
# 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.|
```

For larger processes, it's recommended to write the contents of process memory pages to a file rather than standard output.

To get an overview of process memory sizes within the checkpoint, run `checkpointctl memparse` without arguments.

```console
$ sudo ./checkpointctl memparse /tmp/jira.tar.gz

Displaying processes memory sizes from /tmp/jira.tar.gz

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

In this case given the large size of the java process, it is better to write it output to a file.

```console
$ sudo ./checkpointctl memparse --pid=2 /tmp/jira.tar.gz --output=/tmp/java-memory-pages.txt
Writing memory pages content for process ID 2 from checkpoint: /tmp/jira.tar.gz to file: /tmp/java-memory-pages.txt...
```

Please note that writing large memory pages to a file can take several minutes.

## Installing from source code

1. Clone the repository.
Expand Down

0 comments on commit a2884de

Please sign in to comment.