m0becのメモ帳

いろいろ書いてきます

AlexCTFのWriteup

RE1:Gifted

giftedというELFファイルが渡される。とりあえずstringsコマンドを使ってみるとフラグが見える。 AlexCTF{Y0u_h4v3_45t0n15h1ng_futur3_1n_r3v3r5ing}

RE4:unVM me

unvm_me.pycが渡される。pycファイルを逆コンパイルするツール Easy Python Decompilerを使うと以下のコードになる。

# Embedded file name: unvm_me.py
import md5
md5s = [174282896860968005525213562254350376167L,
 137092044126081477479435678296496849608L,
 126300127609096051658061491018211963916L,
 314989972419727999226545215739316729360L,
 256525866025901597224592941642385934114L,
 115141138810151571209618282728408211053L,
 8705973470942652577929336993839061582L,
 256697681645515528548061291580728800189L,
 39818552652170274340851144295913091599L,
 65313561977812018046200997898904313350L,
 230909080238053318105407334248228870753L,
 196125799557195268866757688147870815374L,
 74874145132345503095307276614727915885L]
print 'Can you turn me back to python ? ...'
flag = raw_input('well as you wish.. what is the flag: ')
if len(flag) > 69:
    print 'nice try'
    exit()
if len(flag) % 5 != 0:
    print 'nice try'
    exit()
for i in range(0, len(flag), 5):
    s = flag[i:i + 5]
    if int('0x' + md5.new(s).hexdigest(), 16) != md5s[i / 5]:
        print 'nice try'
        exit()

print 'Congratz now you have the flag'

これは入力した文字を5文字ずつ読み込みmd5変換した数値とmd5sの数値を比較するプログラムである。 要するにmd5sの数値を16進数にしてから逆変換してつなげればflagになるので、md5を逆変換してくれるサイトにぶん投げれば終了!
md5s[6]の8705…は16進数にすると31桁になるがこれは先頭の0がいなくなっただけなので、逆変換するときに0をつければいい。 ALEXCTF{dv5d4s2vj8nk43s8d8l6m1n5l67ds9v41n52nv37j481h3d28n4b6v3k}

CR1:Ultracoded

ZEROとONEが大量に書かれたファイルが渡されるZEROとONEを0,1に変換した後、8bitずつ16進数にしてAsciiコードに変換すると次の文字列になる。 Li0gLi0uLiAuIC0uLi0gLS4tLiAtIC4uLS4gLSAuLi4uIC4tLS0tIC4uLi4uIC0tLSAuLS0tLSAuLi4gLS0tIC4uLi4uIC4uLSAuLS0uIC4uLi0tIC4tLiAtLS0gLi4uLi4gLiAtLi0uIC4tLiAuLi4tLSAtIC0tLSAtIC0uLi0gLQ== Base64変換されている感じがするので、Base64でデコードする。
.- .-.. . -..- -.-. - ..-. - .... .---- ..... --- .---- ... --- ..... ..- .--. ...-- .-. --- ..... . -.-. .-. ...-- - --- - -..- -
点と棒だけである。モールス信号っぽい?ってことでモールス信号をデコードしてくださるサイトに投げる。
ALEXCTFTH15O1SO5UP3RO5ECR3TOTXT
flagゲット!!となるが難しいのはここからである…
適当に{}で囲ってもはじかれてしまう。思いつく限りのパターンをたたきこんでると点数が入った。
ALEXCTF{th15_1S_5up3r_5ecr3t_txt} (たぶんこれかな)(自信ない)  

CR2:Many time secrets

16進数が書いてあるファイルが渡される。catで見ると次のようになる。

0529242a631234122d2b36697f13272c207f2021283a6b0c7908
2f28202a302029142c653f3c7f2a2636273e3f2d653e25217908
322921780c3a235b3c2c3f207f372e21733a3a2b37263b313012
2f6c363b2b312b1e64651b6537222e37377f2020242b6b2c2d5d
283f652c2b31661426292b653a292c372a2f20212a316b283c09
29232178373c270f682c216532263b2d3632353c2c3c2a293504
613c37373531285b3c2a72273a67212a277f373a243c20203d5d
243a202a633d205b3c2d3765342236653a2c7423202f3f652a18
2239373d6f740a1e3c651f207f2c212a247f3d2e65262430791c
263e203d63232f0f20653f207f332065262c3168313722367918
2f2f372133202f142665212637222220733e383f2426386b

問題文ではone time pad の意味を理解していない、みたいなことが書いてあった。同じ鍵でxorし続けたんだなぁ、と予想をたてALEXCTF{でxorをすると文章が出てくる。文章の続きを予測しながらxorしていくと鍵(flag)がわかる。
ALEXCTF{HERE_GOES_THE_KEY}

CR4:Poor RSA

RSAの公開鍵とRSAエンコードしてからBase64でさらにエンコードしたflagが渡される。RSAの数式はよくわからないので
http://kira000.hatenadiary.jp/entry/2016/02/07/191924 からコードをもってきて使うとflagが出る。 ALEXCTF{SMALL_PRIMES_ARE_BAD}

Fore1:Hit the core

渡されたファイルをstringsで眺めると怪しい文字列が出てくる。

cvqAeqacLtqazEigwiXobxrCrtuiTzahfFreqc{bnjrKwgk83kgd43j85ePgb_e_rwqr7fvbmHjklo3tews_hmkogooyf0vbnk0ii87Drfgh_n kiwutfb0ghk9ro987k5tfb_hjiouo087ptfcv}

Aから5文字おきに読んでいくとflagになった。 ALEXCTF{K33P_7H3_g00D_w0rk_up}

SC1:Math bot

ncでつなぐと計算問題が表示されて答えを入力する。計算問題は500問あり、すべてに正解するとflagが表示される。てけいさん for ビギナーズだ!。以下のプログラムでflagを入手した。
どこかと通信して処理を行うプログラムは初めてなので変なところがあったら教えてくださると助かります。

#!/usr/bin/env python
from pwn import *


#nc 195.154.53.62 1337
def connect(ip, port):
    return remote(ip, port)

conn = connect('195.154.53.62', 1337)

while 1:
    try:
        st1 = conn.recvuntil(':', drop=True)
    except:
        print conn.recv(1024)
        break
    print st1
    st2 = conn.recvline()
    print st2
    stri = conn.recvline()
    print stri
    str_lis = stri.split(" ")
    ans = 0
    if str_lis[1] == "+":
        ans = int(str_lis[0]) + int(str_lis[2])
    elif str_lis[1] == "-":
        ans = int(str_lis[0]) - int(str_lis[2])
    elif str_lis[1] == "*":
        ans = int(str_lis[0]) * int(str_lis[2])
    elif str_lis[1] == "/":
        #ans = input()
        ans = int(str_lis[0]) // int(str_lis[2])
    elif str_lis[1] == "%":
        ans = int(str_lis[0]) % int(str_lis[2])
    ans_str = str(ans)
    ans_str += "\n"
    conn.send(ans_str)

flagはメモし忘れました。