Skip to content

Commit c95befb

Browse files
committed
Add challenges written by Mystiz
1 parent e483a34 commit c95befb

32 files changed

+1069
-0
lines changed

calm-down/.gitkeep

Whitespace-only changes.

calm-down/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Calm Down
2+
===
3+
4+
## Category
5+
6+
Crypto
7+
8+
## Solves
9+
10+
* 1/69 (Tertiary division)
11+
12+
## Description
13+
14+
I am so excited having a chance talking to Alice. She told me to calm down - and sent me an encrypted secret.
15+
16+
* [chall.py](public/chall.py)
17+
18+
## Flag
19+
20+
`hkcert20{c4lm_d0wn_4nd_s0lv3_th3_ch4llen9e}`

calm-down/env/chall.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Challenge written by Mystiz.
2+
# Signature: PHNjcmlwdD5jb25zb2xlLmxvZygnVEhJUyBDSEFMTEVOR0UgSVMgV1JJVFRFTiBGT1IgSEtDRVJUIENURiBBTkQgSVMgTk9UIEZPUiBGUkFOS0lFIExFVU5HIFRPIFBMQUdBUklaRS4nKTwvc2NyaXB0Pg==
3+
4+
import base64
5+
import binascii
6+
import hashlib
7+
import os
8+
import random
9+
from Crypto.PublicKey import RSA
10+
from Crypto.Util.number import bytes_to_long, long_to_bytes
11+
12+
from secret import message
13+
14+
class RSAKey:
15+
def __init__(self, e, d, n):
16+
self.e = e
17+
self.d = d
18+
self.n = n
19+
20+
def encrypt(self, message):
21+
message = bytes_to_long(message)
22+
ciphertext = pow(message, self.e, self.n)
23+
return long_to_bytes(ciphertext)
24+
25+
def decrypt(self, ciphertext):
26+
ciphertext = bytes_to_long(ciphertext)
27+
message = pow(ciphertext, self.d, self.n)
28+
return long_to_bytes(message)
29+
30+
31+
class Challenge:
32+
def __init__(self, message):
33+
self.generate_key()
34+
self.message = message
35+
36+
def generate_key(self):
37+
key = RSA.generate(2048)
38+
self.key = RSAKey(key.e, key.d, key.n)
39+
40+
def get_public_key(self):
41+
n = base64.b64encode(long_to_bytes(self.key.n)).decode()
42+
print(f'[pkey] {n}')
43+
44+
def get_secret_message(self):
45+
target = long_to_bytes(random.randint(0, self.key.n-1))
46+
print(f'[targ] {base64.b64encode(target).decode()}')
47+
ciphertext = self.key.encrypt(target)
48+
ciphertext = base64.b64encode(ciphertext).decode()
49+
print(f'[shhh] {ciphertext}')
50+
51+
def send(self, ciphertext):
52+
ciphertext = base64.b64decode(ciphertext)
53+
message = self.key.decrypt(ciphertext)
54+
if message[-1:] != b'.':
55+
raise Exception('Be polite. Your message should terminate with a full-stop.')
56+
print('nice')
57+
58+
def main():
59+
c = Challenge(message)
60+
61+
while True:
62+
command = input('[cmd] ').split(' ')
63+
64+
try:
65+
if command[0] == 'send':
66+
c.send(command[1])
67+
elif command[0] == 'pkey':
68+
c.get_public_key()
69+
elif command[0] == 'read':
70+
c.get_secret_message()
71+
except:
72+
print('nope')
73+
74+
if __name__ == '__main__':
75+
main()

calm-down/env/secret.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
message = b'Hey, congratulations on solving the challenge. But please hkcert20{c4lm_d0wn_4nd_s0lv3_th3_ch4llen9e}.'

calm-down/public/chall.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Challenge written by Mystiz.
2+
# Signature: PHNjcmlwdD5jb25zb2xlLmxvZygnVEhJUyBDSEFMTEVOR0UgSVMgV1JJVFRFTiBGT1IgSEtDRVJUIENURiBBTkQgSVMgTk9UIEZPUiBGUkFOS0lFIExFVU5HIFRPIFBMQUdBUklaRS4nKTwvc2NyaXB0Pg==
3+
4+
import base64
5+
import binascii
6+
import hashlib
7+
import os
8+
from Crypto.PublicKey import RSA
9+
from Crypto.Util.number import bytes_to_long, long_to_bytes
10+
11+
from secret import message
12+
13+
class RSAKey:
14+
def __init__(self, e, d, n):
15+
self.e = e
16+
self.d = d
17+
self.n = n
18+
19+
def encrypt(self, message):
20+
message = bytes_to_long(message)
21+
ciphertext = pow(message, self.e, self.n)
22+
return long_to_bytes(ciphertext)
23+
24+
def decrypt(self, ciphertext):
25+
ciphertext = bytes_to_long(ciphertext)
26+
message = pow(ciphertext, self.d, self.n)
27+
return long_to_bytes(message)
28+
29+
30+
class Challenge:
31+
def __init__(self, message):
32+
self.generate_key()
33+
self.message = message
34+
35+
def generate_key(self):
36+
key = RSA.generate(2048)
37+
self.key = RSAKey(key.e, key.d, key.n)
38+
39+
def get_public_key(self):
40+
n = base64.b64encode(long_to_bytes(self.key.n)).decode()
41+
print(f'[pkey] {n}')
42+
43+
def get_secret_message(self):
44+
ciphertext = self.key.encrypt(self.message)
45+
ciphertext = base64.b64encode(ciphertext).decode()
46+
print(f'[shhh] {ciphertext}')
47+
48+
def send(self, ciphertext):
49+
ciphertext = base64.b64decode(ciphertext)
50+
message = self.key.decrypt(ciphertext)
51+
if message[-1:] != b'.':
52+
raise Exception('Be polite. Your message should terminate with a full-stop.')
53+
print('nice')
54+
55+
def main():
56+
c = Challenge(message)
57+
58+
while True:
59+
command = input('[cmd] ').split(' ')
60+
61+
try:
62+
if command[0] == 'send':
63+
c.send(command[1])
64+
elif command[0] == 'pkey':
65+
c.get_public_key()
66+
elif command[0] == 'read':
67+
c.get_secret_message()
68+
except:
69+
print('nope')
70+
71+
if __name__ == '__main__':
72+
main()

calm-down/src/solve.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: UTF-8 -*-
3+
4+
from pwn import *
5+
import requests
6+
import binascii
7+
import base64
8+
from Crypto.PublicKey import RSA
9+
from Crypto.Cipher import AES
10+
import hashlib
11+
from gmpy2 import powmod
12+
import itertools
13+
14+
def connect():
15+
HOST = 'tertiary.pwnable.hk'
16+
PORT = 50013
17+
18+
global debug
19+
if debug:
20+
context.log_level = 'debug'
21+
r = remote(HOST, PORT)
22+
return r
23+
24+
def pkey(r):
25+
r.sendlineafter('[cmd] ', 'pkey')
26+
r.recvuntil('[pkey] ')
27+
return int.from_bytes(base64.b64decode(r.recvline().strip()), 'big')
28+
29+
def read(r):
30+
r.sendlineafter('[cmd] ', 'read')
31+
r.recvuntil('[shhh] ')
32+
return int.from_bytes(base64.b64decode(r.recvline().strip()), 'big')
33+
34+
def send(r, ciphertext):
35+
ciphertext = int(ciphertext)
36+
ciphertext = int.to_bytes(ciphertext, length=(ciphertext.bit_length()+7)//8, byteorder='big')
37+
ciphertext = base64.b64encode(ciphertext).decode()
38+
r.sendlineafter('[cmd] ', f'send {ciphertext}')
39+
return r.recvline().strip() == b'nice'
40+
41+
def main():
42+
r = connect()
43+
44+
n, e = pkey(r), 65537
45+
c0 = read(r)
46+
47+
m = 1
48+
while True:
49+
print(f'[{m//2}, {m})')
50+
c = pow(0x80 * m + 1, e, n) * c0 % n
51+
if not send(r, c): break
52+
m *= 2
53+
54+
lb, rb = m//2, m
55+
while lb + 1 < rb:
56+
print(f'[{lb}, {rb})')
57+
m = (lb + rb) // 2
58+
c = pow(0x80 * m + 1, e, n) * c0 % n
59+
if send(r, c): lb = m
60+
else: rb = m
61+
62+
print('n =', n)
63+
print('k =', lb)
64+
65+
m = int(n // (0x80 * lb + 1))
66+
m = int.to_bytes(m, length=(m.bit_length()+7)//8, byteorder='big')
67+
print(m)
68+
69+
70+
if __name__ == '__main__':
71+
global debug
72+
debug = 'debug' in os.environ
73+
74+
main()

lf2/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
lf2

lf2/.gitkeep

Whitespace-only changes.

lf2/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
LF2
2+
===
3+
4+
## Category
5+
6+
Reverse Engineering
7+
8+
## Solves
9+
10+
* 1/69 (Tertiary division)
11+
* 0/74 (Secondary division)
12+
13+
## Description
14+
15+
Have you ever played Little Fighter 2? I have modified _stage.dat_ to make the game more interesting. Of course, I hid a flag inside, too.
16+
17+
* [stage.dat](public/stage.dat)
18+
19+
## Flag
20+
21+
`hkcert20{lf2_i5_st1l1_awes0me}`

lf2/public/stage.dat

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)