小菜鸟一枚 发表于 2023-6-3 17:58

学破解第207天,《攻防世界 easy_java》学习

前言:

  坛友们,年轻就是资本,和我一起逆天改命吧,我的学习过程全部记录及学习资源:(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);
            }
      });
    }
}
```

&emsp;&emsp;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;
                }

```

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

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

&emsp;&emsp;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=

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=
```

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

&emsp;&emsp;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);
```

&emsp;&emsp;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
&emsp;&emsp;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};
```

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

&emsp;&emsp;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;
                        for (int j = 1; j < B_c.length; j++) {
                                B_c = B_c;
                        }
                        B_c = 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;
        }
}

```

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

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

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

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

## 0x4 参考资料:
&emsp;&emsp;1.[菜鸟教程](https://www.runoob.com/java/java-string-contains.html)

&emsp;&emsp;2.[攻防世界Mobile新手入门题easyjava](https://blog.csdn.net/m0_52122417/article/details/125626835)

TheNobody 发表于 2023-6-3 18:56

膜拜大佬~

fish1994 发表于 2023-6-3 19:21

还附上了资源,太贴心了

ydafu168 发表于 2023-6-3 21:05

你学习是认真的,更有赋,我啥也看不懂

ccclcy 发表于 2023-6-3 21:30

佩服楼主的能力

moruye 发表于 2023-6-3 22:07

shuaibi_chen 发表于 2023-6-3 22:39

谢谢楼主分享

哈哈嘿嘿 发表于 2023-6-3 22:42

楼主还在学习啊,我也在努力

侃遍天下无二人 发表于 2023-6-4 00:53

怎么还是easy呀{:301_997:}

pandaren37 发表于 2023-6-4 08:40

看不懂,但是好厉害哦
页: [1] 2 3
查看完整版本: 学破解第207天,《攻防世界 easy_java》学习