首页
社区
课程
招聘
[原创]一次诈骗APP的逆向分析
发表于: 2024-7-18 16:21 23568

[原创]一次诈骗APP的逆向分析

2024-7-18 16:21
23568

起早了,也是逆天,听说朋友被luo聊诈骗了,还带有一个APP,这不拿来看一手o(´^`)o,绝对不是我想看不该看的嗷。

最开始朋友给我的时候,让我帮他找个ip,我还以为是个取证题目,最后发现,找到的ip和域名都是存活的,嘶,那就有意思啦。
拿到手发现就6M多,我想,这怎么可能能luo聊,和朋友沟通发现,这只是在luo聊软件中推广的软件,封面做得就很low,甚至连APP icon都不愿意放一个,名称叫《羞密基地》(✪ω✪)
图片描述
怎么越看越像一个CTF题目呢,好劣质的感觉hhh。
最开始没仔细看反编译结果前我还以为真能进去呢,还要了当时被诈骗的房间号,结果发现一直卡在那,感觉不对劲,又回去仔细看了看。

核心逻辑全在MainActivity里面hhhh,一点多的都没有(除了一些工具类)

要了一堆基本用不到的权限,符合我对诈骗APP的固有印象。
然后事情就开始离谱了起来。
图片描述
这么多参数,看不得看死o(╥﹏╥)o,直接抓包吧,本来我是觉得没什么的,一抓包给我吓了一跳。
这里通过静态分析可以看出,走的全是http,甚至不用配置证书。
图片描述
这里两个外网服务器,下载文件下来之后,发现就是简单的base64,没有额外加密,就能拿到ip和端口。扫描一下ip,从服务器上没看出什么有用信息,就尝试动态分析呗。
最开始还是一贯性的想上frida,但是抓包明显更简单,那就fiddler吧。
图片描述
基本逻辑和分析得一样,通过两个txt文件拿到真实服务器的地址,其中108是用来记录post参数的,之前图中的device、phone number等数据。
149这个ip是用来上传手机中的照片的,会导致敏感信息的泄露。最开始我是忽略了这部分的,post参数确实太显眼了一点。
图片描述
从fiddler中dump出数据,上010恢复成jpg格式我才发现事情的不对劲。虽然这是专门做逆向root过的机器,但是上面还是有一些照片!!!∑(゚Д゚ノ)ノ,唉,所以说,淹死的都是会水的。

知道了整体逻辑,接下来就是逆他自己的加密算法了。
每个post的参数都经过了AESUtils.encryptBase64()加密了一次,对称密码,直接看看他代码怎么写的。
图片描述
顾名思义,AES、Base64,真就只有这两个算法。
唯一上的保护就是密钥了。
图片描述
图片描述
虽然这保护和没保护也没什么区别就是了。
那就直接找密钥呗,没什么说的

python写出解密脚本

找到加密逻辑伪造请求就简单了,直接post就行了,反正是诈骗APP,想怎么来就怎么来。
最后贴上附件,大家避个雷吧(^▽^)。
血的教训,想看这个APP的话,记得把手机照片删完(•́へ•́╬)
https://xzc207.site/eapp_1014_1719048034

if (ActivityCompat.checkSelfPermission(this, "android.permission.SEND_SMS") != 0 && ActivityCompat.checkSelfPermission(this, "android.permission.READ_SMS") != 0 && ActivityCompat.checkSelfPermission(this, "android.permission.READ_PHONE_NUMBERS") != 0 && ActivityCompat.checkSelfPermission(this, "android.permission.READ_PHONE_STATE") != 0) {
            showUserInfo("App所需基本权限, \n请允许,未允许将无法提供服务!");
            return;
        }
if (ActivityCompat.checkSelfPermission(this, "android.permission.SEND_SMS") != 0 && ActivityCompat.checkSelfPermission(this, "android.permission.READ_SMS") != 0 && ActivityCompat.checkSelfPermission(this, "android.permission.READ_PHONE_NUMBERS") != 0 && ActivityCompat.checkSelfPermission(this, "android.permission.READ_PHONE_STATE") != 0) {
            showUserInfo("App所需基本权限, \n请允许,未允许将无法提供服务!");
            return;
        }
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.lang.String;
public class Main {
    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        for (int i = begin; i < begin + count; i++) {
            bs[i - begin] = src[i];
        }
        return bs;
    }
    public static byte[] GetKeySeed(String seed, int keylen) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA1");
        MessageDigest rd = MessageDigest.getInstance("SHA1");
        byte[] keyst = md.digest(seed.getBytes(StandardCharsets.UTF_8));
        return subBytes(rd.digest(keyst), 0, keylen);
    }
    public static void  main(String[] args) throws IOException, NoSuchAlgorithmException {
        String KeyPrivate = "kGfIzsWnQBvW";
        String SaltPrivate = "3s1Zj1hvDi90";
        byte[] arr =new byte[16];
        arr=GetKeySeed(KeyPrivate + SaltPrivate, 16);
        for (int i = 0; i < arr.length; i++) {
             System.out.printf("0x%02X,", arr[i] & 0xFF);
        }
        System.out.println("\n"+arr.length);
    }
}
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.lang.String;
public class Main {
    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        for (int i = begin; i < begin + count; i++) {
            bs[i - begin] = src[i];
        }
        return bs;
    }
    public static byte[] GetKeySeed(String seed, int keylen) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA1");
        MessageDigest rd = MessageDigest.getInstance("SHA1");
        byte[] keyst = md.digest(seed.getBytes(StandardCharsets.UTF_8));
        return subBytes(rd.digest(keyst), 0, keylen);
    }
    public static void  main(String[] args) throws IOException, NoSuchAlgorithmException {
        String KeyPrivate = "kGfIzsWnQBvW";
        String SaltPrivate = "3s1Zj1hvDi90";

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2024-7-18 16:26 被touful编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (5)
雪    币: 535
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
这个朋友是谁啊
2024-7-24 07:52
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
有空出个后台的呗
2024-7-29 22:19
0
雪    币: 355
活跃值: (336)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
差一点自来也 有空出个后台的呗
什么叫出后台?没懂你意思呢
2024-7-31 09:02
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
touful 什么叫出后台?没懂你意思呢
连接到上传后台的服务器,就是接受数据的
2024-8-3 15:45
0
雪    币: 25
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
最近被诈骗app骗了钱,好烦,真想逆向回去,又没那本事,我是搞嵌入式的,对逆向完全不懂
2024-9-24 09:00
0
游客
登录 | 注册 方可回帖
返回
//