Skip to content

Commit 9089b44

Browse files
committed
add nactf_error-1 challenge,
1 parent 9db427d commit 9089b44

File tree

5 files changed

+86
-1
lines changed

5 files changed

+86
-1
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Here we upload:
2727
- [UTCTF-crypto2: One True Problem](./cryptography/utctf_One-True-Problem/WRITEUP.md)
2828
- [UTCTF-crypto3: Random ECB](./cryptography/utctf_Random-ECB/WRITEUP.md)
2929
- [nactf-crypto5: Random Number Generator](./cryptography/nactf_random-number-generator/WRITEUP.md)
30+
- [nactf-crypto5: Error 1](./cryptography/nactf_error-1/WRITEUP.md)
3031
- Sites and Laboratories
3132
- [Ctflearn-p177: ALEXCTF CR2: MANY TIME SECRETS](./cryptography/ctflearn_ALEXCTF-CR2:-MANY-TIME-SECRETS/ctflearn-p177.md)
3233
- [Ctflearn-p115: Character Encoding](./cryptography/ctflearn_Character-Encoding/ctflearn-p115.md)

cryptography/nactf_error-1/WRITEUP.md

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
## Challenge name: Error 1
2+
3+
### Description:
4+
> Pranay has decided that the previous error detection scheme is a little bit too inefficient... While eating his delicious HAM-filled Italian Sub at lunch, he came up with a new idea. Fortunately, he has also invested in a less noisy communication channel.
5+
>
6+
> P.S: given files: *[error1.py](./error1.py)*, *[enc.txt](./enc.txt)*
7+
8+
### Solution:
9+
10+
This is not a cryptography but a communication systems challenge that referred to **Hamming code Error Detection**. It **XOR** the index of ones (actually, index + 1) in binary representation of each block of message and save the result number *(parity)* with the block. You can read more [here](https://en.wikipedia.org/wiki/Hamming_code).
11+
12+
In this challenge, they partitioned the message into block of size 11-bit that form a 4-bit parity and saved them at indexes of 0, 1, 3 and 7, which will form 15-bit blocks. After creating each block, they simulate one-bit error that flip a single bit. The parity number of result block will be:
13+
14+
> parity = last_parity ^ (index_of_fliped_bit + 1)
15+
16+
As we know about XOR, we can calculate **index_of_fliped_bit** as follow:
17+
18+
> index_of_fliped_bit = (parity ^ last_parity) - 1
19+
20+
So we need to partition the cipher into 15-bit blocks, calculate parity and compare it to parity that is saved with message, calculate XOR of them to get fliped bit index, and correct it.
21+
22+
**Code**
23+
24+
from functools import reduce
25+
26+
text = ''
27+
28+
with open('enc.txt', 'r') as fd:
29+
text = fd.read()
30+
31+
flag = []
32+
flag = [[int(j) for j in text[i:i + 15]] for i in range(0, len(text), 15)]
33+
34+
code = ''
35+
for i in flag:
36+
p_arr = []
37+
for j in range(4):
38+
p_arr.append(str(i[2 ** j - 1]))
39+
p_num = int(p_arr[0]) + int(p_arr[1]) * 2 + int(p_arr[2]) * 4 + int(p_arr[3]) * 8
40+
41+
parity = reduce(lambda a, b: a ^ b, [j + 1 for j, bit in enumerate(i) if (bit and j != 0 and j != 1 and j != 3 and j != 7)])
42+
parity_arr = list(reversed(list(str(format(parity, "04b")))))
43+
44+
ind = (p_num ^ parity) - 1
45+
i[ind] = int(not i[ind])
46+
47+
for j in range(15):
48+
if (j != 0 and j != 1 and j != 3 and j != 7):
49+
code += str(i[j])
50+
51+
for i in range(0, len(code), 8):
52+
print(chr(int(code[i:i+8], 2)), end='')
53+
print()
54+
55+
**The Flag**
56+
57+
nactf{hamm1ng_cod3s_546mv3q9a0te}

cryptography/nactf_error-1/enc.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
010011011010011010100011011001111110111101000101010011110111010101110110100110001100000111011101100100101111011010110001010011001110011010101111010111111010111010110111010111110110100110011011001101101101011101000111101000110100001010110100100001110110011110111011111101111000001100100011011010010111101100100100000011001101000001001010100000100111001011111101

cryptography/nactf_error-1/error1.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import random
2+
from functools import reduce
3+
4+
with open("flag.txt", "r") as fin:
5+
flag = fin.read()
6+
7+
flag = "".join(str(format(ord(c), '08b')) for c in flag) # converts flag to 8 bit ascii representation
8+
flag = [[int(j) for j in flag[i:i + 11]] for i in range(0, len(flag), 11)] # separates into 11 bit groups
9+
code = []
10+
for i in flag:
11+
for j in range(4):
12+
i.insert(2 ** j - 1, 0)
13+
parity = reduce(lambda a, b: a ^ b, [j + 1 for j, bit in enumerate(i) if bit])
14+
parity = list(reversed(list(str(format(parity, "04b"))))) # separates number into individual binary bits
15+
16+
for j in range(4):
17+
if parity[j] == "1":
18+
i[2 ** j - 1] = 1
19+
20+
# ind = random.randint(0, len(i) - 1)
21+
# i[ind] = int(not i[ind]) # simulates a one bit error
22+
code.extend(i)
23+
24+
enc = "".join([str(i) for i in code])
25+
with open("enc1.txt", "w") as fout:
26+
fout.write(enc)

cryptography/nactf_random-number-generator/WRITEUP.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ The **time.time()** will return seconds passed from 1970. So before we start the
2727
resp = r.recvline()
2828
return resp
2929

30-
Since the service use only 5 precision of time() function, and it's divided by 100, the bruteforce should not be large. Add **0.000001** to time, generate a random number, compare to **r**, till we find right seed. Then we generate two next numbers and send to server and get flag in return. let's see the code:
30+
Since the service use only 5 precision of time() function, and it's divided by 100, the bruteforce should not be large. Add **0.00001** to time, generate a random number, compare to **r**, till we find right seed. Then we generate two next numbers and send to server and get flag in return. let's see the code:
3131

3232
start_seed = round(time.time() / 100, 5)
3333

0 commit comments

Comments
 (0)