サイバーコロッセオ参加記(供養)

サイバーコロッセオにチームMusashiの一員として参加してきました。 なにもできなかった感が強い。

やってたこと

自分はサーバ2を基本的にやってました。 stage1はやるだけでstage2でシェルコードを送り込むだけだったのは気づいたんですがやり方がわからなかった。

というのも最初のうちはncで反応がなくて、パイプで渡す方法(下のようなコマンド)しかやっていなかったので…. どうしたら標準入力に渡せるんだろうと考えていたところで終わった(/tmpに書き込めたので/tmpから実行していたがうまくいかなかった。シェルコードが間違ってた可能性もある)

$ echo 'exec ./stage2' | nc 10.100.2.1 22222

解説のときに普通にncできていて、なんだったんだと言う感じだった。

感想

とりあえずPC2つあると便利と思いました。外部ネットワークにつながらないのは不便きわまりない。 次の機会があるならスクレイピングとかの技術なり準備なりをしておくべきだと思いました。

Alex CTF Writeup

Alex CTFにも参戦してました。 解いた問題もCTFらしくはないですが、一応Writeupを

[Scripting 100] SC1: Math bot

アクセスするとひたすら計算問題を出されるのでひたすらpythonで解かせる 500問解くとflagが落ちてくる。適当にスクリプト組んだのでこれだけ上げとく.

import socket,telnetlib
import math

# common funcs ---
def sock(remoteip, remoteport):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((remoteip,remoteport))
    return s, s.makefile('rw',bufsize=0)

def read_until(f,delim='\n'):
    data = ''
    while not data.endswith(delim):
        data+= f.read(1)
    return data

def ans():
    r= ''
    # Questionの文字まで読み込む
    while "Question" not in r:
        r += f.read(1)
        print(r)

    r = ''
    # Question番号まで読み込む
    while "\n" not in r:
        r += f.read(1)
    print(r)
    r = ''
    first = ''
    second = ''
    r = read_until(f)
    print(r)
    # 問題を読み込む
    lis = r.split(' ')

    first = long(lis[0])
    ope = lis[1]
    second = long(lis[2])

    # math
    if ope == "+":
        ret = int(first + second)
    elif ope == "-":
        ret = int(first - second)
    elif ope== "*":
        ret = first * second
    elif ope== "/":
        ret = math.floor(first/second)
    elif ope== "%":
        ret = int(first % second)
    if ret == int(ret):
        ret = int(ret)
    f.write(ret)
    f.write("\n")
    print(str(ret)+"\n")

# main
s, f = sock('195.154.53.62', 1337)
r = ''
for i in range(10000):
    ans()

BITSCTF Writeup

BITSCTFにTeam:Harekazeの一員として参加してました。得点は520点で順位は18位でした。 自分が問いた1問のWriteupを記します。

[Crypto 40pts] Beginner’s Luck

問題から渡されるのはBITSCTFfullhd.pngとenc27.pyというファイル

pythonファイルの方を見ると、適当な鍵ファイルからfullhd.pngファイルを暗号化してBITSCTFfullhd.pngファイルを出力しているのが分かる。

PNGのヘッダには固定の部分があること、またスクリプトで最後にpaddingを使っていることからこの2つの部分があれば鍵の復元は可能ということで組んだスクリプトがこちら 適当なpngファイルを用いて復元を行った。

 #!/usr/bin/env python

def supa_encryption(s1, s2):
    res = [chr(0)]*24
    for i in range(len(res)):
        q = ord(s1[i])
        d = ord(s2[i])
        k = q ^ d
        res[i] = chr(k)
    res = ''.join(res)
    return res

def add_pad(msg):
    L = 24 - len(msg)%24
    msg += chr(L)*L
    return msg

with open('BITSCTFfullhd.png','rb') as f:
    data = f.read()
with open('test.png','rb') as f:
    test = f.read()


org = test[0:24]

# search key
key = [chr(0)]*24
for i in range(len(org)):
    q = ord(org[i])
    k = ord(data[i])
    d = k ^ q
    key[i] = chr(d)

#end of file
last = data[len(data)-24:len(data)]
for i in range(len(last)):
    print(ord(last[i]))

このスクリプトでkeyの大部分の特定とpaddingが19であることがわかる。またkeyが間違っているのが19,20,24番目というのもわかるので、スクリプトに追加して鍵を特定する。(適当に選んだ結果23番の鍵があってたのは運の問題、本来は19,20,23,24番目のkeyが違う)

mes =[chr(0)]*24
# missing key is 19 20 24
# original padding is 19
q = 19
k = ord(last[18])
d = k ^ q
key[18] = chr(d)
q = 19
k = ord(last[19])
d = k ^ q
key[19] = chr(d)
q = 19
k = ord(last[23])
d = k ^ q
key[23] = chr(d)

for i in range(len(last)):
    k = ord(last[i])
    d = ord(key[i])
    q = k ^ d
    mes[i] = chr(q)
mes = ''.join(mes)
for i in range(len(mes)):
    print(ord(mes[i]))
    print(mes[i])
print(mes)
print(''.join(key))

この結果key = rkh%QP4g0&3g46@4*%f(UN#\となる あとはこのkeyを用いて復号を行う。復号のスクリプトはこちら

#!/usr/bin/env python

def supa_encryption(s1, s2):
    res = [chr(0)]*24
    for i in range(len(res)):
        q = ord(s1[i])
        d = ord(s2[i])
        k = q ^ d
        res[i] = chr(k)
    res = ''.join(res)
    return res

def dec(s1,s2):
    res=[chr(0)]*len(s1)
    for i in range(len(res)):
        d = ord(s2[i])
        k = ord(s1[i])
        q = k ^ d
        res[i] = chr(q)
    res = ''.join(res)
    return res

def add_pad(msg):
    L = 24 - len(msg)%24
    msg += chr(L)*L
    return msg
        

with open('BITSCTFfullhd.png','rb') as f:
    data = f.read()

#data = add_pad(data)
padding = 19


with open('key.txt') as f:
    key = f.read()
    
dec_data = ''
for i in range(0, len(data), 24):
    #enc = supa_encryption(data[i:i+24], key)
    #enc_data += enc
        if i == len(data)-24:
            decdata = dec(data[i:i+4],key)
            dec_data += decdata
        else:
            decdata = dec(data[i:i+24],key)
            dec_data += decdata
        

with open('ans.png', 'wb') as f:
    f.write(dec_data)

f:id:kataware8136:20170206105528p:plain

という画像ができる。FLAGはBITSCTF{p_en_gee}

終わり

結構時間かかってしまった。もっとチームに貢献できるようにがんばりたい…..