BCACTF write up (後半)
前半はこちら
1+1=window
ふたつの16進数をそれぞれ足し算して、アスキーコードから逆変換するとフラグが得られる。
a="0x23 0x49 0x16 0x46 0x45 0x16 0x3c 0x3c 0x45 0x64 0x16 0x37 0x3c 0x3c 0x3c 0x16 0x46 0x45 0x37 0x1e 0x49 0x16 0x46 0x49 0x16 0x1e 0x16 0x32 0x32 0x3c 0x32 0x49 0x3c 0x64 0x1e 0x32 0x3c 0x18 0x64 0x32 0x32 0x50 0x14 0x64 0x32 0x5a 0x45 0x32 0x32 0x55 0x50 0x49 0x3c 0x14 0x3c 0x5f" b="0x26 0x2b 0x0a 0x23 0x2e 0x0a 0x29 0x25 0x2e 0x15 0x0a 0x37 0x25 0x25 0x2c 0x0a 0x23 0x2e 0x37 0x09 0x2b 0x0a 0x23 0x2b 0x0a 0x21 0x0a 0x30 0x31 0x25 0x31 0x2b 0x2a 0x17 0x13 0x2d 0x2c 0x18 0x0c 0x01 0x2d 0x29 0x1c 0x11 0x2d 0x1b 0x2e 0x01 0x2d 0x1b 0x29 0x2b 0x2c 0x1c 0x32 0x1e" a.split.zip(b.split).map{|ab|(ab[0].to_i(16)+ab[1].to_i(16)).chr}.join
bca-store
やるだけ。すごく雑なコードが残っていたので一応貼る。
ans = [] 7.times do cnta,cntb,cntc,cntd=0,0,0,0 s=gets.split yen=s.pop.to_i tmp=0.0 s.each do |t| if t=='A' cnta+=1 tmp+=45 elsif t=='B' cntb+=1 tmp += cntb%2==0 ? 52*0.9 : 52 elsif t=='C' cntc+=1 tmp+=cntc%2==0 ? 67*0.5 : 67 else cntd+=1 tmp+=75 if cntd%3!=0 end end if(yen-tmp>=0) ans<<format("%.2f",yen-tmp) else ans<< -1 end end puts ans.join(" ")
instructions
やるだけ。コードはこんな感じになった。
nums = gets.split.map(&:to_i) i=0 while true line=gets.chomp next if line.length%3!=0 next if line.include?("&") print(line[nums[i]-1]) i+=1 break if i>=nums.length end
public-library
Javaのclassファイルが渡される。インターフェースを作成して実行したりするのが本線っぽいけれど、stringsで覗けばそれで解けてしまう。
manner-of-thpeaking
LISPの構文らしい。aの数が要素の番号を表しているっぽい。最初がbcactfであることからメタ読みして、コードに落とすと以下のようになった。
printables = [[*' '..'/'],[*'0'..'9'],[*':'..'@'],[*'A'..'Z'],[*'['..'`'],[*'a'..'z'],[*'{'..'~']] instructions = "cadadddddr, caddadddddr, caadddddr, caddadddddr, cadddddddddddddddddddadddddr, cadddddadddddr, caaddddddr, cadddddddddddadddr, cadadr, cadddddadr, cadddddddadr, caddddaddddr, caddddddddadr, caddddadr, cadddddadr, cadddadr, cadddadddddr, caddddaddddr, cadddddddddddddddadddddr, cadddddddddddddddddadddr, caadr, caddddddadddddr, cadddddddddddddddddadddr, caddddadr, caddddddddddddadddr, caddddddddddddadddddr, cadadr, cadddddddddddddadddddr, caddddddadddr, caddddaddddr, cadadr, cadddddadr, caddddaddddr, caddddadr, caddddddddddddddddddddddadddddr, cadddadr, caddddddddddddddddddadddr, caadr, caddddddddddddadddr, caddddadddddr, cadar, caddaddddddr" instructions.split(", ").map{|s|printables[s.split("a")[2].length-1][s.split("a")[1].length]}.join
free-real-estate
意味がわからないけれど、Bを選んだら減点された。
copypasta
discardからflagを拾ってくる。
you-wanted-it
1を出力するコードを書けばいい。何となく雰囲気がpythonっぽかったので、3系の構文で書いたら通った。
def main(): print(1) main()
for-the-night-is-dark-1
bmp画像の各ピクセルのRの値を上から順に並べる。数字をasciiコードから逆変換するとURLになるので、アクセスするとflagが得られる。Rubyだとbitmapの操作が少し辛いのでこういう感じになった。(headerのバイト数は適当です)
str = File.open("starmap.bmp") do |f| f.seek(120) f.read.unpack('H*') end str[0].split(/0+/).reverse.map{|hex| (hex.length==1 ? hex+'0' : hex).to_i(16).chr}.join[0..-2]
for-the-night-is-dark-2
1で得られるURLにアクセスする。JSのフォームがぽつんとあり、ソースコードは以下。
$("#target").submit(function( event ) { var hash = md5($("#secret").val()) if (hash == "3758002ab24653af8d550c0c50473098") { var encode = "ÐßÏ½æ¦ ÐÞÙ֩û¤× úªîÈ©¼×ÐÖËÕ§£¢Íç«ÖÉ̱ÈÕÒßÊÕÅ" var newstr = "" var key = $("#secret").val() for (var i = 0; i < encode.length; i++) { newstr += String.fromCharCode(encode.charCodeAt(i) - key.charCodeAt(i%key.length)) } window.location = "/f" + newstr } $("#secret").val("") event.preventDefault(); });
MD5のハッシュ値が3758002ab24653af8d550c0c50473098
になるものを適当に検索するとdarknight
が出てくるので入力する。
for-the-night-is-dark-3
2をクリアした後のページの英語を読むと、そのページにflagがあって、現在は削除されていることが書かれている。webarchiveで探すとflagが残ったバージョンのサイトが見つかる。
basic-pass-1
stringsで覗けばflagが丸見えだった。
scratch-that
これ好き。以下のように書き換える。
basic-pass-2
stringsで覗けばflagが丸見えだった。
basic-pass-3
パスワードが合っている部分にはビットが立つ。1文字ずつ総当たりするスクリプトを書く。
require 'socket' def main sockin = TCPSocket.open('challenges.ctfd.io', '30133') sockout = sockin response = sockin.gets ans="bcactf{" while true do (33..200).each do |t| sockin.write("#{ans+(t.chr)}\n") response1 = sockin.gets response2 = sockin.gets if response2[ans.length]=='1' ans+=t.chr break end end puts ans end end main if $PROGRAM_NAME == __FILE__
この待ってる時間好き。
the-inspector
検証ツールで探すとflagがある。
wite-out
ドラッグするとflagが隠れているとわかる。
dig-dug
与えられたhostのTXTレコードを見る。
dig -t txt hole.sketchy.dev
cookie-clicker
クッキーを書き換えてflagを購入する。
おわりに
お疲れ様でした!(最後の方の解説が雑になってごめんなさい)
公式でも解答を出すそうなので、解けなかった問題はしっかり復習します。