吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3437|回复: 21
上一主题 下一主题
收起左侧

[Android CTF] 学破解第207天,《攻防世界 easy_java》学习

[复制链接]
跳转到指定楼层
楼主
小菜鸟一枚 发表于 2023-6-3 17:58 回帖奖励

前言:

  坛友们,年轻就是资本,和我一起逆天改命吧,我的学习过程全部记录及学习资源:https://www.52pojie.cn/thread-1791705-1-1.html

立帖为证!--------记录学习的点点滴滴

0x1 简单分析

  1.下载题目:攻防世界easy_java:https://adworld.xctf.org.cn/media/file/task/3f06e60ded5e44e3b0f4c47020cbcb3c.apk

  2.jadx反编译看源码:

package com.a.easyjava;

import android.os.Bundle;
import android.support.v7.app.c;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import java.util.Timer;
import java.util.TimerTask;

/* loaded from: classes.dex */
public class MainActivity extends c {
    private static char a(String str, b bVar, a aVar) {
        return aVar.a(bVar.a(str));
    }

    /* JADX INFO: Access modifiers changed from: private */
    public static Boolean b(String str) {
        if (str.startsWith("flag{") && str.endsWith("}")) {
            String substring = str.substring(5, str.length() - 1);
            b bVar = new b(2);
            a aVar = new a(3);
            StringBuilder sb = new StringBuilder();
            int i = 0;
            for (int i2 = 0; i2 < substring.length(); i2++) {
                sb.append(a(substring.charAt(i2) + "", bVar, aVar));
                Integer valueOf = Integer.valueOf(bVar.b().intValue() / 25);
                if (valueOf.intValue() > i && valueOf.intValue() >= 1) {
                    i++;
                }
            }
            return Boolean.valueOf(sb.toString().equals("wigwrkaugala"));
        }
        return false;
    }

    /* JADX INFO: Access modifiers changed from: protected */
    @Override // android.support.v7.app.c, android.support.v4.a.i, android.support.v4.a.aa, android.app.Activity
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { // from class: com.a.easyjava.MainActivity.1
            @Override // android.view.View.OnClickListener
            public void onClick(View view) {
                if (MainActivity.b(((EditText) ((MainActivity) this).findViewById(R.id.edit)).getText().toString()).booleanValue()) {
                    Toast.makeText(this, "You are right!", 1).show();
                    return;
                }
                Toast.makeText(this, "You are wrong! Bye~", 1).show();
                new Timer().schedule(new TimerTask() { // from class: com.a.easyjava.MainActivity.1.1
                    @Override // java.util.TimerTask, java.lang.Runnable
                    public void run() {
                        System.exit(1);
                    }
                }, 2000L);
            }
        });
    }
}

  3.先看onCreate函数里面的onclick事件,很明显必须要让这个if语句为true,这句代码意思就是拿我们输入的文本作为b函数的参数去执行,booleanValue()函数用于返回Boolean对象对应的布尔原始值。

if (MainActivity.b(((EditText) ((MainActivity) this).findViewById(R.id.edit)).getText().toString()).booleanValue()) {
                    Toast.makeText(this, "You are right!", 1).show();
                    return;
                }

  4.接下来就看看b函数

1)首先判断输入的字符串是不是flag{开头, }结尾的

2)然后调用substring去掉开头和结尾,接着new两个对象,如果容易搞混可以重命名类和函数名

3)再看for循环,调用a类对象取里面的一个字符串追加到sb,valueOf=b类对象的值除以25,然后i++

4)最后比较sb是否等于wigwrkaugala

https://s1.ax1x.com/2023/06/03/pCpJgu8.png

0x2 动态调试

  1.光看我们不是很容易看出每句代码的作用,把程序拖进jeb,输入flag{123456}点击,先看看 b bVar = new b(2);这一句执行后bVar的返回值,这看的太不方便了。

https://s1.ax1x.com/2023/06/03/pCpYWM6.png

  2.直接把a类和b类拖进eclipse改造,再执行相同代码看看,打断点看,a类就是从下标3开始开始取值添加,最后再添加0,1,2下标的值进入ArrayList,b类和a类类似,所以初始化后两个对象的a值如下所示。

A类中
c = {7, 14, 16, 21, 4, 24, 25, 20, 5, 15, 9, 17, 6, 13, 3, 18, 12, 10, 19, 0, 22, 2, 11, 23, 1, 8};
a=[21, 4, 24, 25, 20, 5, 15, 9, 17, 6, 13, 3, 18, 12, 10, 19, 0, 22, 2, 11, 23, 1, 8, 7, 14, 16]

B类中
c = {8, 25, 17, 23, 7, 22, 1, 16, 6, 9, 21, 0, 15, 5, 10, 18, 2, 24, 4, 11, 3, 14, 19, 12, 20, 13};
a=[17, 23, 7, 22, 1, 16, 6, 9, 21, 0, 15, 5, 10, 18, 2, 24, 4, 11, 3, 14, 19, 12, 20, 13, 8, 25]

https://s1.ax1x.com/2023/06/03/pCptaYd.png

  3.再看看for循环那里,同样把代码粘贴进去,调试可以到从我输入的字符串123456中取第一个字符,再把b对象和a对象一起作为参数调用a方法,a方法中直接一句aVar.a(bVar.a(str)),再去看B类的a方法,查看两个函数意思可知我们输入的内容应该为字母,去字符串b中查找指定位置,得到下标。

contains() 方法用于判断字符串中是否包含指定的字符或字符串。

toLowerCase() 方法将字符串转换为小写。

get() 方法通过索引值获取动态数组中的元素。

然后再看for循环里面遍历a数组中的元素,等于刚刚得到的下标时,赋值给i,最后返回i。

 for (int i2 = 0; i2 < a.size() - 1; i2++) {
                if (a.get(i2) == valueOf) {
                    i = Integer.valueOf(i2);

返回之前还去执行a函数,这个方法就是将a数组的第一个放到最后面(先删再加),将字符串b第一个字符放到最后面(先加在末尾,然后截取第二位到最后一位),之后d+1

 int intValue = a.get(0);
        a.remove(0);
        a.add(Integer.valueOf(intValue));
        b += "" + b.charAt(0);
        b = b.substring(1, 27);
        Integer num = d;
        d = Integer.valueOf(d + 1);

上面的执行完后,i作为参数调用A类的a方法,先判断等不等于-10,也就是说前面我输入123456数字到这里gg了,重来一遍,这次用abcdef来试,这次匹配到i=9,所以正常进入下一个for循环,里面同样是遍历a元素匹配i,得到num2,然后再调用b.charAt根据下标取对应字符返回。返回之前也是去调用a函数,d+1,然后如果d变成了25,a数组就将第一个位置放到最后面(先删再加),然后d重新变成0.

public char a(Integer num) {
        Integer num2 = 0;
        if (num == -10) {
            a();
            return " ".charAt(0);
        }
        for (int i = 0; i < a.size() - 1; i++) {
            if (a.get(i) == num) {
                num2 = Integer.valueOf(i);
            }
        }
        a();
        return b.charAt(num2);

  4.这一块分析完了再回去,就是将A类中b对应下标的元素取出来添加进sb,B类b方法就是直接返回d,小于25就不会触发下面的if,看前面也知道不会循环这么多次(wigwrkaugala的长度决定了)。

 sb.append(a(substring.charAt(i2) + "", bVar, aVar));
             Integer valueOf = Integer.valueOf(bVar.b().intValue() / 25);
             if (valueOf.intValue() > i && valueOf.intValue() >= 1) {
                 i++;
             }

0x3 计算flag

  1.分析完了,接下来就要以wigwrkaugala作为输入,首先把需要的变量定义好:

    public static ArrayList<Integer> A_a = new ArrayList<>();
    static String A_b = "abcdefghijklmnopqrstuvwxyz";
    static Integer A_d = 0;
    //前面分析右移3位后的数据,就是new(3)了之后的值
    Integer[] A_c = {21, 4, 24, 25, 20, 5, 15, 9, 17, 6, 13, 3, 18, 12, 10, 19, 0, 22, 2, 11, 23, 1, 8, 7, 14, 16};

    public static ArrayList<Integer> B_a = new ArrayList<>();
    static String B_b = "abcdefghijklmnopqrstuvwxyz";
    static Integer B_d = 0;
    //前面分析右移2位后的数据,就是new(2)了之后的值
    Integer[] B_c = {17, 23, 7, 22, 1, 16, 6, 9, 21, 0, 15, 5, 10, 18, 2, 24, 4, 11, 3, 14, 19, 12, 20, 13, 8, 25};

  2.接下来就是charAt根据下标查字符,变成idnexOf根据字符串查下标,根据wigwrkaugala长度判断A_c和B_c移动,然后前面是将第一个放到最后一个,这里就要循环向后移位,再将最后一个值set()到最前面。

  3.一个小时后......,代码越写越乱,懵逼了,最后运算结果死活不对,去抄一抄别人的wp得到:

package test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test {

    public static ArrayList<Integer> A_a = new ArrayList<>();
    static String A_b = "abcdefghijklmnopqrstuvwxyz";
    static Integer A_d = 0;
    // 前面分析右移3位后的数据,就是new(3)了之后的值
    static Integer[] A_c = { 21, 4, 24, 25, 20, 5, 15, 9, 17, 6, 13, 3, 18, 12, 10, 19, 0, 22, 2, 11, 23, 1, 8, 7, 14,
            16 };

    public static ArrayList<Integer> B_a = new ArrayList<>();
    static String B_b = "abcdefghijklmnopqrstuvwxyz";
    static Integer B_d = 0;
    // 前面分析右移2位后的数据,就是new(2)了之后的值
    static Integer[] B_c = { 17, 23, 7, 22, 1, 16, 6, 9, 21, 0, 15, 5, 10, 18, 2, 24, 4, 11, 3, 14, 19, 12, 20, 13, 8,
            25 };

    static String str = "wigwrkaugala";

    public static void main(String[] args) {
        String res = "";
        // 将B_a以及B_b推到最终结果的时候
        changeB_c();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(str.length() - 1 - i);
            res += B_char(aInteger(c + ""));
            // 最终res为rckvidivinev 然后将其反转就是答案
        }
        System.out.println("flag{" + new StringBuffer(res).reverse() + "}");
    }

    static void changeB_c() {
        // 这里逆推,B_b,数组最终移动了12位,最后一次移动是结束了的结果,因此退11位就行,
        int length = str.length();
        for (int i = 0; i < length - 1; i++) {
            String s = B_b.charAt(0) + "";
            B_b = B_b.substring(1, B_b.length()) + s;
            int t = B_c[0];
            for (int j = 1; j < B_c.length; j++) {
                B_c[j - 1] = B_c[j];
            }
            B_c[B_c.length - 1] = t;
        }
        List<Integer> list = Arrays.asList(B_c);
        B_a = new ArrayList<>(list);
    }

    static void changeB_c2() {
        // 获得最后一个
        Integer integer = B_a.get(B_a.size() - 1);
        // 把最后一个放到前面
        List<Integer> list = B_a.subList(0, B_a.size() - 1);
        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(integer);
        integers.addAll(list);
        B_a = new ArrayList<>(integers);
        // 字符串交换后拼接
        String substring  = B_b.substring(25, B_b.length());
        String substring1 = B_b.substring(0, 25);
        B_b = substring  + substring1;
    }

    static char B_char(Integer i) {
        Integer cq = B_a.get(i);
        char c = B_b.charAt(cq);
        changeB_c2();
        return c;
    }

    static Integer aInteger(String c) {
        int i = A_b.indexOf(c);
        return A_c[i];
    }
}

  4.运行得到flag{venividivkcr},验证成功。

https://s1.ax1x.com/2023/06/03/pCpBLbq.png

  5.这个算法题把我脑瓜子整的嗡嗡的,基础不牢,再加上好多java函数不知道意思,要反复去查,一不小心绕进去出不来了。

  6.还有那个Integer类型,jeb必须点开一个个看数组,很麻烦,eclipse点开后看结果,数组移位就很方便了,Android studio应该也可以(不会用),不会导项目进去,jadx另存打包报错不知道咋处理。。

0x4 参考资料:

  1.菜鸟教程

  2.攻防世界Mobile新手入门题easyjava

免费评分

参与人数 9吾爱币 +7 热心值 +8 收起 理由
汉江龙王 + 1 谢谢@Thanks!
哪一天我不在 + 1 热心回复!
allspark + 1 + 1 用心讨论,共获提升!
cxfzaysb + 1 + 1 热心回复!
liu1238 + 1 + 1 热心回复!
duokebei + 1 谢谢@Thanks!
canty胖胖 + 1 + 1 热心回复!
風信子 + 1 + 1 用心讨论,共获提升!
shuaibi_chen + 1 + 1 谢谢@Thanks!

查看全部评分

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

沙发
TheNobody 发表于 2023-6-3 18:56
膜拜大佬~
3#
fish1994 发表于 2023-6-3 19:21
4#
ydafu168 发表于 2023-6-3 21:05
5#
ccclcy 发表于 2023-6-3 21:30
佩服楼主的能力
头像被屏蔽
6#
moruye 发表于 2023-6-3 22:07
提示: 作者被禁止或删除 内容自动屏蔽
7#
shuaibi_chen 发表于 2023-6-3 22:39
谢谢楼主分享
8#
哈哈嘿嘿 发表于 2023-6-3 22:42
楼主还在学习啊,我也在努力
9#
侃遍天下无二人 发表于 2023-6-4 00:53
怎么还是easy呀

免费评分

参与人数 1热心值 +1 收起 理由
小菜鸟一枚 + 1 没办法,小菜鸟太菜了呀!

查看全部评分

10#
pandaren37 发表于 2023-6-4 08:40
看不懂,但是好厉害哦
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-24 12:02

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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