Skip to content

Commit a5ca6cd

Browse files
mzfrmzfr
authored andcommitted
Solution for useless admin
1 parent 6a43a07 commit a5ca6cd

File tree

2 files changed

+161
-0
lines changed

2 files changed

+161
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Useless admin
2+
3+
__PROBLEM__
4+
5+
One member of our team, piece of sh#t an#s_boss, made a huge mistake using multi time pad.
6+
7+
He knew that the OTP, if it is well applied, it is unbreakable. But this usesless brainless retard, went yoloooo.
8+
9+
Not only that, but he deleted the original plain text, so we are screwed.
10+
11+
The only thing left is the following file : cipher.json
12+
13+
It contains multiple cipher text, created using OTP and the same key.
14+
15+
So can you figure out the plain text of the cipher_flag ?
16+
17+
Flag format : Securinets{plain text here}
18+
19+
Author:BlueWhale
20+
21+
[cipher.json](https://www.ctfsecurinets.com/files/bbfe31808617c8c67fd9da96f1daa8bd/cipher.json)
22+
23+
24+
__SOLUTION__
25+
26+
Okay so this is like super xor attack or something :smile:
27+
28+
The best part about this is that I didn't had to do anything because this is common know problem and someone already have created a great [script](https://gist.github.com/intrd/a12e1bb564b1825e864efa2ebeb37874)
29+
30+
I just had to make few changes to it.
31+
32+
First this is what the json data looked.
33+
34+
```json
35+
➜ http https://www.ctfsecurinets.com/files/bbfe31808617c8c67fd9da96f1daa8bd/cipher.json | jq .
36+
{
37+
"cipher_list": [
38+
"1b0605000e14000d1b524802190b410700170e10054c11480807001806004e4f1f4f01480d411400531158141e1c100016535a480c000c031a000a160d421e004113010f13451e0c0100100a020a1a4e165f500d0c1e041a090b001d0515521c0a0410000a4f4b4d1d1c184d071600071c0a521d1706540940",
39+
"1e10524e001f11481c010010070b13024f0704590903094d0c000e4f0711000615001911454217161a1a45040149000a5218404f1e0012060b1b590a1048171741140c01174c0d49174f0c8d4fc7520211531b0b0c1e4f",
40+
"1d0c04451352001a000154431b014109450a0a0b000045490403520a1d16490008535848085942071c0d0c57101c0045111c40430c4e111c0b1b1c451d4f071712010508475518061d00060a1b0a1a4c165d",
41+
"160d074300061d071b524e06190b134e450a0b0a4d4c12411d004f014045491b4649074804001100011d4504520612451e165d53064e164e1d060d0d44541a0041031b0b06540d1a070004001d4b074800531c04101d4f",
42+
"1a1d524912521548120045021b4e1506490a0859150345531d12521b4e094909030003011148420453074d161e05540b071e4c451b000a084a1d1c04084c0b45060b060a4742070618534218070210484512020043100e191e5956111a1c001c1f0b5c",
43+
"1a1d5248000154041a1c47430d0b04000005015900140c4f04534f094e08490103000000045442111b11001b1b1d000917535a48004e021d4a0e0b0044491c03080a001a024c11490748074f02040054451a1d150c1b150d020d0e",
44+
"1a1d5249125215481613500a1b0f0d4e4d0d1c0d000700001d1c001b06004f1d0f5a11480745040a011100181c0c540d13000e44085404404a061716014e010c0308104e084e0d4911450506011853540a5304120a1a154c0a1843001b45541c481607051b431f480d001e0400000c531d01011d00124441010200190d0800000000000e54060001100a1b4d0b040d105347",
45+
"0a0607000913020d551300041d0f0f0a0003061f154c034f1b53530602004e0c030c541f0454110a1d5a001e0649190419165d00104f104e1b1a101101001b0b1705051b0642040c5341114f0e4b104f0803110b0a060f42",
46+
"160d074300061d071b524e06190b134e450a0b0a4d4c12411d004f014045491b4649074804001100011d4504520612451e165d53064e16424a1810110c00060d04440e1c02411c0c00544209001953540d165009021a1542",
47+
"1e10524e001f11481c010010070b13024f0704590903094d0c000e4f0711000615001911454217161a1a45040149000a5218404f1e0012060b1b590a1048171741140c01174c0d49174f4201001f534b0b1c074b",
48+
"1a49134d4113540a0713490d434e160f541700174f4c11480c53520a1d1100000000190d4549114512544d12000c540402034b4e0d491d40"
49+
],
50+
"cipher_flag": "1a4905410f06110c55064f430a00054e540c0a591603174c0d5f000d1b110006414c1848164516111f1100111d1b54001c17474e0e001c011f1d0a4b"
51+
}
52+
```
53+
54+
After using the [cipher.py](cipher.py) we get the output:
55+
56+
```bash
57+
➜ python2 cipher.py
58+
Fix this sentence:
59+
* *anted to ind t** y*rl*, but i'*l*settle for endin* ****s.
60+
61+
Fixed:
62+
cure let me be know a
63+
64+
('key is', 'y<w$/jtxuk*che%%:c}yw')
65+
Decrypted msg:
66+
b:r$!~tun9baqnd":tsir
67+
g,%j/ue0ij*son6'udy ~
68+
d0sa<8tbuj~ sdd,iwrw
69+
o1pg/lin9deqn6kivs:
70+
c!%m=8a0gkoas+0#siu b
71+
c!%l/k |owm en!%:f| w
72+
c!%m=8a0cxzisj(kwnatw
73+
s:p$&yvu x*guj*/:`{fb
74+
o1pg/lin9deqn6kivs:
75+
g,%j/ue0ij*son6'udy ~
76+
cudiny rrxcn++3*nt}n8
77+
78+
Private key recovered: y<w$/jtxuk*che%%:c}yw
79+
```
80+
81+
So I took the String and googled it and found the write string `I wanted to end the world, but I'll settle for ending yours`
82+
83+
Using this on __line 38__ and we get
84+
85+
```
86+
➜ python2 cipher.py
87+
Fix this sentence:
88+
* *anted to ind t** y*rl*, but i'*l*settle for endin* ****s.
89+
90+
Fixed:
91+
I wanted to end the world, but I'll settle for ending yours
92+
93+
('key is', 'Sir arthur conan doyale is one Of the best writers. i enjoy')
94+
Decrypted msg:
95+
How often have i said that whenyou have excluded the impos
96+
My name is sherlock holmes. it Is my business to know what
97+
Never trust to general impressiOns, my boy, but concentrate
98+
Education never ends, watson. iT is a series of lessons wit
99+
It is a great thing to start liFe with a small number of re
100+
It has long been an axiom of miNe that the little things ar
101+
It is a capital mistake to theoRize before one has data. in
102+
You have a grand gift for silenCe, watson. it makes you qui
103+
Education never ends, watson. iT is a series of lessons, wi
104+
My name is sherlock holmes. it Is my business to know what
105+
I am a brain, watson. the rest Of me is a mere appendix.
106+
107+
Private key recovered: Sir arthur conan doyale is one Of the best writers. i enjoy
108+
```
109+
110+
The flag was the Fixed sentence
111+
112+
FLAG - `Securinets{I wanted to end the world, but I'll settle for ending yours}`
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import requests
2+
import string
3+
import collections
4+
import sets, sys
5+
6+
r = requests.get("https://www.ctfsecurinets.com/files/bbfe31808617c8c67fd9da96f1daa8bd/cipher.json").json()
7+
ciphers = r['cipher_list']
8+
target_cipher = r['cipher_flag']
9+
10+
def strxor(a, b):
11+
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b)])
12+
13+
final_key = [None]*150
14+
known_key_positions = set()
15+
16+
for current_index, ciphertext in enumerate(ciphers):
17+
counter = collections.Counter()
18+
for index, ciphertext2 in enumerate(ciphers):
19+
if current_index != index:
20+
for indexOfChar, char in enumerate(strxor(ciphertext.decode('hex'), ciphertext2.decode('hex'))): # Xor the two ciphertexts
21+
if char in string.printable and char.isalpha(): counter[indexOfChar] += 1 # Increment the counter at this index
22+
knownSpaceIndexes = []
23+
24+
for ind, val in counter.items():
25+
if val >= 7: knownSpaceIndexes.append(ind)
26+
27+
xor_with_spaces = strxor(ciphertext.decode('hex'),' '*150)
28+
for index in knownSpaceIndexes:
29+
final_key[index] = xor_with_spaces[index].encode('hex')
30+
known_key_positions.add(index)
31+
32+
final_key_hex = ''.join([val if val is not None else '00' for val in final_key])
33+
output = strxor(target_cipher.decode('hex'),final_key_hex.decode('hex'))
34+
35+
print("Fix this sentence:")
36+
print(''.join([char if index in known_key_positions else '*' for index, char in enumerate(output)])+"\n")
37+
38+
target_plaintext = "I wanted to end the world, but I'll settle for ending yours"
39+
print("Fixed:")
40+
print(target_plaintext+"\n")
41+
42+
key = strxor(target_cipher.decode('hex'),target_plaintext)
43+
print("key is", key)
44+
45+
print("Decrypted msg:")
46+
for cipher in ciphers:
47+
print(strxor(cipher.decode('hex'),key))
48+
49+
print("\nPrivate key recovered: "+key+"\n")

0 commit comments

Comments
 (0)