IntelliJ IDEA+gradleでもぢんぐ環境整える(Forge964)

ForgeGradleを使った環境構築について書きます。
gradleを使わない場合はlaco0416さんの記事とか見たほうがいいと思います。

1.Forgeのセットアップ
まずはダウンロードしてきたForgeのsourceを好きなところに展開します。
展開したフォルダを[PROJECT]とします。
次に、コマンドラインでgradleのセットアップをします。

gradlew setupDevWorkspace ideaModule

2.IntelliJのプロジェクト作成
New ProjectからEmpty Projectを作ります。

Project name: forge(好きに変えて)
Project location: [PROJECT]

File Already Existsとか出てくると思いますが気にせず続けてください。
次に、Project Structure→Modulesで+をクリックしてImport Moduleします。
そこでforge.imlとか選べばいいと思います。
そのままではSDKが指定されていないと思うので、DependenciesからModule SDKを適当に選びます。
ついでにProject Structure→ProjectのProject SDKも適当に選んでおきます。
これで基本的な設定は終わりです。

3.起動設定
このままでは起動できないので、Run→Edit ConfigurationでClientとServerの設定を追加します。
Client

Main class: net.minecraft.launchwrapper.Launch
VM options: -Xmx1024M -Xms1024M -Dfml.ignoreInvalidMinecraftCertificates=true -Djava.library.path="../../build/natives"
Program arguments: --version 1.6 --tweakClass cpw.mods.fml.common.launcher.FMLTweaker --username user
Working directory: [PROJECT]/run/client

Server

Main class: cpw.mods.fml.relauncher.ServerLaunchWrapper
VM options: -Xmx1024M -Xms1024M -Dfml.ignoreInvalidMinecraftCertificates=true -Djava.library.path="../../build/natives"
Working directory: [PROJECT]/run/server
Single instance only: true

これで設定は終わりです。
作ったものを公開するときは

gradlew build

とかすればいいかもしれません。(まだ試していないのでわかりませんが)

CSAW CTF 2013 Reversing 150 bikinibonanza Writeup

f:id:nk0t:20130923145840p:plain:w564:h302
まずは起動してみます。すると直感で.NETプログラムだという事が分かります。
なのでとりあえずILSpyで開いてみます。
するとメソッド名が難読化されてeval_□になっています。
まずは怪しそうなボタンのクリックされた時の処理を見てみます。

private void eval_□(object obj, EventArgs eventArgs)
{
    string strB = null;
    Assembly executingAssembly = Assembly.GetExecutingAssembly();
    ResourceManager resourceManager = new ResourceManager(executingAssembly.GetName().Name + ".Resources", executingAssembly);
    DateTime now = DateTime.Now;
    string arg_65_0 = this.eval_□.Text;
    string value = string.Format("{0}", now.Hour + 1);
    string text = "NeEd_MoRe_Bawlz";
    this.eval_□(text, Convert.ToInt32(value), ref strB);
    if (string.Compare(arg_65_0.ToUpper(), strB) == 0)
    {
        this.eval_□.Text = "";
        this.eval_□(this.eval_□(107));
        this.eval_□();
        this.eval_□.Text = string.Format(this.eval_□.Text, this.eval_□(resourceManager));
        this.eval_□.Image = (Bitmap)resourceManager.GetObject("Sorry You Suck");
    }
    else
    {
        this.eval_□.Image = (Bitmap)resourceManager.GetObject("Almost There");
        this.eval_□();
    }
}

処理が多少難読化されていますが、string.Compareで比較しているのでそこを見ていきます。
入力した文字(arg_65_0)とstrBを比較していて、strBは現在時刻のhourを使って生成していることが分かります。
同じことをするプログラムを作って入力するとkeyが出てきます。
f:id:nk0t:20130923145857p:plain

しかし、なぜかこのkeyでは通りませんでした。
想定では正しいkeyが表示されるようですが、環境によるのか、間違ったkeyが出てきたチームが多かったみたいです。

とりあえず出てきたkeyで検索してみると、"???????????????????????"のハッシュ値らしいということが分かります。
どこかで文字化けしているような気がしてきたので、次はkeyを生成・表示しているところを見ていきました。

private unsafe string eval_□(ResourceManager resourceManager)
{
    string @string = resourceManager.GetString("numbers");
    int length = @string.Length;
    sbyte* ptr = (sbyte*)Marshal.StringToHGlobalAnsi(@string).ToPointer();
    <Module>.eval_□(ptr, length);
    string text = new string((sbyte*)ptr);
    return this.eval_□(text);
}

keyの生成は単純で、まずはリソースから"ThisIsASecretSeedYouCanSeeTheSecretSeed"というシード値を取得してきます。
次に<Module>.eval_□でこの文字列を変換して、そのmd5ハッシュ値がkeyになります。
しかし、<Module>.eval_□はネイティブコードなので、ILSpyでは解析できません。
次に、この関数をIL DASMで見てみます。
f:id:nk0t:20130923150431p:plain
すると、この関数は 0x00001490 に配置されるらしい、という事が分かります。

f:id:nk0t:20130923150447p:plain
OllyDbgで動かしながらそれっぽいアドレスを見るとそれっぽい処理が出てきます。
アセンブリからC#に書き直してみるとこんな感じになります。

public string Hoge(string seed)
{
    var result = seed.ToCharArray();
    for (int i = 0; i < seed.Length; i++)
    {
        result[i] = (char)(result[i] ^ 0x2);
    }
    for (int i = 0; i < seed.Length; i++)
    {
        result[i] = (char)(result[i] ^ 0xfb);
    }
    return new string(result);
}

というわけで答えは key(0920303251BABE89911ECEAD17FEBF30) でした。
終わった後に他の人に聞いてみたところ、PMで運営に解き方を話したら正しいフラグを貰えたみたいです。
難易度的にはrev200よりも難しいかなーという感じでした。
今回は本当に何もできなかったので来年から本気出します。
おしまい。

ASIS CTF Writeup PPC/Code&Code

ncで接続するとQRコードが表示されるので、デコードして入力すると別のQRコードが表示される。
100回入力するとflagが出てくる。
文字列なQRコードをデコードする方法が思いつかず、画像に変換してからデコードした。

import sys
import socket
import Image
from qrtools import QR
 
def solve(qrcode):
    make_qrcode_image(qrcode)
 
    code = QR(filename='qrcode.png')
    if code.decode():
        return code.data
    return 'null'
 
def make_qrcode_image(qrcode_str):
    img = Image.new('RGB', (30*2, 30*2), (0xff, 0xff, 0xff))
    x = 0
    y = 0
    for l in qrcode_str.rstrip('\n').split('\n'):
        for c in l.lstrip(' ').split(' '):
            if c == '-':
                for kx in range(2):
                    for ky in range(2):
                        img.putpixel((y*2+ky,x*2+kx), (0x00, 0x00, 0x00))
            x += 1
        y += 1
        x = 0
    img.save('qrcode.png')
 
s = socket.socket(socket.AF_INET)
s.connect(('asis-ctf.ir', 12435))
 
print s.recv(1024)
print s.recv(1024)
s.send('\n')
 
for count in range(0,100):
    print s.recv(1024)
    qrcode = s.recv(1024)
    qrcode += s.recv(1024)
    qrcode += s.recv(1024)
    print qrcode
    ans = solve(qrcode)
    print ans
    print count
    s.send(ans + '\n')
 
print s.recv(1024) # flag
 
s.close()

the flag is: ASIS_ebd814d43f558d1b73d077234f65b71b

今回はWebが難しくて1問も解けませんでした。
バイナリも解きたかったけど @potetisensei が解きまくってて手が出せませんでした。
おしまい。