老婆大人上班要打卡,所以我这个JAVA小白只能对某水印相机下手了!!

查看 189|回复 14
作者:闷骚小贱男   
前排提醒
2022-12-12 :最近有人说APP更新方法不能用了,下载了一个2.9.325.8的版本看了下,AES的decrypt都一模一样...直接hook替换解密后明文的相关内容即可,理论上通杀所有版本
千万不要看最后的打卡图中的速度,不然...
本帖仅是记录分析过程,如有违规请告知或..
考勤打卡水印是不支持自定义修改的
本贴的由来:
前段时间有人找到我,说他这有一款打卡的APP(好像家里那位也用这个APP),还有一个某某助手竟然能虚拟定位➕模拟拍照,我当时在想,这么神奇的吗??果然,我一个Android小白不懂的还是有很多。
接下来的时间就在研究这个APP,他说助手不好用,照片经常被自动裁剪变形【其实是因为想要替换的图片和拍到的图片宽度/高度不同导致裁剪,修改图片宽度高度即可。
这篇帖子不讲这个,讲一下另类的改时间➕定位➕经纬度➕速度➕天气。
帖中用到的工具
1.抓包工具(fd/HttpCanary/或者别的均可),本帖用的是fd
2.某遥模拟器(其他模拟器均可),手机也可以
3.Androidkiller(查看日志用),如果有别的工具,也都可以
4.jadx(mt/np管理器也行),反编译神器,自从有了他,mt我都很少用了
我是这样操作的
查看APP是否加固
用MT查看APP的安装包是否加固,发现没有加固。


1.0没有加固.png (35.83 KB, 下载次数: 1)
下载附件
2021-1-18 23:00 上传

连接Androidkiller,查看指定APP的日志
只有找到一个能看得懂的,它这里输出的内容,就是我这的位置,所以应该是输出定位。
Tag: AT_
Message: RESPONSE = {"code":200,"msg":"success","toast_msg":"","data":{"formatted_address":"XX省XX市XX县XXXXXX","specialTip":"","locationDetail":{"country":"中国","province":"XX省","city":"XX市","district":"XX县","township":"XX","poi":"XXXX"}}}


1.1ak日志.png (20.66 KB, 下载次数: 0)
下载附件
2021-1-18 23:03 上传

查看fd传送数据是否加密


1.2FD抓.png (104.69 KB, 下载次数: 1)
下载附件
2021-1-19 00:16 上传

emmmmmmmmm,明眼人都能看得出来数据是加密的(Ps:我认为,看不懂的这个字母数字串就是aes/des加密)
fd中有意思的一个点
在分析的过程中,fd一直在跑数据,而且还是同一个地址next/fmtaddress,如下图:


1.3FD.png (32.81 KB, 下载次数: 0)
下载附件
2021-1-18 23:14 上传

看不懂英文没关系,不过address应该能懂吧?地址……APP一直在定位……
但是数据是加密的,接下来我们尝试解密
jadx上场
搜关键词
根据刚才Androidkiller的日志,在jadx中搜索关键词“RESPONSE =”,得到如下结果:


1.4jadx搜.png (83.57 KB, 下载次数: 0)
下载附件
2021-1-18 23:19 上传

我们双击,看下详细的内容:
final class c implements Converter {
    /* renamed from: a  reason: collision with root package name */
    private final TypeAdapter f8608a;
    private String b;
    private boolean c;
    c(TypeAdapter typeAdapter, boolean z) {
        this.f8608a = typeAdapter;
        this.c = z;
    }
    /* renamed from: a */
    public T convert(ab abVar) throws IOException {
        try {
            String string = abVar.string();
            try {
                JSONObject jSONObject = new JSONObject(string);
                if (this.c) {
                    this.b = AESUtil.decrypt(jSONObject.optString(DbParams.KEY_CHANNEL_RESULT));/* ②decrypt多么熟悉的一个单词!解密 */
                } else {
                    this.b = string;
                }
                Log.d("AT_", "RESPONSE = " + this.b);/* ①看到log输出,然后往前推 */
            } catch (Exception e) {
                this.b = "";
                e.printStackTrace();
            }
            return this.f8608a.fromJson(this.b);
        } finally {
            abVar.close();
        }
    }
}
看decrypt函数
现在只要一看到decrypt就有点小激动。
我们右键decrypt,然后“跳到声明”
    private static final String ENCRYPTION_IV = "xhey-cc4275fd-43";
    private static final String ENCRYPTION_KEY = "xhey-cc4275fd-43";
    public static String encrypt(String str) {
        if (TextUtils.isEmpty(str)) {
            return str;
        }
        try {
            Cipher instance = Cipher.getInstance("AES/CBC/PKCS5Padding");
            instance.init(1, makeKey(), makeIv());
            Log.e("time", "==" + Base64.encode(instance.doFinal(str.getBytes()), 0));
            return new String(Base64.encode(instance.doFinal(str.getBytes()), 2)).trim();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static String decrypt(String str) {/* ① 跳到声明  跳到这里来的,分析下函数?*/
        if (TextUtils.isEmpty(str)) {
            return str;/*  如果密文参数str为空,解密结果是str */
        }
        try {
            Cipher instance = Cipher.getInstance("AES/CBC/PKCS5Padding");/* ② 解密模式 */
            instance.init(2, makeKey(), makeIv());/* ③ make?制造key和iv?我们看下面 */
            return new String(instance.doFinal(Base64.decode(str, 2)));/* 返回解密的结果 */
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    static AlgorithmParameterSpec makeIv() {
        try {
            return new IvParameterSpec("xhey-cc4275fd-43".getBytes("utf-8"));/* ④ ??直接就把iv给我们了?? */
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }
    static SecretKeySpec makeKey() {
        try {
            return new SecretKeySpec("xhey-cc4275fd-43".getBytes("utf-8"), "AES");/* ⑤ ??直接就把key给我们了??iv和key竟然一样? 我们用key/iv/fd抓包的密文,解密试下。*/
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }
尝试解密+加密
我们用在线解密尝试解密。竟然解密成功了。的确如我猜想,next/fmtaddress返回的是当前地址的定位信息。


1.5解密.png (55.33 KB, 下载次数: 0)
下载附件
2021-1-18 23:35 上传

那么我们把定位信息修改之后,再加密,然后用自动响应返回……來來來
然后,我们的定位就变成了真的XX......來來來


1.6加密后自动响应.png (20.21 KB, 下载次数: 1)
下载附件
2021-1-19 00:16 上传

关于时间的探索
尝试修改本机时间
先关闭APP,关闭自动时间,随意修改手机时间后,打开APP,竟然.........


1.7app修改时间.png (33.84 KB, 下载次数: 0)
下载附件
2021-1-19 00:16 上传

竟然没用??看来改本地时间没用,APP可能会从某个地方获取正确的时间
继续分析
看来,这个时间应该也是有相关的请求来获取。
那么我们从fd中一个一个解密过去,最后发现了一个接口返回的密文解密后,有时间戳存在。猜想:就是这个接口是APP获取时间


1.8时间戳.png (31.92 KB, 下载次数: 1)
下载附件
2021-1-18 23:48 上传

加密然后....
和刚才的定位信息一样尝试加密,然后自动响应,你懂的。
加密的结果如下:
bncdzrxa+Dq49i7NxArtSeZtLpZ7cxsOynuCD5Co47mgXj5V8wuwHKrBZk6XMBm1gAml1mawaGdjlxRCpTLsBHFCKqMU7V/qiHgFynirxtBfVkTChq/1f4NV7dpmoomY/B9OaInmjqBsj5/d+b72WA==
然后体现在APP中是这样的:


1.9.png (45.76 KB, 下载次数: 0)
下载附件
2021-1-19 00:39 上传

关于经纬度的修改之从打开日志入手
jadx上场
搜关键词
搜索"经纬度",发现w.a ,总感觉是log输出日志用的
[为什么要搜经纬度?因为考勤打卡编辑的时候第一个是"经纬度"呀]
w.a("loc", "==经纬度获取列表==");
跳转w.a并打开日志输出
发现类com.xhey.xcamera.util.w中的f7724a = false;
    public static void a(String str, String str2) {
        String str3;
        f7724a = true;/* 咱们在MT中把a(也就是jadx中的f7724a)的值设为true */
        if (f7724a) {
                /* 一系列操作,包括Log.e(str, format); 证明他可能真的是输出日志*/
        }
    }
}
连Androidkiller查看日志
看到有相关"获取定位信息,更新本地保存的经纬度"的文字


1.11.png (93.31 KB, 下载次数: 1)
下载附件
2021-1-21 20:42 上传

搜索"获取定位"
jadx搜索"获取定位",发现com.xhey.xcamera.data.b.a类中的a(BDLocation bDLocation, boolean z)
    public static void a(BDLocation bDLocation, boolean z) {
                /* 这里贴出的代码为部分代码,不完整 */
            double latitude = bDLocation.getLatitude();
            double longitude = bDLocation.getLongitude();
            String cityCode = bDLocation.getCityCode();
            String str = bDLocation.getAddress().address;
            if (z) {
                w.a("loc", "==获取定位信息,更新本地保存的经纬度==");
            }
    }
发现getLatitude和getLongitude函数...这个就是get经纬度的2个函数了.
mt管理器上场
第一种:可以直接搜索getLatitude,但是有很多getLatitude函数,我们找BDLocation类中的.因为日志输出中多次提到BDLocation(别的高德的类就不用看了)
第二种:也可以搜com.xhey.xcamera.data.b.a    a函数中长按getLatitude和getLongitude分别设置经纬度
[PS:我这里贴出北京东经116°20′、北纬39°56′的代码,大家可以举一反三,116°20′就是116.20]
.method public getLongitude()D
    .registers 3
    iget-wide v0, p0, Lcom/baidu/location/BDLocation;->d:D #下面设置了v0的数,那么这句话就没意义了
    const-wide v0, 0x405d0ccccccccccdL  # 116.2
    return-wide v0
.end method
.method public getLatitude()D
    .registers 3
    iget-wide v0, p0, Lcom/baidu/location/BDLocation;->c:D #下面设置了v0的数,那么这句话就没意义了
    const-wide v0, 0x4043c7ae147ae148L  # 39.56
    return-wide v0
.end method
展示下小结果
鲁伪造京的经纬:


1.12北京经纬度.png (28.5 KB, 下载次数: 0)
下载附件
2021-1-21 21:11 上传

总结下经纬度
其实就是getLatitude和getLongitude函数,直接固定结果即可
小弟猜测经纬度是网络定位,因为APP请求了loc.map.baidu.com/sdk.php地址,返回了RSA密文
小弟也没咋研究过RSA加密呀..
PublicKey generatePublic = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.decode("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiP7BS5IjEOzrKGR9/Ww9oSDhdX1ir26VOsYjT1T6tk2XumRpkHRwZbrucDcNnvSB4QsqiEJnvTSRi7YMbh2H9sLMkcvHlMV5jAErNvnuskWfcvf7T2mq7EUZI/Hf4oVZhHV0hQJRFVdTcjWI6q2uaaKM3VMh+roDesiE7CR2biQIDAQAB".getBytes(), 0)));
Signature instance = Signature.getInstance("SHA1WithRSA");
instance.initVerify(generatePublic);
成功打卡截图


1.14.png (1 MB, 下载次数: 1)
下载附件
2021-1-22 15:53 上传

打卡成功,发送到工作群,然后睡觉。。。。
不对不对,还要总结下。
最后总结下
Smali中D类型为双精小数const-wide v0,0x4043c7ae147ae148L  # 39.56
小白只能从看日志开始搞起.
搞完之后,发现其实可以直接jadx中搜"定位",稍微快那么几步,也不用打开日志
.....好吧,也就是一堆工具的一起应用。。也没啥总结的
应该怎么预防?作为小白,我认为:
1.首先APP加固...这一点至少我看到加固的是暂时是不会的。。不过要是单独看函数的话,还是可以脱壳看dex的,也不用修复。。
2.key和iv尽量不要一样。
3.key和iv写成变量,也可动态key,不要直接把key和iv固定成常量。
4.增加对手机代{过}{滤}理的检测。
5.增加对模拟器的检测。
...嗯,暂时就想到这么多。。。发帖,睡觉。不然头发真的会越来越少
最后再聊一块钱的
我发现有好多同学说PS或一键之类的。
我提取了APP中的字体文件,尝试了做改时间的APP。。效果好像一般般。
下面是图:(大块白色的是APP生成的)


Screenshot_2021_0123_221712.png (734.37 KB, 下载次数: 1)
下载附件
2021-1-23 22:26 上传

经纬度, 下载次数

CrazyNut   

帖子是好帖 我选择直接PS
鬆Godlike   

you女朋友,不点赞
siye52888   

打开**水印相机,水印-团队-添加水印模板-把地址和时间取消,然后自定义文字里面标题写地址,完成添加就可以自己随便打地址时间之类的了。改其他也一样。
fuzhend   

直接从Android包中把字体拿出来   写个程序一键处理图片
じ☆ve不哭   


闷骚小贱男 发表于 2021-5-25 21:58
从JAVA代码入手?字体文件反编译都能找到

能不能跟其他水印软件整合,有一款水印软件不是能修改内容吗,能不能把今日水印的水印放到那个软件里
一瓶啤酒   


taohuawu1998 发表于 2021-1-27 16:59
请问楼主最后一步模拟拍照是只用了西瓜助手吗?
我学到最后一步西瓜助手疯狂闪退

模拟拍照的话 我暂时只知道西瓜助手  应该还有别的助手可以的
关于你问的只用了西瓜助手...我只能说是?
PS:模拟拍照是为了替换你当前拍到的照片
闷骚小贱男
OP
  

说了一大堆,就是没有软件有个屁用麽
samupday   


AlanTR 发表于 2021-1-21 12:48
大佬nb
(然而没看懂 = =
mt是那个收费的安卓文件管理器吗?

mt是mt管理器...但是免费的功能也挺强大的
闷骚小贱男
OP
  

就像鼓励下你们这些有毅力的同学
您需要登录后才可以回帖 登录 | 立即注册

返回顶部