在bugku上做逆向题,想写篇文章记录下过程和我的心路历程,直接接上正文:
直接扔进IDA中,没想到一进去就看到了flag:
看到这就明白这道题已经结束了:
a=[0x66,0x6C,0x61,0x67,0x7B,0x52,0x65,0x5F,0x31,0x73,0x5F,0x53,0x30,0x5F,0x43,0x30,0x4F,0x4C,0x7D] flag="" for i in a: flag+=chr(i) print (flag)
直接用OD打开搜索Unicode字符串,或者使用VB的反编译器VB Decompiler Pro
可以直接看到flag
先扔到IDA里面去,shift+F12 打开字符串窗口,没想到又直接看到了flag,或者直接string一下也可以得到flag:
玩游戏是不可能玩游戏的,这辈子都不可能玩游戏的,只能扔到IDA分析一下,打开字符串找到关键语句,跳到该函数位置:
F5看下伪代码,对两个数组的每个成员进行异或,最后再按位和0x13异或得到flag,脚本如下所示:
flag='' a=[18,64,98,5,2,4,6,3,6,48,49,65,32,12,48,65,31,78,62,32,49,32,1,57,96,3,21,9,4,62,3,5,4,1,2,3,44,65,78,32, 16, 97, 54, 16, 44, 52, 32, 64, 89, 45, 32, 65, 15, 34, 18, 16, 0] b=[123,32,18,98,119,108,65,41,124,80,125,38,124,111,74,49,83,108,94,108,84,6,96,83,44,121,104,110,32,95,117,101,99,123,127,119,96,48,107,71,92,29,81,107,90,85,64,12,43,76,86,13,114,1,117,126,0] for i in range(56): flag+=chr(a[i]^b[i]^0x13) print (flag)
OD也可以做,但是我的渣动态调试总是失败。。。
首先用jeb分析下源码:
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; import android.widget.TextView; 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 arg4) { boolean v1 = true; if(arg4 > 3) { if(arg4 % 2 != 0 && arg4 % 3 != 0) { int v0 = 5; while(true) { if(v0 * v0 <= arg4) { if(arg4 % v0 != 0 && arg4 % (v0 + 2) != 0) { v0 += 6; continue; } return false; } else { return v1; } } return false; } v1 = false; } else if(arg4 <= 1) { v1 = false; } return v1; } protected void onCreate(Bundle arg7) { super.onCreate(arg7); this.setContentView(0x7F040018); View v2 = this.findViewById(0x7F0C0050); View v3 = this.findViewById(0x7F0C0051); Handler v0 = new Handler(); v0.postDelayed(new Runnable(((TextView)v3), ((TextView)v2), v0) { public void run() { MainActivity.this.t = System.currentTimeMillis(); MainActivity.this.now = ((int)(MainActivity.this.t / 1000)); // Int会只保留整数位的数 MainActivity.this.t = 1500 - MainActivity.this.t % 1000; // 存在一种情况,即在200000秒之后,会得到flag 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 arg3) { this.getMenuInflater().inflate(0x7F0D0000, arg3); return 1; } public boolean onOptionsItemSelected(MenuItem arg3) { boolean v1 = arg3.getItemId() == 0x7F0C005F ? true : super.onOptionsItemSelected(arg3); return v1; } public native String stringFromJNI2(int arg1) { } }
大概意思是二十万秒后给出flag,我们可以直接快速模拟二十万秒后k的值,传入就可以得到flag了
脚本如下所示:
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); } }
emmmmm,还以为是逆向,其实是道misc,后缀名改成txt后,直接base64转图片,得到一张二维码:
扫一扫,得到flag
可以看到输入的字符串经过sub_4110BE后,和Dest进行拼接,按位加j后与str2进行比较,逻辑很清晰,sub_4110BE函数是一个base64加密,从密码表就可以看出来,解题脚本如下:
a='e3nifIH9b_C@n@dH' flag='' for i in range(len(a)): flag+=chr(ord(a[i])-i) print flag.decode('base64')
info 评论功能已经关闭了呐!