はじめに
SECCON Beginners CTF 2021 のWriteupです。
Webは別の記事です。 https://qiita.com/tm741_/items/8c9db94bf039d4dc3e5a
Crypto
simple_RSA
Let's encrypt it with RSA!
想定難易度: Beginner
eが小さいので「Low Public-Exponent Attack」を試します。こちらを参考にさせていただきました。
from Crypto.Util.number import *
import gmpy2
n = 17686671842400393574730512034200128521336919569735972791676605056286778473230718426958508878942631584704817342304959293060507614074800553670579033399679041334863156902030934895197677543142202110781629494451453351396962137377411477899492555830982701449692561594175162623580987453151328408850116454058162370273736356068319648567105512452893736866939200297071602994288258295231751117991408160569998347640357251625243671483903597718500241970108698224998200840245865354411520826506950733058870602392209113565367230443261205476636664049066621093558272244061778795051583920491406620090704660526753969180791952189324046618283
e = 3
c = 213791751530017111508691084168363024686878057337971319880256924185393737150704342725042841488547315925971960389230453332319371876092968032513149023976287158698990251640298360876589330810813199260879441426084508864252450551111064068694725939412142626401778628362399359107132506177231354040057205570428678822068599327926328920350319336256613
m,result = gmpy2.iroot(c,e)
print(long_to_bytes(m))
ctf4b{0,1,10,11...It's_so_annoying.___I'm_done}
Misc
Mail_Address_Validator
あなたのメールアドレスが正しいか調べます.
nc mail-address-validator.quals.beginners.seccon.jp 5100
想定難易度: Easy
正規表現で入力値のチェックをするのに5秒以上かかるとflagが出力されます。
とても長い文字列を送ることでflagが出力されました。
$ python -c "print('a'*100+'@'+'a'*100)" | nc mail-address-validator.quals.beginners.seccon.jp 5100
I check your mail address.
please puts your mail address.
ctf4b{1t_15_n0t_0nly_th3_W3b_th4t_15_4ff3ct3d_by_ReDoS}
depixelization
Can you depixelize it ?
想定難易度: Medium
モザイクがかかったflag文字列の画像output.png
とそれを生成するコードが配布されました。output.png
は次のようなものです。
flag先頭のctf4b
のうち「4」がかろうじて読めそうだったので見やすい画像を作ろうとしました。
想定解はflagに使われる文字を一通りモザイク化して問題と比較する方法だったようです。作問者様Writeup
数日前に見出しだけ見た記事 https://gigazine.net/news/20201207-depix/ をちゃんと読んでたら想定解の通り思いついていたかもしれません。
P・I・Xだけを重ねたモザイクにした画像を作り、それとflag画像で同じピクセルを白く消してみることにしました。
まず配布ソースを利用してP・I・Xだけを重ねてモザイクにした画像output2.png
を作ります。
import cv2
import numpy as np
images = np.full((100, 85, 3), (255,255,255), dtype=np.uint8)
flag = "1234567890123456789012345678901" # 文字数は問題画像と合わせておくが出力しない
for i in flag:
# char2img
img = np.full((100, 85, 3), (255,255,255), dtype=np.uint8)
#cv2.putText(img, i, (0, 80), cv2.FONT_HERSHEY_PLAIN, 8, (0, 0, 0), 5, cv2.LINE_AA)
# pixelization
cv2.putText(img, "P", (0, 90), cv2.FONT_HERSHEY_PLAIN, 7, (0, 0, 0), 5, cv2.LINE_AA)
cv2.putText(img, "I", (0, 90), cv2.FONT_HERSHEY_PLAIN, 8, (0, 0, 0), 5, cv2.LINE_AA)
cv2.putText(img, "X", (0, 90), cv2.FONT_HERSHEY_PLAIN, 9, (0, 0, 0), 5, cv2.LINE_AA)
simg = cv2.resize(img, None, fx=0.1, fy=0.1, interpolation=cv2.INTER_NEAREST) # WTF :-o
img = cv2.resize(simg, img.shape[:2][::-1], interpolation=cv2.INTER_NEAREST)
# concat
if images.all():
images = img
else:
images = cv2.hconcat([images, img])
cv2.imwrite("output2.png", images)
output2.pngとしてこのような画像が出力されました。
続いてoutput.pngとoutput2.pngを比較して同じなら白(255)、違っていたらoutput.pngの通りを出力してみます。
question = cv2.imread("output.png")
pix = cv2.imread("output2.png")
dst = np.where(question == pix, 255, question)
cv2.imwrite("output3.png", dst)
ctf4b{1f_y0u_p1x_y0u_c4n_d3p1x}