Android逆向二—CTF逆向实战(四个方向)

Something u have to know:

实践是检验真理的唯一标准,本次逆向学习使用的AppDemo为Frida官网提供的ctf的示例。

本次实战通过静态插桩篡改法、动态插桩调用法、动态插桩篡改法、汇编代码分析法四个方向获取flag

 

目录

Something u have to know:

0x01 环境准备:

0x02 代码分析:

0x03 静态插桩篡改法(AndroidKiller):

0x04 动态插桩调用/篡改法(Frida):

方法一:不篡改程序,调用calc()方法拼接得到flag

方法二:篡改cnt的值为1000 获得flag

0x05 汇编代码分析(Radare2):


0x01 环境准备:

该部分内容较多,可以先跳过,需要了回来安装

ID工具名链接说明
1AppDemohttps://github.com/ctfs/write-ups-2015/blob/master/seccon-quals-ctf-2015/binary/reverse-engineering-android-apk-1/rps.apk下载失败翻墙下载
2AndroidKillerhttp://www.downza.cn/soft/275382.html 
3J2S2Jhttps://www.onlinedown.net/download/1209079?module=download 
4

Frida

https://github.com/frida/frida/releases

安装对应版本

5Radare2

$ git clone https://github.com/radareorg/radare2.git

$ cd radare2

$ ./sys/user.sh

下载失败翻墙下载

1、AppDemo下载安装

(略)

2、AndroidKiller下载

(略)

若jd-gui不兼容当前java版本,可替换为插件包中原jd-gui

3、J2S2J下载

(略)

转换过程中某dex/jar文件异常,删掉该文件重新转换即可

4、Frida安装

       4.1 u need know:

Frida是一款以Python作为载体,Javascript作为在Android中执行代码的Hook框架。

Frida自带的Messages机制与进程交互,以下为Frida的基础模板:

import frida, sys
 
//hook代码,采用javascript编写
jscode = """
//javascript代码!!!!!!!!!
"""
 
//自定义回调函数
def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)
 
//获取设备并得到应用包对应进程号pid的session实例化对象
process = frida.get_remote_device().attach('应用完整包名')
//创建jscode的Script类
script = process.create_script(jscode)
//将自定义回调函数带入mseesage
script.on('message', on_message)
//启动javascript脚本
script.load()
sys.stdin.read()

Frida分为frida和finrda-sever两部分,frida-server安装在移动端用于监听来自PC端frida的Messages用来热更

       4.2 PC端安装frida需要具备Python开发环境(没有的自己下懒死了),命令行输入:

    pip install frida-tools

       4.3 移动端安装frida-server需要根据架构信息安装对应版本,使用adb工具查看(此处演示虚模拟器,真机不会的百度,略略略)

模拟器安装目录下自带adb工具,cmd命令行启动

adb shell

getprop ro.product.cpu.abi

看到下面打印的了么,框架为x86,下载对应版本:https://github.com/frida/frida/releases

下载下来后放入移动端,启动监听和frida-server:

adb push xxxxx /data/local/tmp

adb forward tcp:27042 tcp:27042

adb forward tcp:27043 tcp:27043

adb shell

cd /data/local/tmp

chmod 755 xxx

./xxx

       4.4 以上安装完毕后测试(第一条打印为server服务未启动或其他原因,第二条打印则为成功)

frida-ps -R

0x02 代码分析:

1、APK反编译

代码分析时可以用自带的J2S,也可以使用J2S2J工具,如下图所示对比下来J2S2J工具转换代码更为清晰准确。

2、代码分析

入口MainActivity.smali分析:

//声明了button控件及对应的监听器
protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      this.P = (Button) findViewById(R.id.button);
      this.S = (Button) findViewById(R.id.button3);
      this.r = (Button) findViewById(R.id.buttonR);
      this.P.setOnClickListener(this);
      this.r.setOnClickListener(this);
      this.S.setOnClickListener(this);
      this.flag = 0;
  }

//那么就看一下button的点击事件

public void onClick(View v) {
      if (this.flag != 1) {
          this.flag = 1;
          ((TextView) findViewById(R.id.textView3)).setText("");
          TextView tv = (TextView) findViewById(R.id.textView);
          TextView tv2 = (TextView) findViewById(R.id.textView2);
          this.m = 0;
          this.n = new Random().nextInt(3);  //随机数0,1,2
          tv2.setText(new String[]{"CPU: Paper", "CPU: Rock", "CPU: Scissors"}[this.n]); 
          if (v == this.P) {
              tv.setText("YOU: Paper");
              this.m = 0;
          }
          if (v == this.r) {
              tv.setText("YOU: Rock");
              this.m = 1;
          }
          if (v == this.S) {
              tv.setText("YOU: Scissors");
              this.m = 2;
          }//以上随机得到剪子包袱锤
          this.handler.postDelayed(this.showMessageTask, 1000);//输赢判断方法
      }
  }

//那么就看看输赢判断方法this.showMessageTask

入口的调用($1.smali)找判断方法:


private final Runnable showMessageTask = new Runnable() {
        public void run() {
            TextView tv3 = (TextView) MainActivity.this.findViewById(R.id.textView3);
            MainActivity mainActivity;
            if (MainActivity.this.n - MainActivity.this.m == 1) {
                mainActivity = MainActivity.this;
                mainActivity.cnt++;
                tv3.setText("WIN! +" + String.valueOf(MainActivity.this.cnt));
            } else if (MainActivity.this.m - MainActivity.this.n == 1) {
                MainActivity.this.cnt = 0;
                tv3.setText("LOSE +0");
            } else if (MainActivity.this.m == MainActivity.this.n) {
                tv3.setText("DRAW +" + String.valueOf(MainActivity.this.cnt));
            } else if (MainActivity.this.m < MainActivity.this.n) {
                MainActivity.this.cnt = 0;
                tv3.setText("LOSE +0");
            } else {
                mainActivity = MainActivity.this;
                mainActivity.cnt++;
                tv3.setText("WIN! +" + String.valueOf(MainActivity.this.cnt));
            }
            if (1000 == MainActivity.this.cnt) {
            //获胜1000次获取flag
                tv3.setText("SECCON{" + String.valueOf((MainActivity.this.cnt + MainActivity.this.calc()) * 107) + "}");
            }
            MainActivity.this.flag = 0;
        }
    };

4、结论

1、直接通过AndroidKiller篡改,使打印flag成为必然事件;

2、使用Frida hook脚本传递注入,获取calc()返回值并拼接/修改cnt的值为1000 获得flag;

3、使用Radare2分析so文件汇编代码,分析calc()算法获得flag。

注:AndroidKiller为静态二进制插桩,Frida为动态二进制插桩。

0x03 静态插桩篡改法(AndroidKiller):

1、代码修改

我们可以将打印flag的前置条件删除,对应smali中的操作分别是:

1、删除对应条件判断的smali码(如图右红框所示)

2、前置跳转锚点继承给下一段代码(.line 50)

3、因为smali使用的if-ne为不等于,所以需要将该后置跳转对应的前置锚点全部删除(删除所有smali代码中存在的:cond_0)

4、判断条件删除后将条件改为背景(super.this$0.cnt=1000,即v2=1000,即const/16 v2,0x3e8)

注:smali码转换成java代码后会优化,所以判断方式等会稍有不同

2、APK编译

3、获取Flag

触发条件在button的onclic事件,点击即可获得

耶斯莫拉

0x04 动态插桩调用/篡改法(Frida):

方法一:不篡改程序,调用calc()方法拼接得到flag

1、移动端运行frida-server

没看懂的参考第二章Frida安装最后几步

2、Javascript代码编写

Java.perform(function () {
    //定义变量MainActivity指定使用的类
    var MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');
    //指定类下的onClick方法,为其添加自定义方法
    MainActivity.onClick.implementation = function () {
        //调用calc()方法,获取返回值
        var calcData = this.calc();
        //发送给PC端打印calc()方法返回值
        send("calc() return:"+calcData);
        var result = (1000+calcData)*107;
        //发送给PC端打印flag
        send("SECCON{"+result.toString()+"}");
    }
});

3、Javascript代码套入python模板

import frida, sys
 
def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)
 
jscode = """
Java.perform(function () {
    var MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');
    MainActivity.onClick.implementation = function () {
        var calcData = this.calc();
        send("calc() return:"+calcData);
        var result = (1000+calcData)*107;
        send("SECCON{"+result.toString()+"}");
    }
});
"""
 
process = frida.get_remote_device().attach('com.example.seccon2015.rock_paper_scissors')
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()

4、运行查看flag

方法二:篡改cnt的值为1000 获得flag

5、同上直接上Python代码

import frida, sys
 
def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)
 
jscode = """
Java.perform(function () {
    var MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');
    MainActivity.onClick.implementation = function (v) {
        this.onClick(v);
        this.n.value = 0;
        this.m.value = 2;
        this.cnt.value = 999;
    }
});
"""
 
process = frida.get_remote_device().attach('com.example.seccon2015.rock_paper_scissors')
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()

6、运行查看flag

耶斯莫拉

0x05 汇编代码分析(Radare2):

1、使用radare2对so文件分析(或者ida pro等工具)

常用命令可借鉴:https://cloud.tencent.com/developer/article/1073910

2、拼接获取flag

"SECCON{" + String.valueOf((MainActivity.this.cnt + MainActivity.this.calc()) * 107)+"}"

MainActivity.this.cnt=1000           MainActivity.this.calc()=7

SECCON {107749}

耶斯莫拉

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
逆向工程是指通过逆向分析已有软件的代码和结构,从中获取信息并了解其功能和设计思路的过程。而IDA(Interactive DisAssembler)是逆向工程过程中常用的工具之一,它能够将进制程序文件或动态链接库文件转换为汇编代码,以方便分析和理解。 逆向工程CTF(Capture The Flag)比赛中,参赛者需要通过逆向工程手段来获取隐藏在某个程序或应用中的标志(flag),常以此为目标进行竞赛。而IDA被广泛用作CTF逆向工程比赛的关键工具之一,主要用于分析并理解被逆向的程序。 通过IDA,参赛者可以加载进制文件,然后通过静态或动态分析的方法获取程序的结构和逻辑。IDA提供友好的界面,能够将进制代码转换为易于阅读和理解的汇编代码,并提供多种各类的分析功能,例如交叉引用分析、函数分析、字符串分析、结构和类分析等。这些功能使得解析程序的逻辑和功能变得更加方便和高效。 在逆向工程CTF中,参赛者需要运用IDA的各种功能,结合代码和结构分析,找出隐藏的标志(flag)。这个过程需要具备较强的程序分析能力和逻辑推理能力,同时对底层汇编语言和常见算法有一定了解。 综上所述,IDA作为逆向工程的重要工具,在逆向工程CTF中发挥着重要作用,通过IDA的使用,参赛者可以分析和理解不同程序的结构和逻辑,进而找到隐藏的标志(flag)以完成比赛的任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

土豆.exe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值