• 攻防世界 reverse android-app-100


     android-app-100  suctf-2016

    jeb启动,找到点击事件:

    验证流程:

    输入作为参数 --> processObjectArrayFromNative 得到一返回值(ret_a) --> IsCorrect 返回0,失败;返回1,成功 --> 输出"Sharif_CTF("+md5(str(d+ret_a)+” “+”)“      (.d = 0x1BEBE)

    可以发现flag的获取关键在于processObjectArrayFromNative 的返回值。

     1 public void onClick(View arg8) {
     2         new String(" ");
     3         String v0 = this.a.b.getText().toString();
     4         Log.v("EditText", this.a.b.getText().toString());
     5         new String("");
     6         int v1 = this.a.processObjectArrayFromNative(v0);
     7         int v2 = this.a.IsCorrect(v0);
     8         v0 = String.valueOf(this.a.d + v1) + " ";
     9         try {
    10             MessageDigest v1_1 = MessageDigest.getInstance("MD5");
    11             v1_1.update(v0.getBytes());
    12             byte[] v1_2 = v1_1.digest();
    13             StringBuffer v3 = new StringBuffer();
    14             int v0_2;
    15             for(v0_2 = 0; v0_2 < v1_2.length; ++v0_2) {
    16                 v3.append(Integer.toString((v1_2[v0_2] & 0xFF) + 0x100, 16).substring(1));
    17             }
    18 
    19             if(v2 == 1 && this.a.e != "unknown") {
    20                 this.a.c.setText("Sharif_CTF(" + v3.toString() + ")");
    21             }
    22 
    23             if(v2 == 1 && this.a.e == "unknown") {
    24                 this.a.c.setText("Just keep Trying :-)");
    25             }
    26 
    27             if(v2 == 0) {
    28                 this.a.c.setText("Just keep Trying :-)");
    29             }
    30 
    31             return;
    32         }
    33         catch(NoSuchAlgorithmException v0_1) {
    34             v0_1.printStackTrace();
    35             return;
    36         }
    37     }

    程序有两个native方法:

    public native int IsCorrect(String arg1)

    public native int processObjectArrayFromNative(String arg1)

    IDA启动,

    发现有混淆,但我们还是能发现这两个native方法中调用了strcmp方法

    Java_com_example_ctf2_MainActivity_processObjectArrayFromNative:

     1 ptr_chars = (env_2->functions->GetStringUTFChars)(env_2, jstring_2, 0);
     2           *p_chars = ptr_chars;
     3           temp_chars_ptr = *p_chars;
     4           v46 = &v8;
     5           v51 = 101;
     6           v8 = 926246501;
     7           v52 = 53;
     8           v45 = 55;
     9           v9 = 102;
    10           v10 = 51;
    11           v11 = 102;
    12           v12 = 101;
    13           v13 = 51;
    14           v44 = 99;
    15           v14 = 99;
    16           v15 = 102;
    17           v16 = 54;
    18           v17 = 48;
    19           v18 = 51;
    20           v19 = 99;
    21           v20 = 48;
    22           v21 = 51;
    23           v22 = 56;
    24           v23 = 57;
    25           v24 = 48;
    26           v25 = 101;
    27           v26 = 101;
    28           v27 = 53;
    29           v28 = 56;
    30           v29 = 56;
    31           v30 = 56;
    32           v31 = 55;
    33           v32 = 56;
    34           v33 = 99;
    35           v34 = 48;
    36           v35 = 101;
    37           v36 = 99;
    38           v50_2 = v50;
    39           v38 = 53;
    40           v5 = j_strcmp(temp_chars_ptr, &v8);

    processObjectArrayFromNative方法返回值:0或者0x57cbbd2

    Java_com_example_ctf2_MainActivity_IsCorrect方法内也进行了字符串比较,

    通过脚本我们可以获取到进行比较的字符串:

     1 v51 = 'e';
     2 v8 = '75fe'[::-1];
     3 v52 = '5';
     4 v45 = '7';
     5 v9 = 'f';
     6 v10 = '3';
     7 v11 = 'f';
     8 v12 = 'e';
     9 v13 = '3';
    10 v44 = 'c';
    11 v14 = 'c';
    12 v15 = 'f';
    13 v16 = '6';
    14 v17 = '0';
    15 v18 = '3';
    16 v19 = 'c';
    17 v20 = '0';
    18 v21 = '3';
    19 v22 = '8';
    20 v23 = '9';
    21 v24 = '0';
    22 v25 = 'e';
    23 v26 = 'e';
    24 v27 = '5';
    25 v28 = '8';
    26 v29 = '8';
    27 v30 = '8';
    28 v31 = '7';
    29 v32 = '8';
    30 v33 = 'c';
    31 v34 = '0';
    32 v35 = 'e';
    33 v36 = 'c';
    34 x=''
    35 for i in range(8,37):
    36   x+=locals()['v'+str(i)]
    37 print(x)
    38 print(len(x))
    39 
    40 v12 = 101;
    41 v13 = 102;
    42 v14 = 53;
    43 v15 = 55;
    44 v16 = 102;
    45 v17 = 51;
    46 v18 = 102;
    47 v19 = 101;
    48 v20 = 51;
    49 v21 = 99;
    50 v22 = 102;
    51 v23 = 54;
    52 v24 = 48;
    53 v25 = 51;
    54 v26 = 99;
    55 v27 = 48;
    56 v28 = 51;
    57 v29 = 56;
    58 v30 = 57;
    59 v31 = 48;
    60 v32 = 101;
    61 v33 = 101;
    62 v34 = 53;
    63 v35 = 56;
    64 v36 = 56;
    65 v37 = 56;
    66 v38 = 55;
    67 v39 = 56;
    68 v40 = 99;
    69 v41 = 48;
    70 v42 = 101;
    71 v43 = 99;
    72 
    73 y=''
    74 for i in range(12,44):
    75   y+=chr(locals()['v'+str(i)])
    76 print(y)
    77 print(len(y))
    78 
    79 
    80 '''
    81 ef57f3fe3cf603c03890ee588878c0ec
    82 32
    83 ef57f3fe3cf603c03890ee588878c0ec
    84 32
    85 '''
    View Code

    ef57f3fe3cf603c03890ee588878c0ec

    运行adb命令输入到编辑框

    adb shell input text ef57f3fe3cf603c03890ee588878c0ec

    当然也可以静态获取:

    1 ret_a=0x57CBBD2
    2 d=0x1BEBE
    3 d=str(d+ret_a)+' '
    4 print(d)
    5 import hashlib
    6 m=hashlib.md5(d.encode()).hexdigest()
    7 print('Sharif_CTF('+m+')')

    Sharif_CTF(833489ef285e6fa80690099efc5d9c9d)

    (一开始还原算法时得到的结果不对,又写了个frida脚本验证,返回值没问题,后来才发现要md5的字符串忘了加空格 0.0)

    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 
     11 jscode = """
     12 setImmediate(function () {
     13     Java.perform(function () {
     14         console.log("start");
     15         //so层hook
     16         //导出函数
     17         //var exports = Module.enumerateExportsSync("libadnjni.so");
     18         //for(var i=0;i<exports.length;i++){
     19         //    send("name:"+exports[i].name+"  address:"+exports[i].address);
     20         // }
     21         var str = Java.use("java.lang.String");
     22         //遍历模块找基址
     23         // Process.enumerateModules({
     24         //     onMatch: function (exp) {
     25         //         if (exp.name == 'libadnjni.so') {
     26         //             send('enumerateModules find');
     27         //             send(exp.name + "|" + exp.base + "|" + exp.size + "|" + exp.path);
     28         //             send(exp);
     29         //             return 'stop';
     30         //         }
     31         //     },
     32         //     onComplete: function () {
     33         //         send('enumerateModules stop');
     34         //     }
     35         // });
     36 
     37         //通过模块名直接查找基址
     38         var soAddr = Module.findBaseAddress("libadnjni.so");
     39         send("soAddr:" + soAddr);
     40 
     41         var parray=0x48c+1;
     42         var pcorrect=0x74c+1;
     43         //   hook导出函数 通过函数名
     44 
     45         //Module.findExportByName 找到的函数地址无效
     46         // var farray=Module.findExportByName("libadnjni.so", "Java_com_example_ctf2_MainActivity_processObjectArrayFromNative")
     47         // send("findExportByName farray() by Module.findExportByName:" +farray);
     48         var farray=new NativePointer(soAddr).add(parray);
     49         //NativePointer   简写ptr
     50         send("findExportByName farray() by ptr:" +farray );
     51 
     52         Interceptor.attach(farray, {
     53             onEnter: function (args) {
     54                 var s = Java.cast(args[2], str);
     55                 send("array()  jstring:" + s );
     56             },
     57             onLeave: function (retval) {
     58                 send("array() return:" + retval);
     59             }
     60         });
     61 
     62         //   hook导出函数 通过函数名
     63         // var fcorrect=Module.findExportByName("libadnjni.so", "Java_com_example_ctf2_MainActivity_IsCorrect");
     64         // send("findExportByName correct()  by Module.findExportByName:" +fcorrect );
     65         var fcorrect=new NativePointer(soAddr).add(pcorrect);
     66         send("findExportByName correct()  by ptr:" +fcorrect );
     67         Interceptor.attach(fcorrect, {
     68             onEnter: function (args) {
     69                 var s = Java.cast(args[2], str);
     70                 send("fcorrect() jstring:" + s );
     71             },
     72             onLeave: function (retval) {
     73                 send("fcorrect() return:" + retval);
     74             }
     75         });
     76         
     77     });
     78 });
     79 """
     80 # print(jscode)
     81 
     82 # 启动时hook   
     83 # devices=frida.get_usb_device()
     84 # pid=devices.spawn(['com.example.goal'])   
     85 # session=devices.attach(pid)
     86 # devices.resume(pid)    #创建完脚本, 恢复进程运行
     87 # script=session.create_script(jscode)
     88 
     89 # 命令行frida -U -f com.example.goal --no-pause -l <hook.js>
     90 
     91 # 运行中hook
     92 process = frida.get_usb_device().attach('com.example.ctf2')
     93 script = process.create_script(jscode)
     94 script.on('message', on_message)
     95 print('[*] Running test')
     96 script.load()
     97 sys.stdin.read()
     98 
     99 # ef57f3fe3cf603c03890ee588878c0ec
    100 
    101 '''
    102 [*] Running test
    103 start
    104 [*] soAddr:0xcd562000
    105 [*] findExportByName farray() by ptr:0xcd56248d
    106 [*] findExportByName correct()  by ptr:0xcd56274d
    107 [*] array()  jstring:Serial Number
    108 [*] array() return:0x0
    109 [*] fcorrect() jstring:Serial Number
    110 [*] fcorrect() return:0x0
    111 
    112 
    113 [*] array()  jstring:ef57f3fe3cf603c03890ee588878c0ec
    114 [*] array() return:0x57cbbd2
    115 [*] fcorrect() jstring:ef57f3fe3cf603c03890ee588878c0ec
    116 [*] fcorrect() return:0x1
    117 '''
    View Code
  • 相关阅读:
    win10前面板耳机没声音
    学计算机的值得一看的文章,跟帖也很有水平啊
    ubuntu下编译caffe
    pip卡住不动的解决方案
    数字图像处理处理中的数学怎么提高?
    安装vmall5:从ebak恢复数据,需要配置php.ini
    python入门(7)Python程序的风格
    python入门(6)输入和输出
    python入门(5)使用文件编辑器编写代码并保存执行
    python入门(4)第一个python程序
  • 原文地址:https://www.cnblogs.com/DirWang/p/11579448.html
Copyright © 2020-2023  润新知