1. 程式人生 > >bugKuCTF第四道reverse題目Timer(阿里CTF)writeup

bugKuCTF第四道reverse題目Timer(阿里CTF)writeup

題目截圖:


解析:

apk安裝之後出現一個讀秒的,20萬秒,大於3600,所以大於一個小時,所以太慢了,不等了。

jeb反編譯,MainActivity程式碼:

package net.bluelotus.tomorrow.easyandroid;

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public
class MainActivity extends AppCompatActivity { int beg; int k; int now; long t; static { System.loadLibrary("lhm"); } public MainActivity() { super(); this.beg = (((int)(System.currentTimeMillis() / 1000))) + 200000; this.k = 0; this.t = 0; } public
static boolean is2(int n) { boolean v1 = true; if(n > 3) { if(n % 2 != 0 && n % 3 != 0) { int v0 = 5; while(true) { if(v0 * v0 <= n) { if(n % v0 != 0 && n % (v0 + 2) != 0) { v0 += 6
; continue; } return false; } else { return v1; } } return false; } v1 = false; } else if(n <= 1) { v1 = false; } return v1; } protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(2130968600); View v2 = this.findViewById(2131492944); View v3 = this.findViewById(2131492945); Handler v0 = new Handler(); v0.postDelayed(new Runnable() { public void run() { MainActivity.this.t = System.currentTimeMillis(); MainActivity.this.now = ((int)(MainActivity.this.t / 1000)); MainActivity.this.t = 1500 - MainActivity.this.t % 1000; this.val$tv2.setText("AliCTF"); if(MainActivity.this.beg - MainActivity.this.now <= 0) { this.val$tv1.setText("The flag is:"); this.val$tv2.setText("alictf{" + MainActivity.this.stringFromJNI2(MainActivity.this .k) + "}"); } if(MainActivity.is2(MainActivity.this.beg - MainActivity.this.now)) { MainActivity.this.k += 100; } else { --MainActivity.this.k; } this.val$tv1.setText("Time Remaining(s):" + (MainActivity.this.beg - MainActivity.this .now)); this.val$handler.postDelayed(((Runnable)this), MainActivity.this.t); } }, 0); } public boolean onCreateOptionsMenu(Menu menu) { this.getMenuInflater().inflate(2131558400, menu); return 1; } public boolean onOptionsItemSelected(MenuItem item) { boolean v1 = item.getItemId() == 2131492959 ? true : super.onOptionsItemSelected(item); return v1; } public native String stringFromJNI2(int arg1) { } }

關鍵點:

if(MainActivity.this.beg - MainActivity.this.now <= 0) {
                    this.val$tv1.setText("The flag is:");
                    this.val$tv2.setText("alictf{" + MainActivity.this.stringFromJNI2(MainActivity.this
                            .k) + "}");
                }

找到beg和now的點:

public MainActivity() {
        super();
        this.beg = (((int)(System.currentTimeMillis() / 1000))) + 200000;//開啟activity時候的時間(除以1000,所以是秒為單位)再加上200000,即200000+當前時間對應的秒
        this.k = 0;
        this.t = 0;
    }

以及MainActivity.this.now = ((int)(MainActivity.this.t / 1000));即判斷的時候的秒 
那麼beg - now就是200000+開始的時間-判斷的時間,也就是200000-已經過去的時間,所以就是如果過去了200000秒,就可以出現flag了。 
呈現flag是通過native層的this.val$tv2.setText("alictf{" + MainActivity.this.stringFromJNI2(MainActivity.this 
.k) + "}");
也就是stringFromJNI2來呈現的,我們不必逆向so,這個引數是一個k,如果真的去等200000秒(雖然不可能),那麼這裡的k應該是多少呢?

跟k相關的兩個關鍵點如下:

 public static boolean is2(int n) {
        boolean v1 = true;
        if(n > 3) {
            if(n % 2 != 0 && n % 3 != 0) {
                int v0 = 5;
                while(true) {
                    if(v0 * v0 <= n) {
                        if(n % v0 != 0 && n % (v0 + 2) != 0) {
                            v0 += 6;
                            continue;
                        }

                        return false;
                    }
                    else {
                        return v1;
                    }
                }

                return false;
            }

            v1 = false;
        }
        else if(n <= 1) {
            v1 = false;
        }

        return v1;
    }



 if(MainActivity.is2(MainActivity.this.beg - MainActivity.this.now)) {
                    MainActivity.this.k += 100;
                }
                else {
                    --MainActivity.this.k;
                }

總結思路:通過beg - now代入is2函式對k進行操作,200000,需要一秒一秒的操作,而我們,直接通過寫程式碼模擬出200000的結果,找到k,然後改動k值,直接呼叫,就可以得到flag了。

程式碼

is2是用java寫的,懶得看邏輯,直接複製到java裡邊:

package test;

public class Main {

    public static boolean is2(int n) {
        boolean v1 = true;
        if(n > 3) {
            if(n % 2 != 0 && n % 3 != 0) {
                int v0 = 5;
                while(true) {
                    if(v0 * v0 <= n) {
                        if(n % v0 != 0 && n % (v0 + 2) != 0) {
                            v0 += 6;
                            continue;
                        }

                        return false;
                    }
                    else {
                        return v1;
                    }
                }
            }

            v1 = false;
        }
        else if(n <= 1) {
            v1 = false;
        }

        return v1;
    }

    public static void main(String args[]) {
        int time = 200000;
        int k = 0;
        while (time > 0) {
            if (is2(time)) {
                k += 100;
            }
            else {
                k--;
            }
            time--;
        }
        System.out.println(k);
    }

}

執行得到k值,然後apktool 反編譯原apk,更改smali,兩個點:

  • 將輸出flag的條件反過來,即MainActivity$1.smali中的if-gtz v0, :cond_0這句話(後面是輸出The Flag Is那裡的跳轉)改為if-ltz v0, :cond_0
  • 將k值改為常量,即上文提到的smali檔案中的iget v3, v3 ....(省略);->k:I之後新增const v3, 1616384

重新打包,簽名,安裝,得到flag為alictf{Y0vAr3TimerMa3te7}

轉載自:https://blog.csdn.net/qq_29343201/article/details/51607527