攻防世界XCTF-MOBILE入门9题解题报告

说实话,这几天被逆向的恐怖思维,深深的吓着了,真的要抱腿腿了,叫我失眠了好几晚,我觉得逆向分析是CTF中最难的,求腿腿指点迷津啊,我决定不闷头自己研究了。

感谢大佬提供的帮助,让我有了继续刷下去的勇气。至此,XCTF 6大类的入门题做完了。

攻防世界XCFT刷题信息汇总如下:攻防世界XCTF黑客笔记刷题记录

第一题:app1

img

解题报告:在MUMU模拟器中安装运行

img

通过dex2jar和jd-gui,逆向出class文件,然后直接进Main函数

img

在BuildConfig.class文件中可以轻松的拿到解密的关键字段

img

通过简单的Python编程,成功拿到flag

img

第二题:app2

img

解题报告:在MUMU模拟器中安装运行

img

在JEB中打开,JEB真的没有排面啊

img

进入SecondActivity类中,寻找关键方法onCreate()

img

使用IDA打开Lib库中的.so文件,找到关键函数doRawData的实现

img

大概的意思就是使用AES对咱们的字符串进行加密,使用的密钥是thisisatestkey==,恰好使得结果等于VEIzd/V2UPYNdn/bxH3Xig==就可以了。

img

输入aimage/tencent结果发现还是腾讯等你哟 Waiting for you,被戏耍了,并不是正确的flag

img

于是通过dex2jar和jd-gui,逆向出class文件,发现第一个FileDataActivity类,里面也有一个奇怪的加密字符串

img

将上面的加密结果改成9YuQ2dk8CSaCe7DTAmaqAA== ,再次运行,成功拿到flag

img

第三题:app3

img

解题报告:

下载附件,发现是.ab文件,需要转换为.tar文件

img

解压.tar这个宝藏文件,得到了一个apk安装包

img

把apk拖进jeb,进入主程序,发现可疑处

img

第一步:分析这个类A

img

第二步:分析这个类B

img

解密得到关键密码:ae56f99

img

查看一下加密的版本3.4.0

img

去找一下3.4.0版本,然后编译安装一下sqlcipher,make不成功

https://github.com/sqlcipher/sqlcipher/releases

于是用windows版本的3.0.1编译好的可执行程序,只要大版本一样就行了

https://github.com/CovenantEyes/sqlcipher-windows/releases

img

sqlite> PRAGMA key = "ae56f99";
sqlite> ATTACH DATABASE "ailx10.db" AS plaintext KEY "";
sqlite> SELECT sqlcipher_export("plaintext");
sqlite> DETACH DATABASE plaintext;

最后,解密这个Base64编码就搞定了

img

第四题:easy-apk

img

解题报告:

安装运行,看不出来啥

img

扔进JEB里面,看上去逻辑很简单的亚子。

img

核心逻辑就是怎么逆向计算Base64New

img

发现这个JEB反编译出来或的操作很难读啊,只好转到dex2jar来试一试

img

反编译出来的结果让我心碎,一毛一样的亚,菜就是原罪,只好硬着皮头逆向运算了=。=

img

这个或运算太骚了吧,这玩意咋逆运算啊?失眠了。这题最难的地方就是异或怎么处理,最后来一个逐项暴力破解版,大约5秒,效果极佳。这是Base64的通用做法,记好哟~

img

最后一部分的=号暴力破解:大约1秒,凑一起就完事了。

img

最后我花了一个草图,实际上这题就是Base64换了一个表,通过不停的或运算,实际上还是那一堆数字,0101并没有发生任何改变,因此直接写一个Base64的逆过程就完事了。

img

逆向核心代码:

package c4;

public class Base64New {
    private static char[] Base64ByteToStr = null;
    private static final int RANGE = 255;
    private static byte[] StrToBase64Byte;

    static {
        Base64New.Base64ByteToStr = new char[]{'v', 'w', 'x', 'r', 's', 't', 'u', 'o', 'p', 'q', '3', '4', '5', '6', '7', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'y', 'z', '0', '1', '2', 'P', 'Q', 'R', 'S', 'T', 'K', 'L', 'M', 'N', 'O', 'Z', 'a', 'b', 'c', 'd', 'U', 'V', 'W', 'X', 'Y', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', '8', '9', '+', '/'};
        Base64New.StrToBase64Byte = new byte[128];
    }

    public Base64New() {
        super();
    }

    public byte getIndex(char x)
    {
        byte index = -1;
        String talbe = new String(Base64New.Base64ByteToStr);
        if(x != '=') {
            index = (byte) talbe.indexOf(x);
        }
        else {
            index = 0;
        }
        return index;
    }

    public void Base64Decode() {
        String enflag = "5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=";
        String flag = "";
        String flag_temp = "";
        for(int i = 0;i < enflag.length();i+=4)
        {
            String enf = enflag.substring(i,i+4);
            byte flag1 = (byte)(((getIndex(enf.charAt(0)) & 255) << 2 | ((getIndex(enf.charAt(1)) & 255) >>> 4)));
            byte flag2 = (byte)(((getIndex(enf.charAt(1)) & 255) << 4 | ((getIndex(enf.charAt(2)) & 255) >>> 2)));
            byte flag3 = (byte)(((getIndex(enf.charAt(2)) & 255) << 6 | ((getIndex(enf.charAt(3)) & 255))));

            flag_temp = "" + (char)flag1 + (char)flag2 + (char)flag3;
            flag += flag_temp;
        }
        System.out.println(flag);
        return;
    }

    public String Base64Encode(byte[] arg9) {
        int v7 = 3;
        StringBuilder v3 = new StringBuilder();
        int v1;
        for(v1 = 0; v1 <= arg9.length - 1; v1 += 3) {
            byte[] v0 = new byte[4];
            byte v4 = 0;
            int v2;
            for(v2 = 0; v2 <= 2; ++v2) {
                if(v1 + v2 <= arg9.length - 1) {
                    v0[v2] = (byte)((arg9[v1 + v2] & 255) >>> (v2 * 2 + 2) | v4);
                    v4 = ((byte)(((arg9[v1 + v2] & 255) << (2 - v2) * 2 + 2 & 255) >>> 2));
                }
                else {
                    v0[v2] = v4;
                    v4 = 64;
                }
            }

            v0[v7] = v4;
            for(v2 = 0; v2 <= v7; ++v2) {
                if(v0[v2] <= 63) {
                    v3.append(Base64New.Base64ByteToStr[v0[v2]]);
                }
                else {
                    v3.append('=');
                }
            }
        }
        return v3.toString();
    }
}

第五题:easy-java

img

解题报告:

img

拖进JEB中找到核心逻辑,这个a方法是关键

img

进入a方法里面,发现调用的是b方法,可以看到提交的字符格式了吧。然后就是重头戏了,有两个类a和b,经过一些列的计算,最后结果等于wigwrkaugala就可以了。

flag{      }

img

整体思路:这是一个错误思路,读者可以直接忽略,为了记录我的愚蠢的。

  • 首先用第一个参数(flag),调用B类的a方法,将结果传递给A类的a方法,写入v3中
  • 然后用B类的b方法对25取余数,得到v6
  • 如果v6大于等于1,并且大于v1,那么v1++,否则v0++
  • 往复循环,处理完整个flag

B类的a方法:B类的b中包含flag的话,找到下标数字,然后在B类的a中到找到相同的数字,输出移动了几次。比如字母a,在B类的b中的下标是0,在B类的a中0的位置是10,那么输出10

A类的a方法:A类的a中找到这个参数的下标,然后输出A类的b中的该下标的字母。比如10在A类的a的下标是14,那么输出A类的b[14],也就是输出字母n

然后我以为我把所有的字母从明文到密文的转换,搞成一个转换字典,然后根据密文去反查明文,岂不是美滋滋,事实证明这个思路走不通。因为明文aa映射到密码并不是xx,而是xy,导致了这个思路破碎,只能硬着皮头反逻辑,这个没有经过老师点拨训练,真的很痛苦。

偷个懒,来一次暴力破解,

flag如果是4位,需要尝试45万次

flag如果是8位,需要尝试2000亿次

额,实际flag是12位,暴力美学,一点都不美丽了,弃坑,CTF没有暴力破解。

img

第二次解题思路:读者继续从这里开始。

先搞懂正向计算过程,再去分析逆向计算过程。

  • 正向计算0层架构:调用B的a方法,再调用A的a方法
  • B的a方法:参数在B的b中索引,在B的a中索引,再调用B的c方法
  • B的c方法:B的a数组,B的b数组循环移动一位,123变成231
  • A的a方法:参数在A的a中索引,再调用A的b中索引值

逆向过程如下:

  • A的a方法:参数在A的b中索引,在A的a中索引值
  • B的a方法:参数在B的a中索引值,在B的b中索引值,再调用B的c方法
  • B的c方法:和正向操作一样,保持操作的表是一样的

那么现在思路清晰了,就很简单了:

img

其中A的a方法的逆运算如下:

img

B的a方法逆运算如下:

img

第六题:easy-jni

img

解题报告:

img

仍进JEB中,发现问题的关键是:

  • new a() 这个A类的a()方法,对输入进行处理
  • native中的ncheack()方法,检测是否相等

img

关键问题1:对类A对a方法进行分析

img

关键问题2:解压apk包,把lib下的.so文件拖进IDA32中,对库函数分析

img

正向思路整理:

  • 对输入的flag进行Base64换表计算B64Encode
  • 对输入的B64Encode进行变换得到加密的flag

逆向思路整理:

  • 对加密的flag进行逆向变换得到B64Encode
  • 对B64Encode进行Decode计算得到flag

编程就非常简单了:

img

第一步:交换操作

img

第二步:Base64Decode操作

img

第七题:easy-so

img

解题报告:

img

扔进JEB中,发现只要经过cyberpeace.CheckString,计算结果等于1就拿到flag

img

而最关键的cyberpeace.CheckString在lib库中,将apk解压,把里面的.so库文件拖到IDA中,发现逻辑非常简单,和上面一题的交换部分一样。

img

直接利用上一题的代码改改,就拿到flag,有点送分的意思。

img

第八题:Ph0en1x-100

img

解题报告:

img

仍进JEB中,需要注意3个地方,一个一个分析

img

第一个注意的地方:getSecret

发现等号两边都要经过这个消息摘要函数的计算,那么只要比较输入值相等就可以了。

img

第二个注意的地方:getFlag

img

第三个注意的地方:encrypt

img

最后,很容易的写出逆向代码,直接拿到flag

img

第九题:RememberOther

img

解题报告:

img

扔进JEB中看看里面的逻辑:

img

进入checkSN,拿到flag有2种选择,要么什么也不要输入,要么输入的用户名经过消息摘要算法等于注册码,所以我们什么也不输入就能拿到flag

img

在App里面点击注册,一串md5一闪而过,在配置文件里面,咱们可以找到它。

img

找一个在线MD5解密网站,扔进去拿到flag:

img

结合令人无语的脑洞,末尾加一个“ANDROID”字符串,拼成最终的flag

YOU_KNOW_ANDROID

img

至此,基础题目都做完了,撒花花~


关于黑客&网络安全学习指南

学好 网络安全不论是就业还是做副业赚钱都不错,但要学会 网络安全 还是要有一个学习规划。最后给大家分享一份全套的 网络安全学习资料,给那些想学习网络安全的小伙伴们一点帮助!

内容涵盖了网络安全法学习、网络安全运营等保测评、渗透测试基础、漏洞详解、计算机基础等教程,带你从零基础系统性的学好网络安全。

1.学习路线图
在这里插入图片描述

攻击和防守要学的东西也不少,具体要学的东西我都写在了上面的路线图,如果你能学完它们,你去就业和接私活完全没有问题。

2.网络安全视频教程600集和配套电子书
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

在这里插入图片描述

温馨提示:篇幅有限,已打包文件夹,获取方式在:CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

3.技术文档
技术文档也是我自己整理的,包括我参加大型网安行动、CTF和挖SRC漏洞的经验和技术要点,电子书也有200多本,由于内容的敏感性,我就不一一展示了。
在这里插入图片描述

4.工具包、面试题和源码
“工欲善其事必先利其器”我为大家总结出了最受欢迎的几十款款黑客工具。涉及范围主要集中在 信息收集、Android黑客工具、自动化工具、网络钓鱼等,感兴趣的同学不容错过。
在这里插入图片描述

还有我视频里讲的案例源码和对应的工具包,需要的话也可以拿走。

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取:CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

最后就是我这几年整理的网安方面的面试题,如果你是要找网安方面的工作,它们绝对能帮你大忙。

这些题目都是大家在面试深信服、奇安信、腾讯或者其它大厂面试时经常遇到的,如果大家有好的题目或者好的见解欢迎分享。

参考解析:深信服官网、奇安信官网、Freebuf、csdn等

内容特点:条理清晰,含图像化表示更加易懂。

内容概要:包括 内网、操作系统、协议、渗透测试、安服、漏洞、注入、XSS、CSRF、SSRF、文件上传、文件下载、文件包含、XXE、逻辑漏洞、工具、SQLmap、NMAP、BP、MSF…
在这里插入图片描述

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取:CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

  • 24
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值