pingpong  XCTF 3rd-BCTF-2017

java层代码很简单:

  1 package com.geekerchina.pingpongmachine;
2
3 import android.os.Bundle;
4 import android.support.v7.app.AppCompatActivity;
5 import android.view.Menu;
6 import android.view.MenuItem;
7 import android.view.View$OnClickListener;
8 import android.view.View;
9 import android.widget.TextView;
10
11 public class MainActivity extends AppCompatActivity {
12 class com.geekerchina.pingpongmachine.MainActivity$1 implements View$OnClickListener {
13 com.geekerchina.pingpongmachine.MainActivity$1(MainActivity arg1) {
14 MainActivity.this = arg1;
15 super();
16 }
17
18 public void onClick(View arg7) {
19 if(MainActivity.this.tt % 2 == 1) {
20 MainActivity.this.p = 0;
21 MainActivity.this.num = 0;
22 MainActivity.this.tt = MainActivity.this.ttt;
23 }
24
25 --MainActivity.this.tt;
26 MainActivity.this.p = MainActivity.this.ping(MainActivity.this.p, MainActivity.this.num);
27 ++MainActivity.this.num;
28 if(MainActivity.this.num >= 7) {
29 MainActivity.this.num = 0;
30 }
31
32 View v0 = MainActivity.this.findViewById(0x7F0B0056);
33 ((TextView)v0).setText("PING");
34 if(MainActivity.this.tt == 0) {
35 ((TextView)v0).setText("FLAG: BCTF{MagicNum" + Integer.toString(MainActivity.this.p) + "}");
36 }
37 }
38 }
39
40 class com.geekerchina.pingpongmachine.MainActivity$2 implements View$OnClickListener {
41 com.geekerchina.pingpongmachine.MainActivity$2(MainActivity arg1) {
42 MainActivity.this = arg1;
43 super();
44 }
45
46 public void onClick(View arg7) {
47 if(MainActivity.this.tt % 2 == 0) {
48 MainActivity.this.p = 0;
49 MainActivity.this.num = 0;
50 MainActivity.this.tt = MainActivity.this.ttt;
51 }
52
53 --MainActivity.this.tt;
54 MainActivity.this.p = MainActivity.this.pong(MainActivity.this.p, MainActivity.this.num);
55 ++MainActivity.this.num;
56 if(MainActivity.this.num >= 7) {
57 MainActivity.this.num = 0;
58 }
59
60 View v0 = MainActivity.this.findViewById(0x7F0B0056);
61 ((TextView)v0).setText("PONG");
62 if(MainActivity.this.tt == 0) {
63 ((TextView)v0).setText("FLAG: BCTF{MagicNum" + Integer.toString(MainActivity.this.p) + "}");
64 }
65 }
66 }
67
68 View$OnClickListener jping;
69 View$OnClickListener jpong;
70 public int num;
71 public int p;
72 public int tt;
73 public int ttt;
74
75 static {
76 System.loadLibrary("pp");
77 }
78
79 public MainActivity() {
80 super();
81 this.p = 0;
82 this.num = 0;
83 this.ttt = 1000000;
84 this.tt = this.ttt;
85 this.jping = new com.geekerchina.pingpongmachine.MainActivity$1(this);
86 this.jpong = new com.geekerchina.pingpongmachine.MainActivity$2(this);
87 }
88
89 protected void onCreate(Bundle arg4) {
90 super.onCreate(arg4);
91 this.setContentView(0x7F04001B);
92 this.findViewById(0x7F0B0057).setOnClickListener(this.jping);
93 this.findViewById(0x7F0B0058).setOnClickListener(this.jpong);
94 }
95
96 public boolean onCreateOptionsMenu(Menu arg3) {
97 this.getMenuInflater().inflate(0x7F0D0000, arg3);
98 return 1;
99 }
100
101 public boolean onOptionsItemSelected(MenuItem arg3) {
102 boolean v1 = arg3.getItemId() == 0x7F0B0070 ? true : super.onOptionsItemSelected(arg3);
103 return v1;
104 }
105
106 public native int ping(int arg1, int arg2) {
107 }
108
109 public native int pong(int arg1, int arg2) {
110 }
111 }

有两个按钮,分别调用natice层 ping方法、pong方法

先随便点一个,然后先ping 后pong,总共点击1000000次后输出flag

libpp.so 中的方法ping、pong中都有调用sleep(1) ,我们需要修改so文件,将其参数设为0

网上的一些wp都是新建个工程,然后调用so中方法。

那我们直接使用frida调用不就好了。

frida脚本:

  1 import frida, sys
2
3
4 def on_message(message, data):
5 if message['type'] == 'send':
6 print("[*] {0}".format(message['payload']))
7 else:
8 print(message)
9
10 jscode = """
11 setImmediate(function () {
12 Java.perform(function () {
13 console.log("start");
14 //so层hook
15 //导出函数
16 //var exports = Module.enumerateExportsSync("libpp.so");
17 //for(var i=0;i<exports.length;i++){
18 // send("name:"+exports[i].name+" address:"+exports[i].address);
19 // }
20
21 //遍历模块找基址
22 Process.enumerateModules({
23 onMatch: function (exp) {
24 if (exp.name == 'libpp.so') {
25 send('enumerateModules find');
26 send(exp.name + "|" + exp.base + "|" + exp.size + "|" + exp.path);
27 send(exp);
28 return 'stop';
29 }
30 },
31 onComplete: function () {
32 send('enumerateModules stop');
33 }
34 });
35
36 //通过模块名直接查找基址
37 var soAddr = Module.findBaseAddress("libpp.so");
38 send("soAddr:" + soAddr);
39
40 var aping=0x1308+1
41 var apong=0x1564+1
42 // hook导出函数 通过函数名
43
44 var fping=Module.findExportByName("libpp.so", "Java_com_geekerchina_pingpongmachine_MainActivity_ping")
45 send("findExportByName ping():" +fping );
46 fping=new NativePointer(soAddr).add(aping);
47 //NativePointer 简写ptr
48 send("findExportByName ping():" +fping );
49 var ping=new NativeFunction(fping, "int", ['pointer','pointer','int', 'int']);
50
51
52 //send("findExportByName edit():"+Module.findExportByName("libpp.so", "_ZL4editP7_JNIEnvP8_jobjecti"))
53 // Interceptor.attach(fping, {
54 // onEnter: function (args) {
55 // send("ping() began p:" + args[2] + ", num:" + args[3] );
56 // },
57 // onLeave: function (retval) {
58 // send("ping() return:" + retval);
59 // }
60 // });
61
62 // hook导出函数 通过函数名
63 var fpong=Module.findExportByName("libpp.so", "Java_com_geekerchina_pingpongmachine_MainActivity_pong")
64 send("findExportByName pong():" +fpong );
65 fpong=new NativePointer(soAddr).add(apong);
66 send("findExportByName pong():" +fpong );
67 var pong=new NativeFunction(fpong, "int", ['pointer','pointer','int', 'int']);
68 //send("findExportByName edit():"+Module.findExportByName("libpp.so", "_ZL4editP7_JNIEnvP8_jobjecti"))
69 // Interceptor.attach(fpong, {
70 // onEnter: function (args) {
71 // send("pong() began p:" + args[2] + ", num:" + args[3] );
72 // },
73 // onLeave: function (retval) {
74 // send("pong() return:" + retval);
75 // }
76 // });
77 var env = Java.vm.getEnv();
78 var obj=ptr(0);
79 var check = 1000000;
80 var beFlag = 0;
81 var num = 0;
82 while (true) { //下面这部分代码参考 https://blog.csdn.net/jasalee/article/details/70242837
83 if (check % 2 == 1) {
84 --check;
85 beFlag = pong(env,obj,beFlag,num);
86 ++num;
87 if(num >= 7) {
88 num = 0;
89 }
90 } else {
91 --check;
92 beFlag = ping(env,obj,beFlag,num);
93 ++num;
94 if(num >= 7){
95 num = 0;
96 }
97 }
98 if (check == 0) {
99 send("check:"+check+" num:"+num)
100 send("FLAG : "+"BCTF{MagicNum" + beFlag+ "}");
101 break;
102 }
103 }
104
105 });
106 });
107 """
108
109
110 # 运行中hook
111 process = frida.get_usb_device().attach('com.geekerchina.pingpongmachine')
112 script = process.create_script(jscode)
113 script.on('message', on_message)
114 print('[*] Running test')
115 script.load()
116 sys.stdin.read()
117
118
119 '''
120 [*] Running test
121 start
122 [*] enumerateModules find
123 [*] libpp.so|0xd4c48000|24576|/data/app/com.geekerchina.pingpongmachine-6gshbHpfeBmTBFRYBxQpNg==/lib/arm/libpp.so
124 [*] {'name': 'libpp.so', 'base': '0xd4c48000', 'size': 24576, 'path': '/data/app/com.geekerchina.pingpongmachine-6gshbHpfeBmTBFRYBxQpNg==/lib/arm/libpp.so'}
125 [*] enumerateModules stop
126 [*] soAddr:0xd4c48000
127 [*] findExportByName ping():0xd34c9309
128 [*] findExportByName ping():0xd4c49309
129 [*] findExportByName pong():0xd34c9565
130 [*] findExportByName pong():0xd4c49565
131 [*] check:0 num:1
132 [*] FLAG : BCTF{MagicNum4500009}
133 '''

大约要跑4、5分钟的样子,没去分析ping、pong方法,大佬们可以分析一波 0.0

BCTF{MagicNum4500009}

脚本编写中也发现了一个问题:

  Module.findExportByName 得到的地址不正确。

应该使用 基地址+函数偏移地址(thumb指令下偏移地址+1)

攻防世界 reverse pingpong的更多相关文章

  1. 攻防世界 reverse 进阶 10 Reverse Box

    攻防世界中此题信息未给全,题目来源为[TWCTF-2016:Reverse] Reverse Box 网上有很多wp是使用gdb脚本,这里找到一个本地还原关键算法,然后再爆破的 https://www ...

  2. 攻防世界 reverse evil

    这是2017 ddctf的一道逆向题, 挑战:<恶意软件分析> 赛题背景: 员工小A收到了一封邮件,带一个文档附件,小A随手打开了附件.随后IT部门发现小A的电脑发出了异常网络访问请求,进 ...

  3. 攻防世界 reverse tt3441810

    tt3441810 tinyctf-2014 附件给了一堆数据,将十六进制数据部分提取出来, flag应该隐藏在里面,(这算啥子re,) 保留可显示字符,然后去除填充字符(找规律 0.0) 处理脚本: ...

  4. 攻防世界 reverse 进阶 APK-逆向2

    APK-逆向2 Hack-you-2014 (看名以为是安卓逆向呢0.0,搞错了吧) 程序是.net写的,直接祭出神器dnSpy 1 using System; 2 using System.Diag ...

  5. 攻防世界 reverse Windows_Reverse2

    Windows_Reverse2   2019_DDCTF 查壳: 寻找oep-->dump-->iat修复   便可成功脱壳 int __cdecl main(int argc, con ...

  6. 攻防世界 reverse BabyXor

    BabyXor     2019_UNCTF 查壳 脱壳 dump 脱壳后 IDA静态分析 int main_0() { void *v0; // eax int v1; // ST5C_4 char ...

  7. 攻防世界 reverse parallel-comparator-200

    parallel-comparator-200 school-ctf-winter-2015 https://github.com/ctfs/write-ups-2015/tree/master/sc ...

  8. 攻防世界 reverse 进阶 8-The_Maya_Society Hack.lu-2017

    8.The_Maya_Society Hack.lu-2017 在linux下将时间调整为2012-12-21,运行即可得到flag. 下面进行分析 1 signed __int64 __fastca ...

  9. 攻防世界 reverse easy_Maze

    easy_Maze 从题目可得知是简单的迷宫问题 int __cdecl main(int argc, const char **argv, const char **envp) { __int64 ...

随机推荐

  1. JDK下载安装与卸载详解

    JDK下载安装 1. 下载: 推荐版本:JDK 8 (7.8目前广泛应用) 官网地址:https://www.oracle.com/cn/java/technologies/javase/javase ...

  2. AbstractQueuedSynchronizer的使用和juc里的相关类的解析

    对AQS进行解析后,先来实现两个简单的基于AQS的类,然后再解析juc里基于AQS构造的类. 1.基于AQS的类的示例 首先先看这个类,这个类是<Java并发编程实战>的一个示例,AQS源 ...

  3. Sentry React SourceMaps All In One

    Sentry React SourceMaps All In One React https://docs.sentry.io/platforms/javascript/guides/react/ h ...

  4. vue 的 computed 属性在什么时间执行

    vue 的 computed 属性在什么时间执行

  5. Flutter & release an iOS app

    Flutter & release an iOS app https://flutter.dev/docs/deployment/ios .ipa https://en.wikipedia.o ...

  6. Word带数学公式发布博客

    Word公式编辑器无法直接上传博客,一个一个的转换LaTeX还要加$,十分麻烦. 下面是我昨天摸索出来的办法.作为博客新人,这个问题困扰我一晚上,能解决我也是非常高兴的. 如果各位前辈有好方法的话,请 ...

  7. 运用Spock编写高质量单元测试

    单元测试作为提升代码质量的有效方法,目前在国内各大互联网公司的开发团队中,尤其是业务团队中却鲜少被使用.这主要由于大家对于单元测试有一些认知错误,或者没有正确的打开方式.至今我们团队在小剧场.零代码运 ...

  8. 微信小程序:数据绑定

    data中的数据不仅仅可以当成文本来显示,还可以当成属性来显示. 注意:属性值要用单引号或双引号引起来. 在微信开发者工具的控制台中点击Wxml会看到 使用Boolean类型充当属性的时候,字符串和花 ...

  9. 1.3.1 apache的配置(上)

    Apache是比较常用的web服务器软件,用来解析HTTP网页.这里需注意,apache本身并不能解析php页面,它是用来配置解析http页面的.当然,作为一款最流行的web服务器软件,apache支 ...

  10. Kubernetes-6.Service

    docker version:20.10.2 kubernetes version:1.20.1 本文概述Kubernetes Service的基本原理和使用. 服务 Service是将运行在一组Po ...