0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SECCON Beginners CTF 2020 Writeup

Last updated at Posted at 2020-05-31

yharimaとして参戦。序盤は上位にいたものの後半とけねーとなり21位でフィニッシュ。

readme

読み込めるファイルに制限があるスクリプトを攻略する問題。/home/ctf/flagにフラグがあるもののファイルパスにctfが含まれていると実行できない。

それを回避するためにうまくフラグのあるディレクトリにアクセスできないかを考え、/procで動いているプロセス自身の情報を利用してファイルを読み込む。
実行プロセスのカレントディレクトリが/home/ctf/serverらしいということが環境変数をみるとわかったのでそれを使うとフラグが取れた。

$ echo /proc/self/environ | nc readme.quals.beginners.seccon.jp 9712
File: ...PWD=/home/ctf/server...
$ echo /proc/self/cwd/../flag | nc readme.quals.beginners.seccon.jp 9712
File: ctf4b{m4g1c4l_p0w3r_0f_pr0cf5}

mask

入力した文字列に定数をマスクして、その値がプログラム内に埋め込まれた文字列に合致するかを判定するバイナリを解析する問題。入力する文字列がフラグになるのでそれを突き止める。

aからzの文字を入力して以下のような換字表を作り、埋め込まれた文字列も持ってきて人力でフラグを取った。

abcdefghijklmnopqrstuvwxyz
a`adede`a`adedepqpqtutupqp
abc`abchijkhijk`abc`abchij

ctf4b{dont_reverse_face_mask}
atd4`qdedtUpetepqeUdaaeUeaqau
c`b bk`kj`KbababcaKbacaKiacki

yakisoba

入力した文字列をいろいろ処理して条件にあっているかどうかを判定するプログラムが渡される。めんどくさかったのでangrで自動処理。

まずは正解のメッセージが出力される処理の実行アドレスを突き止める。そしてangrのGithubのトップにあったコード持ってきてアドレスをちゃちゃっと書き換え実行するとフラグが出てくる。

import angr

project = angr.Project("./yakisoba", auto_load_libs=False)

@project.hook(0x4006d9)
def print_flag(state):
  print(state.posix.dumps(0))
  project.terminate_execution()

project.execute()

ghost

GhostScriptのソースコードが渡される。実行すると標準入力から文字列が読み込まれ、文字列が数値に加工される。問題ファイルには加工後の文字列が記されたoutput.txtが渡されるので、その値になるように入力する文字列を特定する問題。

GhostScriptを調べて他の言語に置き換えるのもいいが、あまりドキュメントもなくめんどくさくなったのでブルートフォースで解析。

from pwn import *

def check(flag):
  p = process('gs chall.gs', shell=True)
  p.sendline(flag)
  p.recvline()
  p.recvline()
  p.recvline()
  r = p.recvline().decode('utf-8').strip()
  p.close()
  return r

worddic = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_}!?.,-/'
flag = 'ctf4b{'

found = True
with open('output.txt') as f:
  l = f.read().strip()
  for i, s in enumerate(l.split(' ')):
    if i < len(flag):
      continue
    if not found:
      print('Ooooops...')
      break
    found = False
    for c in worddic:
      r = check(flag + c).split(' ')[-1]
      if r == s:
        flag += c
        found = True
        break

print(flag)

sneaky

スネークゲームをするプログラムが渡される。問題文を読むと高得点取るとフラグらしい。

真面目にやっても仕方ないのでバイナリ解析して得点を管理する部分を突き止め初期得点を書き換える。

sneaky
画像のように0x04007d0が初期得点を入れる命令なので、そこを高得点に書き換えて実行するとフラグが出力される。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?