前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【愚公系列】2023年05月 攻防世界-MOBILE(easy-so)

【愚公系列】2023年05月 攻防世界-MOBILE(easy-so)

作者头像
愚公搬代码
发布2023-05-24 10:10:53
2660
发布2023-05-24 10:10:53
举报
文章被收录于专栏:历史专栏历史专栏

前言

下面介绍两个反编译工具

  • jadx是一个用于反编译Android APK文件的开源工具,静态反编译,查找索引功能强大
  • jeb和IDA很像,属于动态调试,可以看java汇编也可以生成伪代码,还可以动态attach到目标调试

对于so文件的逆向工具选择

  • IDA逆向工具是一款反汇编器,被广泛应用于软件逆向工程领域,能够反汇编各种不同平台的二进制程序代码,并还原成可读的汇编代码。

Objection是一款移动设备运行时漏洞利用工具,该工具由Frida驱动,可以帮助研究人员访问移动端应用程序,并在无需越狱或root操作的情况下对移动端应用程序的安全进行评估检查。

安装命令

代码语言:javascript
复制
pip3 install objection 

frida是一款便携的、自由的、支持全平台的hook框架,可以通过编写JavaScript、Python代码来和frida_server端进行交互

frida的安装可以参考:https://www.jianshu.com/p/60cfd3f6afde

一、easy-so

1.题目

在这里插入图片描述
在这里插入图片描述

2.答题

2.1 运行app

点击check提示

在这里插入图片描述
在这里插入图片描述

2.2 jadx反编译apk文件

搜索验证失败字符串

在这里插入图片描述
在这里插入图片描述

找到源码

在这里插入图片描述
在这里插入图片描述

发现核查字符串函数:CheckString

2.3 IDA修改apk逻辑实现破解

上IDA,搜索刚才的方法名check,只有一个结果,双击跳过去,F5转伪代码,大概看一下,就是TestDec输出的字符串和f72c5a36569418a20907b55be5bf95ad进行对比,如果相等则返回1,也就是验证通过。

代码语言:javascript
复制
_BOOL8 __fastcall Java_com_testjava_jack_pingan2_cyberpeace_CheckString(__int64 a1, __int64 a2, __int64 a3)
{
  const char *v3; // r14
  size_t v4; // rax
  int v5; // er15
  unsigned __int64 v6; // r12
  char *v7; // rax
  char *v8; // r13
  bool v9; // cc
  size_t v10; // r12
  size_t v11; // rbx
  char v12; // al
  char v13; // al
  size_t v14; // rbx
  char v15; // al

  v3 = (const char *)(*(__int64 (__fastcall **)(__int64, __int64, _QWORD))(*(_QWORD *)a1 + 1352LL))(a1, a3, 0LL);
  v4 = strlen(v3);
  v5 = v4;
  v6 = (__int64)((v4 << 32) + 0x100000000LL) >> 32;
  v7 = (char *)malloc(v6);
  v8 = v7;
  v9 = v6 <= v5;
  v10 = v6 - v5;
  if ( v9 )
    v10 = 0LL;
  memset(&v7[v5], 0, v10);
  memcpy(v8, v3, v5);
  if ( strlen(v8) >= 2 )
  {
    v11 = 0LL;
    do
    {
      v12 = v8[v11];
      v8[v11] = v8[v11 + 16];
      v8[v11++ + 16] = v12;
    }
    while ( strlen(v8) >> 1 > v11 );
  }
  v13 = *v8;
  if ( *v8 )
  {
    *v8 = v8[1];
    v8[1] = v13;
    if ( strlen(v8) >= 3 )
    {
      v14 = 2LL;
      do
      {
        v15 = v8[v14];
        v8[v14] = v8[v14 + 1];
        v8[v14 + 1] = v15;
        v14 += 2LL;
      }
      while ( strlen(v8) > v14 );
    }
  }
  return strcmp(v8, "f72c5a36569418a20907b55be5bf95ad") == 0;
}
在这里插入图片描述
在这里插入图片描述

const char * v3是传入的字符串,接下来逐个分析代码逻辑: 第一步:两两交换

代码语言:javascript
复制
v4 = strlen(v3);//取变量v4=v3的字符串长度,假设v3="abcd",v4=4
v5 = v4;
v6 = (__int64)((v4 << 32) + 0x100000000LL) >> 32;
v7 = (char *)malloc(v6);//为字符指针v7请求一块长度为v6的内存空间
v8 = v7;
v9 = v6 <= v5;
v10 = v6 - v5;
if ( v9 )
  v10 = 0LL;
memset(&v7[v5], 0, v10);//将v7扩增一倍并后面扩增的部分初始化为0,此行代码结束,v7=----0000
memcpy(v8, v3, v5);//将v3的内容复制到v8中
if ( strlen(v8) >= 2 )//若v8的长度大于等于2则执行花括号内的内容
{
  v11 = 0LL;//初始化v11=0
  do//执行循环
  {
    v12 = v8[v11];//从第0个开始读取v8的每个字符
    v8[v11] = v8[v11 + 16];//逐个将v8的第v11个字符与第v11+16个字符交换位置
    v8[v11++ + 16] = v12;//v6自增1
  }
  while ( strlen(v8) >> 1 > v11 );
}

假设传入字符串为abcd,则上述代码执行完之后的v8为cdab 继续分析接下来的代码: 第二步:头尾互换

代码语言:javascript
复制
v13 = *v8;
if ( *v8 )
{
  *v8 = v8[1];
  v8[1] = v13;
  if ( strlen(v8) >= 3 )
  {
    v14 = 2LL;
    do
    {
      v15 = v8[v14];
      v8[v14] = v8[v14 + 1];
      v8[v14 + 1] = v15;
      v14 += 2LL;
    }
    while ( strlen(v8) > v14 );
  }
}

根据上述我们直接手动得到flag的code:

1.将f7 2c 5a 36 56 94 18 a2 09 07 b5 5b e5 bf 95 ad两两交换得到7f c2 a5 63 65 49 81 2a 90 70 5b b5 5e fb 59 da

2.将7fc2a5636549812a 90705bb55efb59da从中间砍断,头尾互换得到90705bb55efb59da 7fc2a5636549812a

得到flag:flag{90705bb55efb59da7fc2a5636549812a}

2.4 脚本解题和Java源码

python脚本

代码语言:javascript
复制
data = list('f72c5a36569418a20907b55be5bf95ad') //把字符串传入,并转为列表
for i in range(len(data)//2):  //第一个循环体
    a = data[i]
    data[i] = data[i+16]
    data[i+16] = a
for i in range(0,len(data),2):  //第二个循环体
    a2 = data[i]
    data[i]=data[i+1]
    data[i+1]=a2
key=''.join(data) //拼接字符串
print("flag{"+key+"}")  //把题目中的flag{}和最终字符串拼接并输出

java源码解析

代码语言:javascript
复制
@Test
public void demo2() {
    String str = "f72c5a36569418a20907b55be5bf95ad";
    char[] data = str.toCharArray();
 
    //伪代码中的第二次循环
    int index2 = 0;
    int result;
    int v9;
    do {
        char v8 = data[index2 + 2];
        data[index2 + 2] = data[index2 + 3];
        data[index2 + 3] = v8;
        result = data.length;
        v9 = index2 + 4;
        index2 += 2;
    }
    while (v9 < result);
 
 
    //循环后进行的简单的互换
    result = data[0];
    data[0] = data[1];
    data[1] = (char) result;
    result = data.length;
 
 
    //伪代码中第一次循环
    int index = 0;
    do
    {
        char v4 = data[index];
        data[index] = data[index + 16];
        data[index+16] = v4;
        ++index;
    }
    while ( index < data.length >> 1 );
 
    System.out.println(data);
    //输出结果 -> 90705bb55efb59da7fc2a5636549812a
}

总结

  • APK
  • JADX
  • IDA
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-05-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一、easy-so
    • 1.题目
      • 2.答题
        • 2.1 运行app
        • 2.2 jadx反编译apk文件
        • 2.3 IDA修改apk逻辑实现破解
        • 2.4 脚本解题和Java源码
    • 总结
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档