menu Alkaid #二进制初学者 / 网络安全 / 大龄CTF退役选手
Bugku练习平台Re全攻略
337 浏览 | 2018-12-19 | 分类:心路历程,CTF | 标签:感悟,CTF,linux,python

在bugku上做逆向题,想写篇文章记录下过程和我的心路历程,直接接上正文:

0x01 入门逆向

直接扔进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)

0x02 Easy_vb

直接用OD打开搜索Unicode字符串,或者使用VB的反编译器VB Decompiler Pro

可以直接看到flag

 

0x03 Easy_Re

先扔到IDA里面去,shift+F12 打开字符串窗口,没想到又直接看到了flag,或者直接string一下也可以得到flag:

0x04 游戏过关

玩游戏是不可能玩游戏的,这辈子都不可能玩游戏的,只能扔到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也可以做,但是我的渣动态调试总是失败。。。

 

0x05 Timer(阿里CTF)

首先用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);
    }
 
}

 

 

0x06 逆向入门

emmmmm,还以为是逆向,其实是道misc,后缀名改成txt后,直接base64转图片,得到一张二维码:

扫一扫,得到flag

 

0x07 love

可以看到输入的字符串经过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')

 

 

温柔正确的人总是难以生存,因为这世界既不温柔,也不正确

发表评论

email
web

全部评论 (暂无评论)

info 还没有任何评论,你来说两句呐!