Skip to content

Commit a1b1b2c

Browse files
committed
added ectf
1 parent c726933 commit a1b1b2c

File tree

5 files changed

+417
-0
lines changed

5 files changed

+417
-0
lines changed

2016-10-23-ectf/README.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Writeup ECTF 2016
2+
3+
Team: nazywam, c7f.m0d3, cr019283, akrasuski1, shalom
4+
5+
6+
### Table of contents
7+
8+
* [number_place (misc 150)](misc_150)
9+
* [DaaS (crypto 50)](crypto_50)

2016-10-23-ectf/crypto_50/DaaS.py

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import Crypto
2+
from Crypto.PublicKey import RSA
3+
import threading
4+
import socket
5+
import sys
6+
import os
7+
8+
# e = 8257e5269cc0cdb32271154d4f5df508380e27b8826798c7271a237ff9e4191cc047629cf9684703f4826df1c69a1cfe786841d191757515abfe1a09d8bef7d92b40c6b37377e3218b109cfa734802ec418c2e08468ffcf6c11a1314600fce6714fa10fb3d5ed4a7ca89d69dc66d1f34aa9acbc8830b3319d281e0defc393ecb
9+
# n = cd67fc599866f87bc45ff87c1634aa144ee257c963ab2541052f3b38d22a11b255b0dd9318153699664b1007b7f38118df77f703909888c3930b73221c57828fc423a643b1eaf47f03d6c24b11d907f979dae4aa47347959c7c77bda8f9804dd95cc438d75ced522c7391a5d1432978440bfacc9939a33d6e6e058b15a084f99
10+
11+
class ClientThread(threading.Thread):
12+
13+
def __init__(self,ip,port,socket):
14+
threading.Thread.__init__(self)
15+
self.ip = ip
16+
self.port = port
17+
self.socket = socket
18+
self.keysFile = "/home/challenge/keys.txt"
19+
self.encrypted_flag_file = "/home/challenge/flag.encrypted"
20+
print "[+] New thread started for "+ip+":"+str(port)
21+
22+
def run(self):
23+
print "Connection from : "+ip+":"+str(port)
24+
original_ctext = open(self.encrypted_flag_file, 'r').readline()
25+
self.socket.send("Enter cipher text for which you want the plaintext.\n")
26+
ct = self.socket.recv(1024).strip()
27+
print ct
28+
if ct == original_ctext:
29+
self.socket.send("Enter a different ciphertext!\n")
30+
else:
31+
parameters = open(self.keysFile, 'r').readlines()
32+
for i in range(len(parameters)):
33+
parameters[i] = int(parameters[i], 16)
34+
parameter_tuple = tuple(parameters)
35+
key = RSA.construct(parameter_tuple)
36+
try:
37+
decrypted = key.decrypt(ct.decode('hex'))
38+
self.socket.send("Plaintext: %s" % decrypted.encode('hex'))
39+
except:
40+
self.socket.send("Invalid" + "\n")
41+
self.socket.close()
42+
43+
print "Client disconnected..."
44+
self.socket.close()
45+
46+
host = "0.0.0.0"
47+
port = 18734
48+
49+
tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
50+
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
51+
52+
tcpsock.bind((host,port))
53+
threads = []
54+
55+
while True:
56+
tcpsock.listen(4)
57+
print "\nListening for incoming connections..."
58+
(clientsock, (ip, port)) = tcpsock.accept()
59+
60+
# Let's use a new thread for each incoming connection
61+
newthread = ClientThread(ip, port, clientsock)
62+
newthread.start()
63+
threads.append(newthread)
64+
65+
for t in threads:
66+
t.join()

2016-10-23-ectf/crypto_50/README.md

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# DaaS (crypto 50)
2+
3+
###ENG
4+
[PL](#pl-version)
5+
6+
In the task we get the address of the remote service and the [source code](DaaS.py).
7+
We also get a file with RSA-encrypted flag.
8+
9+
```
10+
flag = 0xc18b1d3b892e29863d8a6b46059995173635a3fd9f2ad877143a2d14ee736d8b12f9e735d6877a553312101eb757a0e3b3795bea88f2b4f72d1eb47ef6062a0dfd659892dfb2b98c70406e0c3e5e8624e81622b772d9e4183a29c9bf2f10ef15de3bfcb112a5f76688a146466db5a8e2dfe6679806c8e0b244458296efcba450
11+
```
12+
13+
The remote service can perform RSA-decode for any input we want, apart from the flag itself.
14+
15+
The RSA implementation is not using any padding, and therefore it is homomorphic, which is what we use to break the encryption.
16+
Homomorphic property means in this case that `rsa_encrypt(a*b) = rsa_encrypt(a)*rsa_encrypt(b)` and the same goes for decrypt, since both are doing exactly the same mathematical operation - modular power.
17+
18+
RSA encryption is `ciphertext = plaintext^e (mod n)` and decryption is `plaintext = ciphertext^d (mod n)`.
19+
20+
We cannot ask the server to decrypt the flag for us, but we can ask it to decrypt `int(flag)/2`, which means we will get the value `enc_flag_2 = (enc_flag/2)^d (mod n)`.
21+
We can then ask the server to decrypt value `2` for us, which means we will get `two = 2^d (mod n)`
22+
23+
Now if we simply multiply those numbers (mod n) we will get:
24+
25+
`enc_flag_2 * two = (enc_flag/2)^d (mod n) * 2^d (mod n) = ((enc_flag/2)^d * 2^d) mod n = enc_flag^d mod n = flag`
26+
27+
So we just sent `flag/2` and `2` as inputs and then recovered flag with:
28+
29+
```python
30+
def long_to_bytes(data):
31+
data = str(hex(data))[2:-1]
32+
return "".join([chr(int(data[i:i + 2], 16)) for i in range(0, len(data), 2)])
33+
34+
n = 0xcd67fc599866f87bc45ff87c1634aa144ee257c963ab2541052f3b38d22a11b255b0dd9318153699664b1007b7f38118df77f703909888c3930b73221c57828fc423a643b1eaf47f03d6c24b11d907f979dae4aa47347959c7c77bda8f9804dd95cc438d75ced522c7391a5d1432978440bfacc9939a33d6e6e058b15a084f99
35+
enc_flag_2 = 0x120643f13ec8942b09296bb1e08c3b1608804771815e7a138560e6e5801cae4c073d5f88f3ced989743818a91290f3772614462f3fa6af7cdf5b534ccb031124656117714f7ae602016b9bd732f366be53c59501d393caba6fb12e38b5e55ffc57ccbb4ce3c7a3e2d344cf2a7e487d45c4e0c76e0cf5e8846efdce0955f81930
36+
two = 0x3a997500f5c2e8cb21996f73cc3d05f58a8f6003fa2e97481dc09f04517ffbf6ef6585f415cb2ea95449ab7ced07443e1b330deeed169bb3d88088167a37434cf1d39ce5b639c1b99a18279f26b8f2e197c0a94a291a6d2efb42adf27d082791be6e589e62dfbc85afc882996a4a68d474f0c334ef29b5a953ec4fbcff52bd38
37+
38+
print(long_to_bytes((enc_flag_2 * two) % n))
39+
40+
```
41+
42+
Which gave `ECTF{Good job! You broke RSA!}`
43+
44+
###PL version
45+
46+
W zadaniu dostajemy adres zdalnego serwera oraz [kod źródłowy](DaaS.py).
47+
Dostajemy także plik z flagą zaszyfrowaną za pomocą RSA.
48+
49+
50+
```
51+
flag = 0xc18b1d3b892e29863d8a6b46059995173635a3fd9f2ad877143a2d14ee736d8b12f9e735d6877a553312101eb757a0e3b3795bea88f2b4f72d1eb47ef6062a0dfd659892dfb2b98c70406e0c3e5e8624e81622b772d9e4183a29c9bf2f10ef15de3bfcb112a5f76688a146466db5a8e2dfe6679806c8e0b244458296efcba450
52+
```
53+
54+
Serwer pozwala zdekodować za pomocą RSA dowolne dane, oprócz samej flagi.
55+
56+
Implementacja RSA nie używa paddingu, co oznacza że operacje są homomorficzne, co pozwala nam na złamanie szyfrowania.
57+
Homomorfizm w tym kontekście oznacza, że `rsa_encrypt(a*b) = rsa_encrypt(a)*rsa_encrypt(b)` i analogicznie dla operacji deszyfrowania, ponieważ obie funkcje realizują tą samą operacje matematyczną - potęgowanie modularne.
58+
59+
Szyfrowanie RSA to `ciphertext = plaintext^e (mod n)` a deszyfrowanie `plaintext = ciphertext^d (mod n)`.
60+
61+
Nie możemy poprosić serwra o deszyfrowanie flagi, ale możemy poprosić o deszyfrowanie `int(flag)/2`, co oznacza że dostaniemy wartość `enc_flag_2 = (enc_flag/2)^d (mod n)`.
62+
Teraz możemy poprosić serwer o dekodowanie wartości `2`, co oznacza że dostaniemy `two = 2^d (mod n)`.
63+
64+
Teraz jeśli pomnożymy te liczby (mod n) dostaniemy:
65+
66+
`enc_flag_2 * two = (enc_flag/2)^d (mod n) * 2^d (mod n) = ((enc_flag/2)^d * 2^d) mod n = enc_flag^d mod n = flag`
67+
68+
Więc wysyłamy do serwera `flag/2` oraz `2` a następnie odzyskujemy flagę przez:
69+
70+
```python
71+
def long_to_bytes(data):
72+
data = str(hex(data))[2:-1]
73+
return "".join([chr(int(data[i:i + 2], 16)) for i in range(0, len(data), 2)])
74+
75+
n = 0xcd67fc599866f87bc45ff87c1634aa144ee257c963ab2541052f3b38d22a11b255b0dd9318153699664b1007b7f38118df77f703909888c3930b73221c57828fc423a643b1eaf47f03d6c24b11d907f979dae4aa47347959c7c77bda8f9804dd95cc438d75ced522c7391a5d1432978440bfacc9939a33d6e6e058b15a084f99
76+
enc_flag_2 = 0x120643f13ec8942b09296bb1e08c3b1608804771815e7a138560e6e5801cae4c073d5f88f3ced989743818a91290f3772614462f3fa6af7cdf5b534ccb031124656117714f7ae602016b9bd732f366be53c59501d393caba6fb12e38b5e55ffc57ccbb4ce3c7a3e2d344cf2a7e487d45c4e0c76e0cf5e8846efdce0955f81930
77+
two = 0x3a997500f5c2e8cb21996f73cc3d05f58a8f6003fa2e97481dc09f04517ffbf6ef6585f415cb2ea95449ab7ced07443e1b330deeed169bb3d88088167a37434cf1d39ce5b639c1b99a18279f26b8f2e197c0a94a291a6d2efb42adf27d082791be6e589e62dfbc85afc882996a4a68d474f0c334ef29b5a953ec4fbcff52bd38
78+
79+
print(long_to_bytes((enc_flag_2 * two) % n))
80+
81+
```
82+
83+
Co daje nam `ECTF{Good job! You broke RSA!}`

0 commit comments

Comments
 (0)