吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9067|回复: 27
收起左侧

[Android CTF] 钉钉CTF+AliCTF2015第三题+Android逆向小助手使用详解

  [复制链接]
Anonymous、 发表于 2018-9-30 16:50
本帖最后由 Anonymous、 于 2018-10-12 20:39 编辑

一、说明
钉钉CTF是一个网友昨晚给我的,比较简单,但是思路和AliCTF非常像,所以就放在一起了,一些坛友问工具怎么使用
其实很简单,在这也稍微加下使用说明,自己技术比较菜,全程靠猜~~~~~有什么不对的地方,还请各位师傅指点.

二、钉钉CTF
这一题比较简单,先打开app看下
1.png
随便输入
3.png
错了,但是有个welcome to flag blank!根据题目意思,尝试什么都不输入
QQ截图20180930143731.png
什么??????居然就对了!!!!!
好了,开始看Ali的吧...............

算啦算啦,还是看看内部怎么实现的这么牛逼的功能的吧
[Java] 纯文本查看 复制代码
    protected void onCreate(Bundle arg3) {
        super.onCreate(arg3);
        this.setContentView(2130968603);
        this.text = this.findViewById(2131427416);
        this.textView1 = this.findViewById(2131427418);
        this.button = this.findViewById(2131427415);
        this.button.setOnClickListener(new View$OnClickListener() {
            public void onClick(View arg4) {
                MainActivity.this.c = new CheckClass();
                MainActivity.this.c.a(MainActivity.this.text.getText().toString());  //先获取输入的字符串
                if(MainActivity.this.c.check()) {  //关键点
                    MainActivity.this.textView1.setText("flag is XMAN{" + MainActivity.this.text.getText().toString() + "}");    
                }
                else {
                    MainActivity.this.textView1.setText("WORING!");
                }
            }
        });
    }

onCreate方法中,先看MainActivity.this.c.a
[Java] 纯文本查看 复制代码
public void a(String arg5) {
        int v1 = 30;
        this.A = new byte[v1];
        this.B = arg5.getBytes();
        int v0;
        for(v0 = 0; v0 < arg5.length(); ++v0) {
            this.A[v0] = this.B[v0];
        }

        this.B = new byte[v1];
    }

获取输入的字符串,再看MainActivity.this.c.check()
[Java] 纯文本查看 复制代码
 public boolean check() {
        boolean v9 = false;
        int[] v0 = new int[]{40, 42, 65, 67, 68, 2, 64, 70, 96, 98, 181, 7, 10, 64, 23, 17, 37, 20, 45, 91, 74, 72, 135, 33, 57, 43, 87, 99, 147, 53};
        byte[] v5 = new byte[]{52, 111, 102, 113, 52, 52, 98};
        int v2 = 0;
        int v4 = 0;
        int v7 = 0;
        int v1;
        for(v1 = 0; v1 < v0.length; ++v1) {
            int v8 = this.b(v0[v1]);
            new String();
            Log.d("now array:", String.valueOf(v8));
            switch(v8) {
                case 0: {
                    this.A[v7] = ((byte)(this.A[v7] ^ v7));
                    break;
                }
                case 1: {
                    if(this.A[v4] != 0) {
                        ++v4;
                    }
                    else {
                    }

                    break;
                }
                case 2: {
                    v5[v4] = ((byte)(v5[v4] ^ v4));
                    ++v4;
                    break;
                }
                case 3: {
                    if(v5[v7] == this.A[v7]) {
                        ++v7;
                    }
                    else {
                    }

                    break;
                }
                case 4: {
                    if(v7 == v4) {
                        v9 = true;
                    }

                    return v9;
                }
                case 5: {
                    if(v4 != v5.length) {
                        v1 = v0.length - 3;
                    }
                    else {
                        v4 = 0;
                    }

                    break;
                }
                default: {
                    ++v2;
                    break;
                }
            }
        }

        return v9;
    }

public int b(int arg4) {
        int v0 = 181 & arg4;
        return (v0 & 1) + ((v0 & 4) >> 2) + ((v0 & 16) >> 4) + ((v0 & 32) >> 5) + ((v0 & 128) >> 7);
  }

此函数为关键点,看着挺复杂的,只要返回为true即可
[Java] 纯文本查看 复制代码
 case 4: {
                    if(v7 == v4) {
                        v9 = true;
                    }
                    return v9;
                }

case 4里的判断执行,下面再接着分析v8
[Java] 纯文本查看 复制代码
int v8 = this.b(v0[v1]); 

由于v0是固定的,所以v8也是固定的,那么switch语句就好分析了
[Java] 纯文本查看 复制代码
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class DCtf {
         private static byte[] A;
         private static byte[] B;
        public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException {
                a("4");
                check();
          }        
        
        public static void a(String arg5) {
        int v1 = 30;
        A = new byte[v1];
        B = arg5.getBytes();
        int v0;
        for(v0 = 0; v0 < arg5.length(); ++v0) {
            A[v0] = B[v0];
        }

        B = new byte[v1];
    }

    public static int b(int arg4) {
        int v0 = 181 & arg4;
        return (v0 & 1) + ((v0 & 4) >> 2) + ((v0 & 16) >> 4) + ((v0 & 32) >> 5) + ((v0 & 128) >> 7);
    }

    public static boolean check() {
        boolean v9 = false;
        int[] v0 = new int[]{40, 42, 65, 67, 68, 2, 64, 70, 96, 98, 181, 7, 10, 64, 23, 17, 37, 20, 45, 91, 74, 72, 135, 33, 57, 43, 87, 99, 147, 53};
        byte[] v5 = new byte[]{52, 111, 102, 113, 52, 52, 98};
        int v2 = 0;
        int v4 = 0;
        int v7 = 0;
        int v1;
        for(v1 = 0; v1 < v0.length; ++v1) {
            int v8 = b(v0[v1]);
            new String();
            System.out.println("now array:" + String.valueOf(v8));
            switch(v8) {
                case 0: {
                    A[v7] = ((byte)(A[v7] ^ v7));
                    break;
                }
                case 1: {
                    if(A[v4] != 0) {
                        ++v4;
                    }
                    else {
                    }
                    break;
                }
                case 2: {
                    v5[v4] = ((byte)(v5[v4] ^ v4));
                    ++v4;
                    break;
                }
                case 3: {
                    if(v5[v7] == A[v7]) {
                            System.out.println("v5[v7] "+v5[v7]+"------A[v7] "+A[v7]+" "+v7);
                        ++v7;
                    }
                    else {
                    }
                    break;
                }
                case 4: {
                    if(v7 == v4) {
                        v9 = true;
                    }
                    System.out.println("v7 "+v7+"------v4 "+v4);

                    return v9;
                }
                case 5: {
                    if(v4 != v5.length) {
                        v1 = v0.length - 3;
                    }
                    else {
                        v4 = 0;
                    }

                    break;
                }
                default: {
                    ++v2;
                    break;
                }
                
            }
        }

        return v9;
    }
}

运行上面的代码,可以得到v8的值分别是
[C] 纯文本查看 复制代码
now array:1
now array:1
now array:1
now array:1
now array:1
now array:0
now array:0
now array:1
now array:1
now array:1
now array:5
now array:3
now array:4

最后执行的就是case 4,符合我们前面的分析,但是v7 == v4,能影响v7的只有case 3这个分支,看上面v8的值,知道下面的代码只执行了一次
[Java] 纯文本查看 复制代码
case 3: {
                    if(v5[v7] == this.A[v7]) {
                        ++v7;
                    }
                    else {
                    }
                    break;
                }

所以要想v7 == v4,v7和v4只能为1或者0,0就是什么都不输入,++v7执行之后为1,执行之前v7为就为0,所以A[v7]=52,查找ascall码表结果为4
4.png
分析到这,你就认为完了?然后并没有结束、、、、
[Java] 纯文本查看 复制代码
case 5: {
                                if (v4 != v5.length) {
                                        v1 = v0.length - 3;
                                } else {
                                        v4 = 0;
                                }

                                break;
                        }

上面的分析的是v4 != v5.length结果,如果v4 = v5.length呢,继续往下分析吧,也就是输入的字符串为7位
[Java] 纯文本查看 复制代码
now array:1
now array:1
now array:1
now array:1
now array:1
now array:0
now array:0
now array:1
now array:1
now array:1
now array:5
now array:2
now array:0
now array:0
now array:3
v5[v7] 52------A[v7] 52 v7 0
now array:2
now array:3
now array:2
now array:3
now array:2
now array:0
now array:0
now array:3
now array:2
now array:3
now array:2
now array:3
now array:2
now array:3
now array:4
v7 1------v4 7

控制v7的的case只有一个
[Asm] 纯文本查看 复制代码
case 3: {
                                if (v5[v7] == A[v7]) {
                                        System.out.println("v5[v7] " + v5[v7] + "------A[v7] " + A[v7] + " v7 " + v7);
                                        ++v7;
                                } else {
                                }
                                break;
                        }

根据上面的代码循环,可以慢慢倒推出来结果为4ndr01d,真是一波三折呀。。。
QQ截图20181012203342.png
放下分析的代码
[Java] 纯文本查看 复制代码
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class ctf1 {
        private static byte[] A;
        private static byte[] B;

        public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException {
                a("4ndr01d");
                check();
        }

        public static void a(String arg5) {
                int v1 = 30;
                A = new byte[v1];
                B = arg5.getBytes();
                int v0;
                for (v0 = 0; v0 < arg5.length(); ++v0) {
                        A[v0] = B[v0];
                }

                B = new byte[v1];
        }

        public static int b(int arg4) {
                int v0 = 181 & arg4;
                return (v0 & 1) + ((v0 & 4) >> 2) + ((v0 & 16) >> 4) + ((v0 & 32) >> 5) + ((v0 & 128) >> 7);
        }

        public static boolean check() {
                boolean v9 = false;
                int[] v0 = new int[] { 40, 42, 65, 67, 68, 2, 64, 70, 96, 98, 181, 7, 10, 64, 23, 17, 37, 20, 45, 91, 74, 72,
                                135, 33, 57, 43, 87, 99, 147, 53 };
                byte[] v5 = new byte[] { 52, 111, 102, 113, 52, 52, 98 };
                int v2 = 0;
                int v4 = 0;
                int v7 = 0;
                int v1;
                for (v1 = 0; v1 < v0.length; ++v1) {
                        int v8 = b(v0[v1]);
                        new String();
                        System.out.println("now array:" + String.valueOf(v8));
                        switch (v8) {
                        case 0: {
                                A[v7] = ((byte) (A[v7] ^ v7));
                                break;
                        }
                        case 1: {
                                if (A[v4] != 0) {
                                        ++v4;
                                } else {
                                }
                                break;
                        }
                        case 2: {
                                v5[v4] = ((byte) (v5[v4] ^ v4));
                                ++v4;
                                break;
                        }
                        case 3: {
                                if (v5[v7] == A[v7]) {
                                        System.out.println("v5[v7] " + v5[v7] + "------A[v7] " + A[v7] + " v7 " + v7);
                                        ++v7;
                                } else {
                                }
                                break;
                        }
                        case 4: {
                                if (v7 == v4) {
                                        v9 = true;
                                }
                                System.out.println("v7 " + v7 + "------v4 " + v4);
                                return v9;
                        }
                        case 5: {
                                if (v4 != v5.length) {
                                        v1 = v0.length - 3;
                                } else {
                                        v4 = 0;
                                }

                                break;
                        }
                        default: {
                                ++v2;
                                break;
                        }

                        }
                }

                return v9;
        }
}


三、Alictf
好啦,终于可以上主菜了~~~~~~

先用jeb反编译
[Java] 纯文本查看 复制代码
package com.ali.mobisecenhance;

import android.app.Application;
import android.content.Context;

public class StubApplication extends Application {
    static {
        try {
            Class v2 = Class.forName("android.os.SystemProperties");
            Object v1 = v2.getDeclaredMethod("get", String.class).invoke(v2, "ro.product.cpu.abi");
        }
        catch(Exception v3) {
            v3.printStackTrace();
        }

        if(((String)v1).equalsIgnoreCase("x86")) {
            System.loadLibrary("mobisecx");
        }
        else {
            System.loadLibrary("mobisec");
        }
    }

    public StubApplication() {
        super();
    }

    protected native void attachBaseContext(Context arg1) {
    }

    public native void onCreate() {
    }
}

加了壳子~~~~关键代码看不到,那就先用IDA脱壳
先打开DDMS
5.png
获取入口点
6.png
一键挂起
7.png
用ida附加
9.png
在ibdvm的dvmDefineClass下了个断点,通过DvmDex的指针,把odex dump下来,下好断点,点jdb启动
11.png
查看r0地址
13.png
跟随上面的地址
14.png
用脚步dump下来
[C] 纯文本查看 复制代码
static main(void)
{
auto fp, dex_addr, end_addr;
fp = fopen("C:\\dump.dex", "wb");
end_addr = 0x75512000 + 0x00010000;
for ( dex_addr = 0x75512000; dex_addr < end_addr; dex_addr ++ )
fputc(Byte(dex_addr), fp);
}

然后修复,最后用版主的Apktool工具,反编译dex,再回编译,就可以用jeb打开了
15.png

16.png
下面就是分析java代码了
主要是根据这个表对我们输入的字符串,进行置换
[Java] 纯文本查看 复制代码
static {
        e.a = new HashMap();
        e.a("a", ". _");
        e.a("b", "_ . . .");
        e.a("c", "_ . _ .");
        e.a("d", "_ . .");
        e.a("e", ".");
        e.a("f", ". . _ .");
        e.a("g", "_ _ .");
        e.a("h", ". . . .");
        e.a("i", ". .");
        e.a("j", ". _ _ _");
        e.a("k", "_ . _");
        e.a("l", ". _ . .");
        e.a("m", "_ _");
        e.a("n", "_ .");
        e.a("o", "_ _ _");
        e.a("p", ". _ _ .");
        e.a("q", "_ _ . _");
        e.a("r", ". _ .");
        e.a("s", ". . .");
        e.a("t", "_");
        e.a("u", ". . _");
        e.a("v", ". . . _");
        e.a("w", ". _ _");
        e.a("x", "_ . . _");
        e.a("y", "_ . _ _");
        e.a("z", "_ _ . .");
        e.a("2", ". _ _ _ _");
        e.a("1", ". . _ _ _");
        e.a("3", ". . . _ _");
        e.a("4", ". . . . _");
        e.a("0", ". . . . .");
        e.a("6", "_ . . . .");
        e.a("9", "_ _ . . .");
        e.a("8", "_ _ _ . .");
        e.a("7", "_ _ _ _ .");
        e.a("5", "_ _ _ _ _");
    }

    public e() {
        super();
    }

    public String a(String arg8) {
        String v0;
        dn.b(dn.a());
        if(arg8.equals("...___...")) {
            v0 = "sos";
        }
        else {
            StringBuilder v2 = new StringBuilder();
            String[] v3 = arg8.split("\\s+");  //根据空格进行分割
            int v4 = v3.length;
            int v1 = 0;
            while(true) {
                if(v1 < v4) {
                    Object v0_1 = e.a.get(v3[v1]); //替换
                    if(v0_1 != null) {
                        v2.append(((String)v0_1));//连接
                        ++v1;
                        continue;
                    }
                    else {
                        break;
                    }
                }
                else {
                    goto label_26;
                }

                return v0;
            }

            throw new IllegalArgumentException();
        label_26:
            v0 = v2.toString();
        }
        return v0;
    }

下面这部分代码,根据压缩包里的strings.xml和public.xml可以分析run()返回值为0时,提示成功的字符
[Java] 纯文本查看 复制代码
public void handleMessage(Message arg5) {
        dn.b(dn.a());
        int v2 = -65536;
        this.a.b.setEnabled(true);
        switch(arg5.what) {
            case 0: {
                goto label_10;
            }
            case 1: {
                goto label_27;
            }
            case 2: {
                goto label_51;
            }
            case 3: {
                goto label_66;
            }
        }
        return;
    label_66:
        this.a.a.setTextColor(v2);
        TextView v1 = this.a.a;
        int v0 = Main.a(this.a).nextBoolean() ? 2130968582 : 2130968581;
        v1.setText(v0);
        return;
        try {
        label_51:
            this.a.a.setTextColor(-65536);
        }
        catch(Exception v0_1) {
            this.a.a.setTextColor(-7829368);
        }

        this.a.a.setText(2130968580);
        return;
    label_10:
        this.a.a.setTextColor(-16776961);
        try {
            this.a.a.setText(103 / arg5.what);
        }
        catch(Exception v0_1) {
            this.a.a.setText(2130968586);
        }
        return;
    label_27:
        this.a.a.setTextColor(v2);
        switch(Main.a(this.a).nextInt(3)) {
            case 0: {
                goto label_36;
            }
            case 1: {
                goto label_41;
            }
            case 2: {
                goto label_46;
            }
        }
        return;
    label_36:
        this.a.a.setText(2130968583);
        return;
    label_41:
        this.a.a.setText(2130968585);
        return;
    label_46:
        this.a.a.setText(2130968584);
    }

下面的run()函数为关键点,只要返回0即可,分析逻辑和上面那个CTF很类似
[Java] 纯文本查看 复制代码
b(a arg1, Handler arg2, String arg3) {
        this.d = arg1;
        this.b = arg2;
        this.input = arg3;
        super();
    }

    public void run() {
        int v0_6;
        String v0_5;
        String v1_5;
        byte[] v2_3;
        Cipher v1_1;
        MessageDigest v0_3;
        String str;
        dn.b(dn.a());
        MessageDigest v1 = null;
        if(Build$VERSION.SDK_INT >= 10 && (Debug.isDebuggerConnected())) {
            this.b.sendEmptyMessage(1);
            return;
        }

        try {
            str = new e().a(this.input);  //a函数的主要目的,在莫尔斯码表中置换
        }
        catch(Exception v0) {
            this.b.sendEmptyMessage(3);
            return;
        }

        try {
            if(str.equals("sos")) {
                this.b.sendEmptyMessage(2);
                return;
            }

            CRC32 v0_1 = new CRC32();  //crc加密
            v0_1.update(str.getBytes());
            v0_1.getValue();
            str.hashCode();
            try {
                v0_3 = MessageDigest.getInstance("sha1"); //sha1加密
            }
            catch(NoSuchAlgorithmException v0_2) {
                v0_2.printStackTrace();
                v0_3 = v1;
            }

            try {
                v1_1 = Cipher.getInstance("AES");   
            }
            catch(NoSuchPaddingException v0_4) {
                v0_4.printStackTrace();
                return;
            }
            catch(NoSuchAlgorithmException v2) {
                v2.printStackTrace();
            }

            if(!b.a && v1_1 == null) {
                throw new AssertionError();
            }
        }
        catch(Exception v0) {
            goto label_26;
        }

        int v2_1 = 2;
        try {
            v1_1.init(v2_1, new SecretKeySpec(Base64.decode("GXiQHT1CZ2elMzwpvvAoPA==".getBytes(), 0), "AES")); //AES设置key
            goto label_69;
        }
        catch(Exception v0) {
        }
        catch(InvalidKeyException v2_2) {
        label_69:
            try {
                new byte[0];
                try {
                    v2_3 = v1_1.doFinal(Base64.decode("hjdsUjIT5je69WXIZP7Kzw==".getBytes("UTf-8"), 0));  //AES解密,值固定
                    goto label_78;
                }
                catch(UnsupportedEncodingException v1_2) {
                    try {
                        v1_2.printStackTrace();
                    label_78:
                        String v6 = new String(v2_3);   //上面AES解密的
                        v0_3.update(new byte[]{127});
                        v0_3.update(str.getBytes());   
                        v0_3.update(new byte[]{1});
                    }
                    catch(Exception v0) {
                        goto label_26;
                    }
                }
                catch(BadPaddingException v1_3) {
                    goto label_78;
                }
                catch(IllegalBlockSizeException v1_4) {
                    goto label_78;
                }
            }
            catch(Exception v0) {
                goto label_26;
            }

            try {
                v1_5 = new String(Base64.encode(v0_3.digest(), 0));  //
                goto label_99;
            }
            catch(Exception v0) {
                try {
                    v0.printStackTrace();
                    return;
                label_99:
                    if(!str.equals(v6)) {
                        goto label_190;
                    }
                    else if(Arrays.equals(v1_5.getBytes(), "2398lj2n".getBytes())) {
                        this.b.sendEmptyMessage(0);
                        return;
                    }
                    else {
                        v0_5 = "234";
                    }

                    goto label_117;
                }
                catch(Exception v0) {
                    goto label_26;
                }
            }

        label_190:
            v0_5 = v1_5;
            try {
            label_117:
                if(v0_5.equals("lsdf==")) {
                    this.b.sendEmptyMessage(0);
                    return;
                }

                char[] v1_6 = str.toCharArray();
                v0_6 = str.substring(0, 2).hashCode();
                if(v0_6 > 3904) {
                    this.b.sendEmptyMessage(4);
                    return;
                }

                if(v0_6 == 3618) {
                    if(v1_6[0] + v1_6[1] != 168) {
                        goto label_178;
                    }

                    do {
                    label_144:
                        byte[] v5_1 = e.class.getAnnotation(f.class).a() + a.class.getAnnotation(f.class).a().getBytes();
                        if(v1_6.length - 2 == v5_1.length) {
                            v0_6 = 0;
                            while(true) {
                                if(v0_6 >= v5_1.length) {
                                    goto label_188;
                                }
                                else if(v1_6[v0_6 + 2] != v5_1[v0_6]) {
                                    v0_6 = 0;
                                }
                                else {
                                    ++v0_6;
                                    continue;
                                }

                                goto label_170;
                            }
                        }

                        goto label_177;
                    }
                    while(true);
                }

                goto label_178;
            }
            catch(Exception v0) {
                goto label_26;
            }

        label_188:
            v0_6 = 1;
            try {
            label_170:
                if(v0_6 != 0) {
                    this.b.sendEmptyMessage(0);
                    return;
                }

            label_177:
                if(v2_3 == null) {
                    goto label_144;
                }

            label_178:
                this.b.sendEmptyMessage(1);
            }
            catch(Exception v0) {
            label_26:
                this.b.sendEmptyMessage(1);
            }
        }
    }

只有为这个的时候this.b.sendEmptyMessage(0);才会提示成功, label_188: ---label_117:---label_190:,跳转这三个点才能成功,
[Java] 纯文本查看 复制代码
 label_190:
            v0_5 = v1_5;
            try {
            label_117:
                if(v0_5.equals("lsdf==")) {
                    this.b.sendEmptyMessage(0);
                    return;
                }

[Java] 纯文本查看 复制代码
 v0_3.update(new byte[]{127});v0_3.update(str.getBytes());
v0_3.update(new byte[]{1});
v1_5 = new String(Base64.encode(v0_3.digest(), 0));
v0_5 = v1_5;

由于前面对v0_3的处理,导致不能相等,所以只剩下label_170:这个独苗,然后看可以谁跳转到label_170:
[Java] 纯文本查看 复制代码
  char[] v1_6 = str.toCharArray();
                v0_6 = str.substring(0, 2).hashCode();
                if(v0_6 > 3904) {
                    this.b.sendEmptyMessage(4);
                    return;
                }

                if(v0_6 == 3618) {
                    if(v1_6[0] + v1_6[1] != 168) {
                        goto label_178;
                    }

                    do {
                    label_144:
                        byte[] v5_1 = e.class.getAnnotation(f.class).a() + a.class.getAnnotation(f.class).a().getBytes();
                        if(v1_6.length - 2 == v5_1.length) {
                            v0_6 = 0;
                            while(true) {
                                if(v0_6 >= v5_1.length) {
                                    goto label_188;
                                }
                                else if(v1_6[v0_6 + 2] != v5_1[v0_6]) {
                                    v0_6 = 0;
                                }
                                else {
                                    ++v0_6;
                                    continue;
                                }

                                goto label_170;
                            }
                        }

                        goto label_177;
                    }
                    while(true);
                }

                goto label_178;
            }

分析可知,v0_6 == 3618 和 v1_6[0] + v1_6[1] = 168必须同时成立,v0_6 = str.substring(0, 2).hashCode();,由于前面置换表只有小写字母和数字,所以可以直接遍历
[C] 纯文本查看 复制代码
#include <stdio.h>
#include <stdlib.h>


int main()
{
        int arry[] = { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122 };
        int n = sizeof(arry) / sizeof(arry[0]);
        for (int i = 0; i < n; i++)
        {
                for (int j = 0; j < n; j++)
                {
                        if ((arry[i] * 31 + arry[j]) == 3618)
                        {
                                printf("%d----%d\n", arry[i],arry[j]);
                        }
                }
        }
        system("pause");
        return 0;
}

c语言很垃圾,只能写这个了.........结果有两个113----115和115----53,只有后面的符合要求,转换成acsll为s5,接着往下看
[Java] 纯文本查看 复制代码
 byte[] v5_1 = e.class.getAnnotation(f.class).a() + a.class.getAnnotation(f.class).a().getBytes(); //获取后面四个字符
                        if(v1_6.length - 2 == v5_1.length) {
                            v0_6 = 0;
                            while(true) {
                                if(v0_6 >= v5_1.length) {
                                    goto label_188;
                                }
                                else if(v1_6[v0_6 + 2] != v5_1[v0_6]) {
                                    v0_6 = 0;
                                }
                                else {
                                    ++v0_6;
                                    continue;
                                }

                                goto label_170;
                            }
                        }

下面就可以看出来是比较了,要长度相等,字符相等,所以后面的为7e1p,加上前面的s5为s57e1p,然后再置换一下就行了,结果为... _____ ____. . ..___ .__.
贴下java的分析代码,很垃圾····························
[Java] 纯文本查看 复制代码
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class aestest {
        
        public static void main(String[] args) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException  {
                byte[] v2_3;
                Cipher v1_1;
                String v5 = "s57e1p";
                String v1_5;
                int v0_6;
                MessageDigest v0_3;
                char[] v1_6 = v5.toCharArray();
                v0_3 = MessageDigest.getInstance("sha1");
                v1_1 = Cipher.getInstance("AES");
                Decoder decoder = Base64.getDecoder();
                Encoder encode = Base64.getEncoder();
                v1_1.init(2, new SecretKeySpec(decoder.decode("GXiQHT1CZ2elMzwpvvAoPA==".getBytes()), "AES"));
                v2_3 = v1_1.doFinal(decoder.decode("hjdsUjIT5je69WXIZP7Kzw==".getBytes("UTf-8")));
                System.out.println(v2_3);
                v0_3.update(new byte[]{127});
                v0_3.update(v5.getBytes());
                v0_3.update(new byte[]{1});
                String v6 = new String(v2_3);
                v1_5 = new String(encode.encode(v0_3.digest()));
                System.out.println(v1_5);
                v0_6 = v5.substring(0, 2).hashCode();
                System.out.println(v0_6);
          }        
}

CTF.zip

1.62 MB, 下载次数: 15, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 6威望 +1 吾爱币 +13 热心值 +6 收起 理由
poisonbcat + 1 + 1 谢谢@Thanks!
科技技能 + 1 热心回复!
cxp521 + 1 + 1 谢谢@Thanks!
xwzj20170829 + 1 + 1 谢谢@Thanks!
bolipapadu + 1 + 1 用心讨论,共获提升!
Sound + 1 + 9 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

C_Ryan 发表于 2018-10-4 03:07
钉钉CTF这一道,还有一种情况没有分析,就是当case5时候v4 = v5.length,会是一个另一个截然不同的分析方向,大致就是v4先加累加到7,然后case5后v7再累加到7,这就需要对输入的字符串有要求了,会进行些亦或比较操作,这个flag答案为4ndr01d。

点评

谢谢提醒,已经更新~  发表于 2018-10-12 20:38
 楼主| Anonymous、 发表于 2018-10-4 09:07
C_Ryan 发表于 2018-10-4 03:07
钉钉CTF这一道,还有一种情况没有分析,就是当case5时候v4 = v5.length,会是一个另一个截然不同的分析方向 ...

666,这么多答案吗....当时分析出一个,就没再仔细看了
sqln0324 发表于 2018-9-30 16:56
90182si 发表于 2018-9-30 17:17
看不懂系列,哈哈哈
hechenpi 发表于 2018-9-30 18:22
看不懂系列, 不知所云
多瑙河下 发表于 2018-9-30 19:18

看不懂系列, 不知所云
雨落丶千寒 发表于 2018-9-30 19:19
向大佬致敬
kanxue2018 发表于 2018-9-30 20:13


感谢楼主分享,支持一下!
onmiuncai 发表于 2018-9-30 20:17
请问下LZ dump后的odex怎么修复,是直接用baksmali -x 转dex 还是需要手动修复什么?
linuxprobe 发表于 2018-9-30 21:09
你即便把它全部逆向了又能怎么样呢?
kk1212 发表于 2018-9-30 21:41
能把这几个学会也挺厉害的
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 22:43

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表