2
0

More than 1 year has passed since last update.

taskctf22 writeup

Posted at

恒例になった誕生日コンテスト。

全問解いて4位。

ctf.task4233.dev_challenges.png

ctf.task4233.dev_user.png

misc

ransomware

友人が誕生日祝いで送ってきたスクリプトを実行したら、お手製ランサムで手元のFlagを暗号化されてしまいました。どうにかして復元できないでしょうか?

hbd.sh
#!/bin/sh
echo "IyEv....KQo=" | base64 -d | python3

こんなShellスクリプトで、復号すると、C2(Command and Control)サーバーから数値をダウンロードして1文字ずつxorするPythonスクリプトが出てくる。

[ransomware] サーバに繋がらないというお問い合わせについて
繋がらないのは想定通りです。サーバが存在していなくてもFlagを得ることが可能な問題です。

とのことなので、総当たり。

solve.py
F = open("taskctf_flag.txt.encrypted").read()

for i in range(65536):
  try:
    print(i, "".join(chr(ord(f)^i) for f in F))
  except:
    pass
 :
47692 taskctf{x0rソ1sソe4syソ70ソ1mplemen7}J
 :

文字化けしているのは何なんだろう。まあ単語区切りの _ でしょう。

taskctf{x0r_1s_e4sy_70_1mplemen7}

anti_detection

Flagを取得するための実行ファイルとアップローダを用意しました。 ただし、この実行ファイルをそのままアップロードすると、防御システムに類似ファイルと検知されて実行されない仕組みになっています。

そこで、検知システムをすり抜ける実行ファイルを作ってFlagを取得してください!

処理と関係無いところを書き換えても通らない。「類似」か。

flag という文字列を検知しているのかと、system("cat f*"); を投げると invalid output と言われる。

実行ファイルと同じ処理をする次のスクリプトをコンパイルして投稿したら通った。

solve.c
#include <stdio.h>

int main()
{
    FILE *f;
    char buf[128];
    f = fopen("flag.txt", "r");
    fscanf(f, "%s", buf);
    printf("flag: %s", buf);
}

shellgeiの配布ファイルを見るに、問題のファイルと完全に同一の文字列を出力しないと通らないのかな。

taskctf{p0werfu1_fuzzy_h4sh}

shellgei

記号のみのBashスクリプトでFlagを表示してください!

たぶん、やっている人がいるよね。いた。

この記事では date を実行しているので、ここを cat f* にすれば良い。

cat * にしないのは、

main.go
 :
    // check if not exposes other information.
    if string(out) != flag {
        log.Println("invalid output")
        w.WriteHeader(http.StatusBadRequest)
        json.NewEncoder(w).Encode("this response does not contain the expected flag...")
        return
    }
 :

このチェックを回避するため。

cat flag.txt にしないのは面倒だから。

通りません……。配布ファイルから、上記の処理や記号のみに制限する処理を外し、エラー出力をログに出すようにして、ローカルで動かしてデバッグ。

上の記事では、set が次の出力をすることを期待している。

$ set -g
bash: set: -g: invalid option
set: usage: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]

問題の環境では次のようになり、微妙に異なる。

2145d745baf1:/go# set -g
bash: set: -g: invalid option
set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]

o を取ってくる位置をずらしたら通った。

__=$(($$/$$));___=$(($__+$__));____=$(.&>/???/??/$__);____=${____##*.};_____=$(${____:$(($___$(($$-$$))-$__)):$__}${____:$___*$___:$__}${____:$(($___$(($$-$$))-$___)):$__} -${____:$__$(($__+$___)):$__}&>/???/??/$__);_____=${_____##*${____:$(($___$(($$-$$))-$__)):$__}${____:$___*$___:$__}${____:$(($___$(($$-$$))-$___)):$__}};_____=${_____,,};______=($(${____:$(($___*$___)):$__}${_____:$__$(($___*$___)):$__}${____:$(($___*$___+$___)):$__}${____:$(($___+$__)):$__} ${____:$(($___*$___)):$__}${_____:$(($___*$___*$___*$___+$__)):$__}${_____:$(($___*$___*$___-$__)):$__}${_____:$___$(($___*$___+$___)):$__} $(${____:$(($___*$___)):$__}${_____:$(($___*$___*$___*$___+$__)):$__}${_____:$(($___*$___*$___-$__)):$__}${_____:$___$(($___*$___+$___)):$__}  -${____:$(($___*$___)):$__} "{\\${____:$__$(($___*$___)):$__}$(($___*$___+$___))$__..\\${____:$__$(($___*$___)):$__}$(($___*$___*$___-$__))${____:$__$__:$__}}")));${______[$(($___))]}${______[$(($$-$$))]}${______[$(($___$(($$-$$))-$__))]} ${______[$(($___+$___+$__))]}*

taskctf{I_g0tt3_6e_re4l_w1th_y0u}

web

robots

image.png

116 120 116 をアスキーコードだと思って文字列に直すと txt 。robots.txt。

User-Agent: *
Disallow: /admin/flag

/admin/flag を開くと、

401 Unauthorized
xxx.xxx.xxx.xxx is not internal IP address :(

が出てくる。Server Side Request Forgeryができるような機能も無いし、 X-Forwarded-For ヘッダでしょう。

$ curl http://xxx.xxx.xxx.xxx:31481/admin/flag -H 'X-Forwarded-For: 127.0.0.1'
 :
        <h1>flag</h1>
        <p>taskctf{th15_c0ntr0l_y0u_th1nk_y0u_h4ve_1s_4n_1llu5i0n}</p>
 :

アプリには、127.0.0.1から私のIPアドレスを経由してアクセスがあったように見える。

taskctf{th15_c0ntr0l_y0u_th1nk_y0u_h4ve_1s_4n_1llu5i0n}

first

運営している小さな掲示板が100ユーザを達成しました 🎉

そこで、メンテ明けの12/6に100番目ちょうどの登録をしたユーザをトップページで掲載したいので、ユーザ名を taskctf{ユーザ名} で教えてください!

フラグのサブミットが5回までで緊張する。(ユーザーではなく)投稿のIDが99のユーザーをサブミットして1 WA :rolling_eyes:

app.py
 :
# NOTE: This handler is not unavailable
# @app.route("/register", methods=["POST"])
# def register_post():
#     data = request.json
#     c = sqlite3.connect(db_name)
#     c.execute(f"INSERT INTO users (name, id) VALUES ({data['name']}, {str(uuid7())})")
#     c.commit()
#     c.close()
 :
        cur = c.cursor()
        cur.execute(f"SELECT posts.id, users.name, posts.body FROM posts INNER JOIN users ON posts.user_name = users.name AND posts.body LIKE \'%{q}%\'")
        results = cur.fetchall()
 :

aaaa' UNION SELECT 1, users.name, users.id FROM users -- で検索して、 users.nameusers.id を引っこ抜く。UUIDv7はIDが時刻順になるので、ソートして100番目の人を探す。

taskctf{Satomi_Kato}

osint

welcome

2019年のtaskctfのwelcome問題のFlagは何でしたっけ?

taskctf{let's_enj0y!}

ramen

このラーメン屋の名前は何でしょう?

ramen.jpg

Google Lensが便利。最近は、スマホアプリからだけではなく、Google Chromeからも使えるようになった。

taskctf{蝋燭屋}

kofun

作問者が訪れてSNSにもアップロードしたはずの古墳の名前を思い出せなくなってしまいました... もしご存知なら教えてくれませんか?

from:task4233 古墳

埴輪が特徴的な右の写真は、「竜角寺101号古墳」らしい。

色々パターンを変えて入れてみたけど、通りません……。

問題に画像ファイルが添付されていたのを見落としていた。ツイートの左の写真だった。「龍角寺古墳群 石室」とかで検索していたら、同じものを見つけた。でも、龍角寺古墳群の近くの別の古墳なのか。

taskctf{上福田岩屋古墳}

douro

寝る前はその時点で出題されていた全ての問題を解いて1位だったのに、この問題を解くのが遅くて4位になってしまった。12時に出題されると分かっていたのだから、早起きすれば……と思ったけど、私が解いた時間と他の人の時間を見るに、ちゃんと12時に起きても1位は無理そうだった。

この写真が撮られた場所の緯度と経度を教えてください!

douro.jpeg

右下に薄らと見える

WITHERS
MATHEIS

は選挙ポスターらしい。

元の画像を見ると、「Irvine Ranch Water District」という文字があり、地区名が分かる。

右端の白飛びしている看板に書かれている文字「Culvar」は道の名前。この道沿いに写真の場所を探せば良い。ここ。

「緯度経度は十進法で小数点以下四桁目を切り捨てたものとします」って問題文に書かれているのに、小数点以下4桁で答えようとして、少し手間取った :rolling_eyes:

taskctf{33.693_-117.798}

tutorial

submit_flat

Flagを提出してみましょう!

書かれているフラグをそのまま提出。

taskctf{th1s_1s_f14g}

just_google_it

分からないことがあれば、自分で調べてみましょう!

Base64で復号して、 Hello! がいっぱい書かれているので、消す。

$ cat base64_encoded.txt | base64 -d | sed -e 's/Hello! //g'
taskctf{Y0u_n0w_know_base64!}

taskctf{Y0u_n0w_know_base64!}

try_python

Pythonはインタプリタ型のプログラミング言語です。計算やファイルの読み書き、ネットワーク操作などを簡単に実行できるため、CTFではよく利用されます。

Pythonを使って配布ファイルに書かれた数字を全て足してみましょう! Flagは taskctf{ファイルに書かれた数の合計} です。

>>> print(sum(map(int, open("numbers.txt").read().split())))
250000

taskctf{250000}

build_docker_environment

DockerとはOSレベルの仮想化技術です。簡単にいうと、どのPCでも同じ環境をコマンド1つで作成できるようになります。これにより、皆さんのPC上でもデバッグを行うことができます。

配布ファイルに含まれるapp/app.pyのコメントを外してDockerコンテナを起動し、Flagを取得してみましょう!

app.py
 :
@app.route("/", methods=["GET"])
def index_get():
    # enable the line below!
	# return render_template('index.html', flag=os.getenv('FLAG'))
 :

環境変数は .env に書かれている。あ、Dockerコンテナを動かしていなかった。

taskctf{D1d_y0u_run_d0cker_c0nta1ner?}

2
0
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
2
0