Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add post/multi/recon/sudo_commands #10021

Merged
merged 4 commits into from
Jun 14, 2018
Merged

Add post/multi/recon/sudo_commands #10021

merged 4 commits into from
Jun 14, 2018

Conversation

bcoles
Copy link
Contributor

@bcoles bcoles commented May 14, 2018

Add post/multi/recon/sudo_commands.

    This module examines the sudoers configuration for the session user
    and lists the commands executable via sudo.

    This module also inspects each command and reports potential avenues
    for privileged code execution due to poor file system permissions or
    permitting execution of executables known to be useful for privesc,
    such as utilities designed for file read/write, user modification,
    or execution of arbitrary operating system commands.

    Note, you may need to provide the password for the session user.

Verification

  • Start msfconsole
  • Get a session
  • use post/multi/recon/sudo_commands
  • set SESSION <ID>
  • run
  • Verify available sudo commands are displayed

Tested on:

  • CentOS 5.6
  • Solaris 11.1
  • Debian 9.0.0
  • Fedora 11
  • RHEL 5.11
  • Linux Mint 18.3
  • HardenedBSD 10 - (requires SUDO_PATH to be changed to /usr/bin/local/sudo)
  • Mac OSX Lion 10.7

Example Output

msf5 post(multi/recon/sudo_commands) > set session 3
session => 3
msf5 post(multi/recon/sudo_commands) > set verbose false
verbose => false
msf5 post(multi/recon/sudo_commands) > run

[+] Found 1 sudo entries for current user
[+] sudo any command!

Sudo Commands
=============

  Command  RunAsUsers  RunAsGroups  Password?  Privesc?
  -------  ----------  -----------  ---------  --------
  ALL      ALL                      false      true

[+] Output stored in: /root/.msf4/loot/20180514141941_default_172.16.191.169_sudo.commands_870128.txt
[*] Post module execution completed
msf5 post(multi/recon/sudo_commands) > set verbose true
verbose => true
msf5 post(multi/recon/sudo_commands) > run

[*] Executing: /usr/bin/sudo -l -l -n
[*] Executing: echo password1 | /usr/bin/sudo -S -l -l
[*] Output:
Matching Defaults entries for centos on this host:
    requiretty, !visiblepw, env_reset, env_keep="COLORS DISPLAY HOSTNAME
    HISTSIZE INPUTRC KDEDIR LS_COLORS MAIL PS1 PS2 QTDIR USERNAME LANG
    LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES
    LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL
    LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"

User centos may run the following commands on this host:

Sudoers entry:
    RunAsUsers: ALL
    Commands: 
	NOPASSWD: ALL

[+] Found 1 sudo entries for current user
[*] Command: "ALL" RunAsUsers: ALL without providing a password
[+] sudo any command!

Sudo Commands
=============

  Command  RunAsUsers  RunAsGroups  Password?  Privesc?
  -------  ----------  -----------  ---------  --------
  ALL      ALL                      false      true

[+] Output stored in: /root/.msf4/loot/20180514141951_default_172.16.191.169_sudo.commands_992679.txt
[*] Post module execution completed
msf5 post(multi/recon/sudo_commands) > cat /root/.msf4/loot/20180514141951_default_172.16.191.169_sudo.commands_992679.txt
[*] exec: cat /root/.msf4/loot/20180514141951_default_172.16.191.169_sudo.commands_992679.txt

Command,RunAsUsers,RunAsGroups,Password?,Privesc?
"ALL","ALL","","false","true"
msf5 post(multi/recon/sudo_commands) > set session 5
session => 5
msf5 post(multi/recon/sudo_commands) > set verbose false
verbose => false
msf5 post(multi/recon/sudo_commands) > run

[+] Found 4 sudo entries for current user
[+] sudo any command!
[+] /usr/bin/echo matches known privesc executable 'echo' !
[+] /usr/bin/echo matches known privesc executable 'echo' !
[+] /usr/bin/echo matches known privesc executable 'echo' !

Sudo Commands
=============

  Command                                                                                                         RunAsUsers  RunAsGroups  Password?  Privesc?
  -------                                                                                                         ----------  -----------  ---------  --------
  /usr/bin/echo \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA this is a really long line that will totally line wrap\"        ALL                      true       true
  /usr/bin/echo \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA this is another really long line that will totally line wrap\"  ALL                      true       true
  /usr/bin/echo \"this, line, contains, commas\"                                                                  ALL                      true       true
  ALL                                                                                                             ALL                      true       true

[+] Output stored in: /root/.msf4/loot/20180514142005_default_172.16.191.220_sudo.commands_378763.txt
[*] Post module execution completed
msf5 post(multi/recon/sudo_commands) > set verbose true
verbose => true
msf5 post(multi/recon/sudo_commands) > run

[*] Executing: /usr/bin/sudo -l -l -n
[*] Executing: echo password1 | /usr/bin/sudo -S -l -l
[*] Output:
Password: User jack may run the following commands on this host:

Sudoers entry:
    RunAsUsers: ALL
    Commands:
	ALL

Sudoers entry:
    RunAsUsers: ALL
    Commands:
	/usr/bin/echo \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA this is a really long line
    that will totally line wrap\"

Sudoers entry:
    RunAsUsers: ALL
    Commands:
	/usr/bin/echo \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA this is another really long
    line that will totally line wrap\"

Sudoers entry:
    RunAsUsers: ALL
    Commands:
	/usr/bin/echo \"this\, line\, contains\, commas\"

[+] Found 4 sudo entries for current user
[*] Command: "ALL" RunAsUsers: ALL
[+] sudo any command!
[*] Command: "/usr/bin/echo \\\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA this is a really long line that will totally line wrap\\\"" RunAsUsers: ALL
[+] /usr/bin/echo matches known privesc executable 'echo' !
[*] Command: "/usr/bin/echo \\\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA this is another really long line that will totally line wrap\\\"" RunAsUsers: ALL
[+] /usr/bin/echo matches known privesc executable 'echo' !
[*] Command: "/usr/bin/echo \\\"this, line, contains, commas\\\"" RunAsUsers: ALL
[+] /usr/bin/echo matches known privesc executable 'echo' !

Sudo Commands
=============

  Command                                                                                                         RunAsUsers  RunAsGroups  Password?  Privesc?
  -------                                                                                                         ----------  -----------  ---------  --------
  /usr/bin/echo \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA this is a really long line that will totally line wrap\"        ALL                      true       true
  /usr/bin/echo \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA this is another really long line that will totally line wrap\"  ALL                      true       true
  /usr/bin/echo \"this, line, contains, commas\"                                                                  ALL                      true       true
  ALL                                                                                                             ALL                      true       true

[+] Output stored in: /root/.msf4/loot/20180514142012_default_172.16.191.220_sudo.commands_578611.txt
[*] Post module execution completed
msf5 post(multi/recon/sudo_commands) > cat /root/.msf4/loot/20180514142012_default_172.16.191.220_sudo.commands_578611.txt
[*] exec: cat /root/.msf4/loot/20180514142012_default_172.16.191.220_sudo.commands_578611.txt

Command,RunAsUsers,RunAsGroups,Password?,Privesc?
"/usr/bin/echo \""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA this is a really long line that will totally line wrap\""","ALL","","true","true"
"/usr/bin/echo \""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA this is another really long line that will totally line wrap\""","ALL","","true","true"
"/usr/bin/echo \""this, line, contains, commas\""","ALL","","true","true"
"ALL","ALL","","true","true"
msf5 post(multi/recon/sudo_commands) > set session 7
session => 7
msf5 post(multi/recon/sudo_commands) > set verbose false
verbose => false
msf5 post(multi/recon/sudo_commands) > run

[+] Found 3 sudo entries for current user
[+] /bin/cat matches known privesc executable 'cat' !
[+] /bin/sh matches known privesc executable 'sh' !
[+] /bin/cp matches known privesc executable 'cp' !
[+] /tmp/echo does not exist and /tmp is writable!
[+] /bin/echo matches known privesc executable 'echo' !

Sudo Commands
=============

  Command                                    RunAsUsers  RunAsGroups  Password?  Privesc?
  -------                                    ----------  -----------  ---------  --------
  /bin/cat                                   ALL                      false      true
  /bin/cp /tmp/source /tmp/destination       ALL         ALL          true       true
  /bin/echo sudo's output sucks for parsing  ALL         ALL          true       true
  /bin/ping                                  ALL         ALL          true       false
  /bin/sh                                    ALL                      true       true
  /sbin/dhclient                             ALL         ALL          true       false
  /sbin/ifconfig                             ALL         ALL          true       false
  /sbin/iptables                             ALL         ALL          true       false
  /sbin/iwconfig                             ALL         ALL          true       false
  /sbin/mii-tool                             ALL         ALL          true       false
  /sbin/route                                ALL         ALL          true       false
  /tmp/echo sudo's output sucks for parsing  ALL         ALL          true       true
  /usr/bin/net                               ALL         ALL          true       false
  /usr/bin/rfcomm                            ALL         ALL          true       false
  /usr/bin/wvdial                            ALL         ALL          true       false

[+] Output stored in: /root/.msf4/loot/20180514142037_default_172.16.191.169_sudo.commands_087764.txt
[*] Post module execution completed
msf5 post(multi/recon/sudo_commands) > set verbose true
rverbose => true
umsf5 post(multi/recon/sudo_commands) > run

[*] Executing: /usr/bin/sudo -l -l -n
[*] Executing: echo password1 | /usr/bin/sudo -S -l -l
[*] Output:
Matching Defaults entries for test on this host:
    requiretty, !visiblepw, env_reset, env_keep="COLORS DISPLAY HOSTNAME
    HISTSIZE INPUTRC KDEDIR LS_COLORS MAIL PS1 PS2 QTDIR USERNAME LANG
    LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES
    LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL
    LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"

User test may run the following commands on this host:

Sudoers entry:
    RunAsUsers: ALL
    Commands: 
	NOPASSWD: /bin/cat
    RunAsUsers: ALL
    Commands: 
	/bin/sh

Sudoers entry:
    RunAsUsers: ALL
    RunAsGroups: ALL
    Commands: 
	/sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net,
    /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig,
    /sbin/mii-tool

Sudoers entry:
    RunAsUsers: ALL
    RunAsGroups: ALL
    Commands: 
	/bin/cp /tmp/source /tmp/destination, /tmp/echo sudo's output sucks for
    parsing, /bin/echo sudo's output sucks for parsing

[+] Found 3 sudo entries for current user
[*] Command: "/bin/cat" RunAsUsers: ALL without providing a password
[+] /bin/cat matches known privesc executable 'cat' !
[*] Command: "/bin/sh" RunAsUsers: ALL
[+] /bin/sh matches known privesc executable 'sh' !
[*] Command: "/sbin/route" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/sbin/ifconfig" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/bin/ping" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/sbin/dhclient" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/usr/bin/net" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/sbin/iptables" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/usr/bin/rfcomm" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/usr/bin/wvdial" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/sbin/iwconfig" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/sbin/mii-tool" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/bin/cp /tmp/source /tmp/destination" RunAsUsers: ALL RunAsGroups: ALL
[+] /bin/cp matches known privesc executable 'cp' !
[*] Command: "/tmp/echo sudo's output sucks for parsing" RunAsUsers: ALL RunAsGroups: ALL
[+] /tmp/echo does not exist and /tmp is writable!
[*] Command: "/bin/echo sudo's output sucks for parsing" RunAsUsers: ALL RunAsGroups: ALL
[+] /bin/echo matches known privesc executable 'echo' !

Sudo Commands
=============

  Command                                    RunAsUsers  RunAsGroups  Password?  Privesc?
  -------                                    ----------  -----------  ---------  --------
  /bin/cat                                   ALL                      false      true
  /bin/cp /tmp/source /tmp/destination       ALL         ALL          true       true
  /bin/echo sudo's output sucks for parsing  ALL         ALL          true       true
  /bin/ping                                  ALL         ALL          true       false
  /bin/sh                                    ALL                      true       true
  /sbin/dhclient                             ALL         ALL          true       false
  /sbin/ifconfig                             ALL         ALL          true       false
  /sbin/iptables                             ALL         ALL          true       false
  /sbin/iwconfig                             ALL         ALL          true       false
  /sbin/mii-tool                             ALL         ALL          true       false
  /sbin/route                                ALL         ALL          true       false
  /tmp/echo sudo's output sucks for parsing  ALL         ALL          true       true
  /usr/bin/net                               ALL         ALL          true       false
  /usr/bin/rfcomm                            ALL         ALL          true       false
  /usr/bin/wvdial                            ALL         ALL          true       false

[+] Output stored in: /root/.msf4/loot/20180514142050_default_172.16.191.169_sudo.commands_880368.txt
[*] Post module execution completed
msf5 post(multi/recon/sudo_commands) > cat /root/.msf4/loot/20180514142050_default_172.16.191.169_sudo.commands_880368.txt
[*] exec: cat /root/.msf4/loot/20180514142050_default_172.16.191.169_sudo.commands_880368.txt

Command,RunAsUsers,RunAsGroups,Password?,Privesc?
"/bin/cat","ALL","","false","true"
"/bin/cp /tmp/source /tmp/destination","ALL","ALL","true","true"
"/bin/echo sudo's output sucks for parsing","ALL","ALL","true","true"
"/bin/ping","ALL","ALL","true","false"
"/bin/sh","ALL","","true","true"
"/sbin/dhclient","ALL","ALL","true","false"
"/sbin/ifconfig","ALL","ALL","true","false"
"/sbin/iptables","ALL","ALL","true","false"
"/sbin/iwconfig","ALL","ALL","true","false"
"/sbin/mii-tool","ALL","ALL","true","false"
"/sbin/route","ALL","ALL","true","false"
"/tmp/echo sudo's output sucks for parsing","ALL","ALL","true","true"
"/usr/bin/net","ALL","ALL","true","false"
"/usr/bin/rfcomm","ALL","ALL","true","false"
"/usr/bin/wvdial","ALL","ALL","true","false"
msf5 post(multi/recon/sudo_commands) > set session 8
session => 8
msf5 post(multi/recon/sudo_commands) > set verbose false
verbose => false
msf5 post(multi/recon/sudo_commands) > run

[+] Found 4 sudo entries for current user
[+] /bin/cat matches known privesc executable 'cat' !
[+] /tmp/asdf does not exist and /tmp is writable!
[+] /bin/echo matches known privesc executable 'echo' !
[+] /bin/echo matches known privesc executable 'echo' !

Sudo Commands
=============

  Command                                                                                             RunAsUsers  RunAsGroups  Password?  Privesc?
  -------                                                                                             ----------  -----------  ---------  --------
  /bin/cat                                                                                            ALL         ALL          true       true
  /bin/echo \"AAAAAAAAAAAAAAAAAAAAAAAA this is a really long line that will totally linewrap\"        ALL                      true       true
  /bin/echo \"AAAAAAAAAAAAAAAAAAAAAAAA this is another really long line that will totally linewrap\"  ALL                      true       true
  /tmp/asdf                                                                                           ALL                      true       true
  /usr/bin/id                                                                                         ALL         ALL          true       false

[+] Output stored in: /root/.msf4/loot/20180514142114_default_172.16.191.236_sudo.commands_177614.txt
[*] Post module execution completed
msf5 post(multi/recon/sudo_commands) > set verbose true
verbose => true
msf5 post(multi/recon/sudo_commands) > run

[*] Executing: /usr/bin/sudo -l -l -n
[*] Output:
Matching Defaults entries for user on debian-9-0-x64:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User user may run the following commands on debian-9-0-x64:

Sudoers entry:
    RunAsUsers: ALL
    RunAsGroups: ALL
    Commands:
	/usr/bin/id
	/bin/cat

Sudoers entry:
    RunAsUsers: ALL
    Commands:
	/tmp/asdf

Sudoers entry:
    RunAsUsers: ALL
    Commands:
	/bin/echo \"AAAAAAAAAAAAAAAAAAAAAAAA this is a really long line that will totally linewrap\"

Sudoers entry:
    RunAsUsers: ALL
    Commands:
	/bin/echo \"AAAAAAAAAAAAAAAAAAAAAAAA this is another really long line that will totally linewrap\"

[+] Found 4 sudo entries for current user
[*] Command: "/usr/bin/id" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/bin/cat" RunAsUsers: ALL RunAsGroups: ALL
[+] /bin/cat matches known privesc executable 'cat' !
[*] Command: "/tmp/asdf" RunAsUsers: ALL
[+] /tmp/asdf does not exist and /tmp is writable!
[*] Command: "/bin/echo \\\"AAAAAAAAAAAAAAAAAAAAAAAA this is a really long line that will totally linewrap\\\"" RunAsUsers: ALL
[+] /bin/echo matches known privesc executable 'echo' !
[*] Command: "/bin/echo \\\"AAAAAAAAAAAAAAAAAAAAAAAA this is another really long line that will totally linewrap\\\"" RunAsUsers: ALL
[+] /bin/echo matches known privesc executable 'echo' !

Sudo Commands
=============

  Command                                                                                             RunAsUsers  RunAsGroups  Password?  Privesc?
  -------                                                                                             ----------  -----------  ---------  --------
  /bin/cat                                                                                            ALL         ALL          true       true
  /bin/echo \"AAAAAAAAAAAAAAAAAAAAAAAA this is a really long line that will totally linewrap\"        ALL                      true       true
  /bin/echo \"AAAAAAAAAAAAAAAAAAAAAAAA this is another really long line that will totally linewrap\"  ALL                      true       true
  /tmp/asdf                                                                                           ALL                      true       true
  /usr/bin/id                                                                                         ALL         ALL          true       false

[+] Output stored in: /root/.msf4/loot/20180514142121_default_172.16.191.236_sudo.commands_096538.txt
[*] Post module execution completed
msf5 post(multi/recon/sudo_commands) > cat /root/.msf4/loot/20180514142121_default_172.16.191.236_sudo.commands_096538.txt
[*] exec: cat /root/.msf4/loot/20180514142121_default_172.16.191.236_sudo.commands_096538.txt

Command,RunAsUsers,RunAsGroups,Password?,Privesc?
"/bin/cat","ALL","ALL","true","true"
"/bin/echo \""AAAAAAAAAAAAAAAAAAAAAAAA this is a really long line that will totally linewrap\""","ALL","","true","true"
"/bin/echo \""AAAAAAAAAAAAAAAAAAAAAAAA this is another really long line that will totally linewrap\""","ALL","","true","true"
"/tmp/asdf","ALL","","true","true"
"/usr/bin/id","ALL","ALL","true","false"
msf5 post(multi/recon/sudo_commands) > set session 9
session => 9
msf5 post(multi/recon/sudo_commands) > set verbose false
verbose => false
msf5 post(multi/recon/sudo_commands) > run

[+] Found 2 sudo entries for current user
[+] sudo any command!

Sudo Commands
=============

  Command                                    RunAsUsers  RunAsGroups  Password?  Privesc?
  -------                                    ----------  -----------  ---------  --------
  /usr/lib/linuxmint/mintUpdate/checkAPT.py  root                     false      false
  ALL                                        ALL         ALL          true       true

[+] Output stored in: /root/.msf4/loot/20180514143453_default_172.16.191.225_sudo.commands_046411.txt
[*] Post module execution completed
msf5 post(multi/recon/sudo_commands) > set verbose true
verbose => true
rmsf5 post(multi/recon/sudo_commands) > run

[*] Executing: /usr/bin/sudo -l -l -n
[*] Output:
Matching Defaults entries for user on linux-mint-18-3:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User user may run the following commands on linux-mint-18-3:

Sudoers entry:
    RunAsUsers: ALL
    RunAsGroups: ALL
    Commands:
	ALL

Sudoers entry:
    RunAsUsers: root
    Options: !authenticate
    Commands:
	/usr/lib/linuxmint/mintUpdate/checkAPT.py

[+] Found 2 sudo entries for current user
[*] Command: "ALL" RunAsUsers: ALL RunAsGroups: ALL
[+] sudo any command!
[*] Command: "/usr/lib/linuxmint/mintUpdate/checkAPT.py" RunAsUsers: root without providing a password

Sudo Commands
=============

  Command                                    RunAsUsers  RunAsGroups  Password?  Privesc?
  -------                                    ----------  -----------  ---------  --------
  /usr/lib/linuxmint/mintUpdate/checkAPT.py  root                     false      false
  ALL                                        ALL         ALL          true       true

[+] Output stored in: /root/.msf4/loot/20180514143458_default_172.16.191.225_sudo.commands_523002.txt
[*] Post module execution completed
msf5 post(multi/recon/sudo_commands) > cat /root/.msf4/loot/20180514143458_default_172.16.191.225_sudo.commands_523002.txt
[*] exec: cat /root/.msf4/loot/20180514143458_default_172.16.191.225_sudo.commands_523002.txt

Command,RunAsUsers,RunAsGroups,Password?,Privesc?
"/usr/lib/linuxmint/mintUpdate/checkAPT.py","root","","false","false"
"ALL","ALL","ALL","true","true"
msf5 post(multi/recon/sudo_commands) > 

@bcoles
Copy link
Contributor Author

bcoles commented May 14, 2018

Notes

Some of the most awful spaghetti code I've ever written.

Spaghetti

@wvu
Copy link
Contributor

wvu commented May 15, 2018

🍝

@bcoles
Copy link
Contributor Author

bcoles commented May 15, 2018

Do not merge

This PR is a work-in-progress and request for comments.

In hindsight, it would have been easier to parse sudo -l than sudo -l -l.

I also need to fix support for older versions of sudo.

@wvu wvu added the blocked Blocked by one or more additional tasks label May 15, 2018
@bcoles
Copy link
Contributor Author

bcoles commented May 15, 2018

Updated to use sudo -l rather than sudo -l -l.

The code is cleaner and this should work on every version of sudo in the last 10 years.

Module is ready for testing.

@bcoles
Copy link
Contributor Author

bcoles commented May 15, 2018

Sample (verbose) output:

msf5 post(multi/recon/sudo_commands) > run

[*] Executing: /usr/bin/sudo -n -l
[*] Executing: echo password1 | /usr/bin/sudo -S -l
Matching Defaults entries for test on this host:
    requiretty, !visiblepw, env_reset, env_keep="COLORS DISPLAY HOSTNAME
    HISTSIZE INPUTRC KDEDIR LS_COLORS MAIL PS1 PS2 QTDIR USERNAME LANG
    LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES
    LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL
    LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"

User test may run the following commands on this host:
    (ALL) NOPASSWD: /bin/cat, (ALL) /bin/sh
    (ALL) NOPASSWD: /tmp/test, (ALL) /tmp/asdf
    (ALL : ALL) /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient,
    /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial,
    /sbin/iwconfig, /sbin/mii-tool
    (ALL : ALL) /bin/cp /tmp/source /tmp/destination, /tmp/echo sudo's output
    sucks for parsing, /bin/echo sudo's output sucks for parsing

[*] Command: "/bin/cat" RunAsUsers: ALL without providing a password
[+] /bin/cat matches known privesc executable 'cat' !
[*] Command: "/bin/sh" RunAsUsers: ALL without providing a password
[+] /bin/sh matches known privesc executable 'sh' !
[*] Command: "/tmp/test" RunAsUsers: ALL without providing a password
[+] /tmp/test does not exist and /tmp is writable!
[*] Command: "/tmp/asdf" RunAsUsers: ALL without providing a password
[+] /tmp/asdf does not exist and /tmp is writable!
[*] Command: "/sbin/route" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/sbin/ifconfig" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/bin/ping" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/sbin/dhclient" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/usr/bin/net" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/sbin/iptables" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/usr/bin/rfcomm" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/usr/bin/wvdial" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/sbin/iwconfig" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/sbin/mii-tool" RunAsUsers: ALL RunAsGroups: ALL
[*] Command: "/bin/cp /tmp/source /tmp/destination" RunAsUsers: ALL RunAsGroups: ALL
[+] /bin/cp matches known privesc executable 'cp' !
[*] Command: "/tmp/echo sudo's output sucks for parsing" RunAsUsers: ALL RunAsGroups: ALL
[+] /tmp/echo does not exist and /tmp is writable!
[*] Command: "/bin/echo sudo's output sucks for parsing" RunAsUsers: ALL RunAsGroups: ALL
[+] /bin/echo matches known privesc executable 'echo' !

Sudo Commands
=============

  Command                                    RunAsUsers  RunAsGroups  Password?  Privesc?
  -------                                    ----------  -----------  ---------  --------
  /bin/cat                                   ALL                                 True
  /bin/cp /tmp/source /tmp/destination       ALL         ALL          True       True
  /bin/echo sudo's output sucks for parsing  ALL         ALL          True       True
  /bin/ping                                  ALL         ALL          True       
  /bin/sh                                    ALL                                 True
  /sbin/dhclient                             ALL         ALL          True       
  /sbin/ifconfig                             ALL         ALL          True       
  /sbin/iptables                             ALL         ALL          True       
  /sbin/iwconfig                             ALL         ALL          True       
  /sbin/mii-tool                             ALL         ALL          True       
  /sbin/route                                ALL         ALL          True       
  /tmp/asdf                                  ALL                                 True
  /tmp/echo sudo's output sucks for parsing  ALL         ALL          True       True
  /tmp/test                                  ALL                                 True
  /usr/bin/net                               ALL         ALL          True       
  /usr/bin/rfcomm                            ALL         ALL          True       
  /usr/bin/wvdial                            ALL         ALL          True       

[+] Output stored in: /root/.msf4/loot/20180515144953_default_172.16.191.169_sudo.commands_477999.txt
[*] Post module execution completed

@wvu wvu self-assigned this May 16, 2018
@wvu
Copy link
Contributor

wvu commented May 16, 2018

Very nice touch with the privesc suggestion.

@bcoles
Copy link
Contributor Author

bcoles commented May 16, 2018

The privesc suggestion output was the sole motivation to write this module.

The module lives in post/multi/recon, rather than post/multi/gather, and was designed to compliment the local exploit suggester for privesc purposes.

Unfortunately autopwn functionality was a little too complex for this module; in particular due to the potential need to move/overwrite/modify existing binaries. I may revisit this at a later date. sudo entries which permit executing ALL as ALL (or root) would be a quick win, especially for entries with a NOPASSWD directive. Similarly, instances where the specified executable is missing, and the directory writable, would also be a good candidate for autopwn.

For these reasons, an autopwn variant, which makes use of only the most reliable privesc vectors, should live in a separate exploits/multi/local module, which may or may not warrant abstracting my awful sudo parsing spaghetti code to a msf post lib.

The main hurdle was parsing the sudo output. I've tested on a bunch of different platforms (Linux/BSD/Solaris/OSX Lion) of various ages and various versions of sudo, with fairly nightmarishly-formatted sudo entries, with success, but I wouldn't be surprised if there's still some bugs lurking in the parsing.

Submitted PR for testing.

Changes to the privesc checks (in particular the list of EoP bins) and output can be easily made later.

@bcoles
Copy link
Contributor Author

bcoles commented May 18, 2018

Removing the delayed tag. I'll write the documentation once the module is tested and verified working by a third party.

@bcoles bcoles removed the blocked Blocked by one or more additional tasks label May 18, 2018
@wvu
Copy link
Contributor

wvu commented Jun 13, 2018

I uncommented a bunch of stuff in my sudoers from the CentOS VM for #10059.

msf5 post(multi/recon/sudo_commands) > run

[*] Executing: /usr/bin/sudo -n -l
Matching Defaults entries for bcoles on localhost:
    !visiblepw, always_set_home, match_group_by_gid, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin

User bcoles may run the following commands on localhost:
    (ALL) ALL
    (ALL) NOPASSWD: ALL
    (root) /sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom
    (root) /sbin/shutdown -h now

[*] Command: "ALL" RunAsUsers: ALL
[+] sudo any command!
[*] Command: "ALL" RunAsUsers: ALL without providing a password
[+] sudo any command!
[*] Command: "/sbin/mount /mnt/cdrom" RunAsUsers: root
[*] Command: "/sbin/umount /mnt/cdrom" RunAsUsers: root
[*] Command: "/sbin/shutdown -h now" RunAsUsers: root

Sudo Commands
=============

  Command                  RunAsUsers  RunAsGroups  Password?  Privesc?
  -------                  ----------  -----------  ---------  --------
  /sbin/mount /mnt/cdrom   root                     True
  /sbin/shutdown -h now    root                     True
  /sbin/umount /mnt/cdrom  root                     True
  ALL                      ALL                      True       True
  ALL                      ALL                                 True

[+] Output stored in: /Users/wvu/.msf4/loot/20180613134731_default_192.168.56.101_sudo.commands_305964.txt
[*] Post module execution completed
msf5 post(multi/recon/sudo_commands) > cat /Users/wvu/.msf4/loot/20180613134731_default_192.168.56.101_sudo.commands_305964.txt
[*] exec: cat /Users/wvu/.msf4/loot/20180613134731_default_192.168.56.101_sudo.commands_305964.txt

Command,RunAsUsers,RunAsGroups,Password?,Privesc?
"/sbin/mount /mnt/cdrom","root","","True",""
"/sbin/shutdown -h now","root","","True",""
"/sbin/umount /mnt/cdrom","root","","True",""
"ALL","ALL","","True","True"
"ALL","ALL","","","True"
msf5 post(multi/recon/sudo_commands) >

Works for me.

@bcoles bcoles added docs and removed needs-docs labels Jun 14, 2018
@bcoles
Copy link
Contributor Author

bcoles commented Jun 14, 2018

@wvu-r7 Cool. I've added docs.

@wvu
Copy link
Contributor

wvu commented Jun 14, 2018

I'll give this another test and a read-over of the docs, then I'll get it landed. This is a really strong contribution!

@wvu wvu merged commit aef74bf into rapid7:master Jun 14, 2018
wvu added a commit that referenced this pull request Jun 14, 2018
@wvu
Copy link
Contributor

wvu commented Jun 14, 2018

Release Notes

This adds the post/multi/recon/sudo_commands module to enumerate a user's sudo capabilities for post-exploitation and privilege escalation purposes.

@bcoles bcoles deleted the sudo_commands branch June 14, 2018 23:59
@tdoan-r7 tdoan-r7 added the rn-enhancement release notes enhancement label Jul 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs module rn-enhancement release notes enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants