攻防世界easyJava(re Moble)
easyJava
題目考察:jeb反編譯工具的使用,逆向能力,本題是基于enigma密碼機的一個加密,可以參考博客https://blog.csdn.net/kyoma/article/details/51857944,大致題目使用的加密就是這個原理。
題目分析
private static char a(String arg1, b arg2, a arg3) {return arg3.a(arg2.a(arg1));}static Boolean a(String arg1) {return MainActivity.b(arg1);}private static Boolean b(String arg8) {Boolean v0_1;int v0 = 0;if(!arg8.startsWith("flag{")) {v0_1 = Boolean.valueOf(false);}else if(!arg8.endsWith("}")) {v0_1 = Boolean.valueOf(false);}else {String v2 = arg8.substring(5, arg8.length() - 1);b v4 = new b(Integer.valueOf(2));a v5 = new a(Integer.valueOf(3));StringBuilder v3 = new StringBuilder();int v1 = 0;while(v0 < v2.length()) {v3.append(MainActivity.a(v2.charAt(v0) + "", v4, v5));Integer v6 = Integer.valueOf(v4.b().intValue() / 25);if(v6.intValue() > v1 && v6.intValue() >= 1) {++v1;}++v0;}v0_1 = Boolean.valueOf(v3.toString().equals("wigwrkaugala"));}return v0_1;}protected void onCreate(Bundle arg3) {super.onCreate(arg3);this.setContentView(2130968603);this.findViewById(2131427446).setOnClickListener(new View$OnClickListener(((Context)this)) {public void onClick(View arg5) {if(MainActivity.a(this.a.findViewById(2131427445).getText().toString()).booleanValue()) {Toast.makeText(this.a, "You are right!", 1).show();}else {Toast.makeText(this.a, "You are wrong! Bye~", 1).show();new Timer().schedule(new TimerTask() {public void run() {System.exit(1);}}, 2000);}}});}首先,拿到題目一個apk文件,拖入jeb反編譯,得到的MainActivity的大致代碼如下。第一步肯定是要看到最下面的onCreate()方法,觀察題目大概是要我們干什么。
可以發現,他是將我們輸入的東西,傳入到a()方法中,然后若返回結果是true,那么,就會輸出“you are right!”。很顯然我們需要令他成立。
可以看到a()方法其實并沒有什么,就是調用了一下b()方法,將我們輸入的傳了過去。
b()方法是這個MainActivity中主要的一段代碼。他有三個判斷,第一個判斷開頭是否為“flag{”,第二個判斷是否以"}"結尾。第三個比較關鍵,他初始化了a類和b類型為v4 v5,同時分別傳入構造函數2和3.然后把我們輸入的字符串的每個字符和v4,v5傳入帶有三個形參的a()方法中。就是去執行a.a(b.a(“字符”)),返回結果是一個字符類型的值,將每個我們輸入的值執行后返回,拼接起來和”wigwrkaugala“比較,若相等就是正確的了。
public class a {public static ArrayList a;static String b;Integer[] c;static Integer d;static {a.a = new ArrayList();a.b = "abcdefghijklmnopqrstuvwxyz";a.d = Integer.valueOf(0);}public a(Integer arg8) {super();this.c = new Integer[]{Integer.valueOf(7), Integer.valueOf(14), Integer.valueOf(16), Integer.valueOf(21), Integer.valueOf(4), Integer.valueOf(24), Integer.valueOf(25), Integer.valueOf(20), Integer.valueOf(5), Integer.valueOf(15), Integer.valueOf(9), Integer.valueOf(17), Integer.valueOf(6), Integer.valueOf(13), Integer.valueOf(3), Integer.valueOf(18), Integer.valueOf(12), Integer.valueOf(10), Integer.valueOf(19), Integer.valueOf(0), Integer.valueOf(22), Integer.valueOf(2), Integer.valueOf(11), Integer.valueOf(23), Integer.valueOf(1), Integer.valueOf(8)};int v0;for(v0 = arg8.intValue(); v0 < this.c.length; ++v0) {a.a.add(this.c[v0]);}for(v0 = 0; v0 < arg8.intValue(); ++v0) {a.a.add(this.c[v0]);}}public char a(Integer arg5) {char v0_1;int v0 = 0;Integer v1 = Integer.valueOf(0);if(arg5.intValue() == -10) {a.a();v0_1 = " ".charAt(0);}else {while(v0 < a.a.size() - 1) {if(a.a.get(v0) == arg5) {v1 = Integer.valueOf(v0);}++v0;}a.a();v0_1 = a.b.charAt(v1.intValue());}return v0_1;}public static void a() {a.d = Integer.valueOf(a.d.intValue() + 1);if(a.d.intValue() == 25) {int v0 = a.a.get(0).intValue();a.a.remove(0);a.a.add(Integer.valueOf(v0));a.d = Integer.valueOf(0);}} }首先對于這個a類,我們在初始化的時候傳入了3,可以看到在a的構造函數中,他實現的就是相當于enigma密碼機轉動了三格,然后在調用a方法的時候,最終返回的值v0_1就是"abcdefghijklmnopqrstuvwxyz"的第v0個,v0就是傳入的Integer類型的值在ArrayList[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]中的索引值
同時可以發現在他給v0_1賦值前,調用了void a()方法,可以發現這個方法本身是實現對ArrayList的轉動,但是由于可以發現他有一個判斷條件,要令成員變量d為25的時候才執行,因為d初始賦值是0,而我們也不會調用25次,所以是不會觸發到這里面的。
b類的話其實和a類是很相似的,在構造函數的初始化適合a類的初始化是一樣的,不過我們一開始傳的值是2,所以就是相當于轉動了二格。
然后看到b類中關鍵的a方法的代碼,可以知道傳入的是我們輸入的字符串的單個字符,返回的是一個Integer類型的值,在MainActivity中作為a類的a方法的傳入值。
可以知道我們的返回v1是等于v0,v0是v2在ArrayList[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]中的索引
而v2就是我們輸入字符在"abcdefghijklmnopqrstuvwxyz"中的索引
然后在給v1賦值后我們可以發現,他調用了b類的void a()方法,void a()方法是實現了對ArrayList的一次轉動,以及對字符串"abcdefghijklmnopqrstuvwxyz"的一次轉動
到這邊就分析完了,只需要寫出逆向的腳本就可以得到正確的輸入了。
python腳本
from collections import deque#雙端隊列 alpha = deque("abcdefghijklmnopqrstuvwxyz") t1 = deque([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]) t2 = deque([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])ss = 'wigwrkaugala' for _ in range(2): t1.append(t1.popleft()) #實現轉動 for _ in range(3): t2.append(t2.popleft()) print(t1) print(t2)def dec(s): i = t2[(ord(s) - ord('a'))] #ord(s) - ord('a')就可以得到在那個a到z的字符中的索引值i = t1[(i)] print(alpha[i], end='')t1.append(t1.popleft()) alpha.append(alpha.popleft()) for s in ss: dec(s)總結
以上是生活随笔為你收集整理的攻防世界easyJava(re Moble)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 攻防世界dice_game(pwn)
- 下一篇: BUUCTF的Web真题学习整理(一)