首页
社区
课程
招聘
[原创]【2019看雪CTF】Q1赛季 第二题变形金钢 WP
2019-3-23 12:59 5299

[原创]【2019看雪CTF】Q1赛季 第二题变形金钢 WP

2019-3-23 12:59
5299

【2019看雪CTF】Q1赛季 第二题变形金钢 WP

此题是安卓题,开始在java层看到这样的校验代码:

class MyHandler extends Handler {
        WeakReference mWeakReference;

        public MyHandler(MainActivity arg2) {
            super();
            this.mWeakReference = new WeakReference(arg2);
        }

        public void handleMessage(Message arg6) {
            String v6_1;
            StringBuilder v1;
            super.handleMessage(arg6);
            Object v0 = this.mWeakReference.get();
            if(v0 == null) {
                return;
            }

            switch(arg6.what) {
                case 0: {
                    Object v6 = arg6.obj;
                    if(!TextUtils.isEmpty(((CharSequence)v6))) {
                        v1 = new StringBuilder();
                        int v3;
                        for(v3 = 0; v3 < ((String)v6).length() / 2; ++v3) {
                            v1.append(((String)v6).charAt(v3));
                        }

                        v6_1 = v1.toString();
                    }

                    v1 = new StringBuilder();
                    v1.append("flag{");
                    v1.append(v6_1);
                    v1.append("}");
                    Toast.makeText(((Context)v0), v1.toString(), 1).show();
                    break;
                }
                case 1: {
                    Toast.makeText(((Context)v0), "登录失败", 1).show();
                    break;
                }
                default: {
                    break;
                }
            }

            ((MainActivity)v0).login.setEnabled(true);
        }
    }



 private void login(String arg3, String arg4, Handler arg5) {
        Toast.makeText(((Context)this), "登录中。。。", 1).show();
        MainActivity.runnable = new Runnable(arg4, arg3, arg5) {
            public void run() {
                Message v0 = Message.obtain();
                StringBuilder v1 = new StringBuilder(this.val$password);
                if(this.val$name.equals(v1.reverse().toString())) {
                    v0.obj = v1.toString();
                }
                else {
                    v0.what = 1;
                }

                this.val$handler.sendMessage(v0);
            }
        };
        MainActivity.cachedThreadPool.execute(MainActivity.runnable);
    }

似乎password就是name的逆序,但是不对。。。卡了好一会,后来回头来看才发现猫腻所在。
public class MainActivity extends AppCompiatActivity {中的AppCompiatActivity是自写类,并非系统中的AppCompatActivity。其主要代码如下:

    static {
        System.loadLibrary("oo000oo");
    }

    private static byte[] dec(byte[] arg4, byte[] arg5) {
        arg5 = Base64.decode(arg5, 0);
        SecretKeySpec v0 = new SecretKeySpec(arg4, "AES");
        try {
            ((Key)v0).getEncoded();
            PrintStream v4_1 = System.out;
            v4_1.println("getFormat = " + ((Key)v0).getFormat() + " ; getAlgorithm = " + ((Key)v0).getAlgorithm());
            Cipher v4_2 = Cipher.getInstance("AES/CFB/PKCS5Padding");
            PrintStream v1_1 = System.out;
            v1_1.println("getBlockSize = " + v4_2.getBlockSize());
            v4_2.init(2, ((Key)v0), new IvParameterSpec(new byte[v4_2.getBlockSize()]));
            return v4_2.doFinal(arg5);
        }
        catch(Throwable v4) {
            v4.printStackTrace();
            return null;
        }
    }


    protected native boolean eq(String arg1) {
    }

    protected void onStart() {
        super.onStart();
        this.login = this.findViewById(2131165260);
        this.login.setOnClickListener(new View$OnClickListener() {
            public void onClick(View arg5) {
                AppCompiatActivity.this.mName = AppCompiatActivity.this.name.getText().toString();
                AppCompiatActivity.this.mPassword = AppCompiatActivity.this.password.getText().toString();
                if(!TextUtils.isEmpty(AppCompiatActivity.this.mName)) {
                    if(TextUtils.isEmpty(AppCompiatActivity.this.mPassword)) {
                    }
                    else {
                        int v1 = 0;
                        AppCompiatActivity.this.login.setEnabled(false);
                        if(AppCompiatActivity.this.eq(AppCompiatActivity.this.mPassword)) {
                            byte[] v5 = AppCompiatActivity.this.mPassword.getBytes();
                            int v3 = 24;
                            if(v5.length != v3) {
                                byte[] v2 = new byte[v3];
                                while(v1 < v2.length) {
                                    byte v3_1 = v1 < v5.length ? v5[v1] : ((byte)v1);
                                    v2[v1] = v3_1;
                                    ++v1;
                                }

                                v5 = v2;
                            }

                            v5 = AppCompiatActivity.dec(v5, "2ggdrsLgM7iPNYPQrD58Rg==".getBytes());
                            AppCompiatActivity v1_1 = AppCompiatActivity.this;
                            StringBuilder v2_1 = new StringBuilder();
                            v2_1.append("flag{");
                            v2_1.append(new String(v5));
                            v2_1.append("}");
                            Toast.makeText(((Context)v1_1), v2_1.toString(), 1).show();
                        }
                        else {
                            Toast.makeText(AppCompiatActivity.this, "error", 1).show();
                        }

                        return;
                    }
                }

                Toast.makeText(AppCompiatActivity.this, "用户名或密码为空", 1).show();
            }
        });
        this.name = this.findViewById(2131165265);
        this.name.setEnabled(false);
        this.password = this.findViewById(2131165277);
    }

从以上代码可以看出,此app还有个native库,加载了oo000oo。输入通过native函数eq完成校验,最后以输入为密钥对flag进行AES解密。

 

函数eq并没有注册导出,在JNI_OnLoad中手动注册。校验算法似乎是魔改的RC4加改了表的base64编码,没细看。直接将校验串解码,动态调试,用解码后的结果替换输入串,在偏移0x9F6处下断,从r11寄存器获取解密结果,结果为fu0kzHp2aqtZAuY6,输入app,正确显示。


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞1
打赏
分享
最新回复 (2)
雪    币: 835
活跃值: (1222)
能力值: ( LV7,RANK:118 )
在线值:
发帖
回帖
粉丝
For@* 2019-3-27 10:19
2
0
求大佬分析用到的工具名称
雪    币: 13713
活跃值: (2851)
能力值: ( LV15,RANK:2663 )
在线值:
发帖
回帖
粉丝
poyoten 22 2019-3-27 12:27
3
0
jeb  ida
游客
登录 | 注册 方可回帖
返回