Skip to content

Commit 71af511

Browse files
committed
intercepted transmissions writeup
1 parent 14158f2 commit 71af511

File tree

5 files changed

+297
-41
lines changed

5 files changed

+297
-41
lines changed

mkdocs.yml

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ nav:
1111
- 'index.md'
1212
- Shufflebox: ./shufflebox/index.md
1313
- Number mashing: ./number_mashing/index.md
14+
- Intercepted transmissions: ./transmissions/index.md

solve/index.md

-41
Original file line numberDiff line numberDiff line change
@@ -11,47 +11,6 @@ description: Writeups for Down Under CTF 2024
1111
* Website: [https://downunderctf.com/](https://downunderctf.com/)
1212
* Official writeups: https://github.com/DownUnderCTF/Challenges_2024_Public
1313

14-
## Writeups
15-
16-
* [shufflebox](./shufflebox/index.md)
17-
* Solved: 582
18-
* Category: cryptography
19-
* [number mashing](./number_mashing/index.md)
20-
* Solved: 299
21-
* Category: reverse engineering
22-
* Intercepted Transmissions
23-
* Solved: 275
24-
* Category: misc
25-
* vector overflow
26-
* Solved: 239
27-
* Category: binary exploitation
28-
* decrypt then eval
29-
* Solved: 197
30-
* Category: cryptography
31-
* yawa
32-
* Solved: 184
33-
* Category: binary exploitation
34-
* DNAdecay
35-
* Solved: 148
36-
* Category: reverse engineering
37-
* sign in
38-
* Solved: 95
39-
* Category: binary exploitation
40-
* sssshhhh
41-
* Solved: 81
42-
* Category: reverse engineering
43-
* rusty vault
44-
* Solved: 81
45-
* Category: reverse engineering
46-
* jmp flag
47-
* Solved: 71
48-
* Category: reverse engineering
49-
* pac shell
50-
* Solved: 55
51-
* Category: binary exploitation
52-
53-
## Acknowledgements
54-
5514
Thank you to team 418WeAreTeapots for taking this journey with me and commiting long hours over weekends:
5615

5716
* ImTheProblem

solve/transmissions/ccir476.png

127 KB
Loading

solve/transmissions/index.md

+214
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
---
2+
id: index
3+
title: Intercepted transmissions writeup
4+
description: Writeup for challenge "Intercepted transmissions" of Down Under CTF 2024
5+
---
6+
7+
## Prologue
8+
9+
Difficulty: beginner
10+
11+
Category: miscellaneous
12+
13+
Solved: 299
14+
15+
!!! quote "Description"
16+
Those monsters! They've kidnapped the Quokkas! Who in their right mind would capture those friendly little guys.. We've managed to intercept a CCIR476 transmission from the kidnappers, we think it contains the location of our friends! Can you help us decode it? We managed to decode the first two characters as '##'
17+
18+
Input files:
19+
20+
??? info "encoding.txt"
21+
101101001101101101001110100110110101110100110100101101101010110101110010110100
22+
101110100111001101100101101101101000111100011110011011010101011001011101101010
23+
010111011100100011110101010110110101011010111001011010110100101101101010110101
24+
101011001011010011101110001101100101110101101010110011011100001101101101101010
25+
101101101000111010110110010111010110101100101100110111101000101011101110001101
26+
101101001010111001011101110001010111001011100011011
27+
28+
NB:
29+
30+
31+
* Following indices bases system is used to avoid ambiguity. Whenever element of a collection is referenced by **number**, 0-based index implied.
32+
33+
Ie, element `0` of list `[1, 2, 4, 8, 16]` is `1`, Element `3` is `8`.
34+
35+
When element is reference in explanation with **word** (first, third...), 1-based system is implied.
36+
37+
Ie, first character of string `Hello World!` is `H`, fifth is `o`.
38+
39+
* Solution code was redacted for readability purposes. Due to time pressure during the competition I was using a lot of one-letter variables and questionable code structure.
40+
41+
## My struggle
42+
43+
Quick google CCIR476 leads us to wiki page that explains that CCIR476 is a character enconding used in radio data protocol.
44+
So seems like we should start by decoding message. Article itself is not too friendly and doesn't explain much (too many
45+
technical words without definition for my liking), but there is important bit it stats that CCIR 476 is a 7-bit encoding.
46+
This allows us quickly test if our input is indeed CCID476 message without investing hours in the wrong direction:
47+
length of input is 441 which is exactly 63 7bit words. Looks promising!
48+
49+
Second link in google is https://blog.gcwizard.net/manual/en/ccitt-codes/08-what-is-ccir-476/
50+
Which contains table that can be used for decoding:
51+
![ccir476.png](./ccir476.png)
52+
53+
So in first version I created alphabet with all characters I can understand and left others (CR, LTRS, FIGS) empty:
54+
55+
!!! note "Interation 1"
56+
```py
57+
letters={
58+
"1000111": "A",
59+
"1110010": "B",
60+
"0011101": "C",
61+
"1010011": 'D',
62+
63+
"1010110": "E",
64+
"0011011": "F",
65+
"0110101": "G",
66+
67+
"1101001": "H",
68+
"1001101": "I",
69+
"0010111": "J",
70+
"0011110": "K",
71+
"1100101": "L",
72+
73+
"0111001": "M",
74+
"1011001": "N",
75+
"1110001": "O",
76+
"0101101": "P",
77+
"0101110": 'Q',
78+
"1010101": "R",
79+
80+
"1001011": "S",
81+
"1110100": "T",
82+
"1001110": "U",
83+
"0111100": "V",
84+
"0100111": "W",
85+
"0111010": "X",
86+
"0101011": "Y",
87+
"1100011": "Z",
88+
"1011100": " ",
89+
90+
"1111000": "",
91+
"0110110": "",
92+
"1011010": "",
93+
}
94+
input="101101001101101101001110100110110101110100110100101101101010110101110010110100101110100111001101100101101101101000111100011110011011010101011001011101101010010111011100100011110101010110110101011010111001011010110100101101101010110101101011001011010011101110001101100101110101101010110011011100001101101101101010101101101000111010110110010111010110101100101100110111101000101011101110001101101101001010111001011101110001010111001011100011011"
95+
96+
for i in range(0, len(input), 7): # generate sequence 0, 7, 14 ... 441
97+
word = input[i:i+7] # take 7 characters starting at i
98+
print(letters[word], end="") # print letter from alphabet that corresponds to the sequence
99+
```
100+
101+
The result is looking very promising, I can even read the sentence:
102+
```txt
103+
HHTHE QUPKKRSS ARE HELD QN FRCQLITY HQQOQQF
104+
```
105+
But some letters are wrong, and also according to description of the challenge result should start with `##`. So, how can we get
106+
from `HH` to `##`? Notice from encoding table has many columns and `1101001` is `H` in letters case, but `#` in `US TTYs`
107+
(whatever that means).
108+
109+
Probably ignored so far characters CR, LTRS and FIGS could be helpful. Explanation is very obvious, but on the day it took
110+
quite a lot of trial and errors:
111+
112+
* LTRS - switches decoding into letters mode (ie after LTRS symbols all characters are letters until FIGS is encountered)
113+
* FIGS - switching decoding into figures mode (ie all characters from now will be symbols until LTRS is encountered)
114+
115+
Second alphabet added, slightly updated decoding logic:
116+
117+
??? success "full solution"
118+
```py
119+
letters={
120+
"1000111": "A",
121+
"1110010": "B",
122+
"0011101": "C",
123+
"1010011": 'D',
124+
125+
"1010110": "E",
126+
"0011011": "F",
127+
"0110101": "G",
128+
129+
"1101001": "H",
130+
"1001101": "I",
131+
"0010111": "J",
132+
"0011110": "K",
133+
"1100101": "L",
134+
135+
"0111001": "M",
136+
"1011001": "N",
137+
"1110001": "O",
138+
"0101101": "P",
139+
"0101110": 'Q',
140+
"1010101": "R",
141+
142+
"1001011": "S",
143+
"1110100": "T",
144+
"1001110": "U",
145+
"0111100": "V",
146+
"0100111": "W",
147+
"0111010": "X",
148+
"0101011": "Y",
149+
"1100011": "Z",
150+
"1011100": " ",
151+
152+
"1111000": "",
153+
"0110110": "FIGS",
154+
"1011010": "LTRS",
155+
}
156+
157+
figures={
158+
"1010011": '$',
159+
"1000111": "-",
160+
"1110001": "9",
161+
"1010110": "3",
162+
"1011100": " ",
163+
"0011101": ":",
164+
"0011011": "!",
165+
"0110101": "&",
166+
"1101001": "#",
167+
"1100101": ")",
168+
"1001101": "8",
169+
"0010111": "`",
170+
"0011110": "(",
171+
"0111001": ".",
172+
"1011001": ",",
173+
"0101101": "0",
174+
"0101110": '1',
175+
"1010101": "4",
176+
"1001011": "'",
177+
"1110100": "5",
178+
"1001110": "7",
179+
"0111100": ";",
180+
"0100111": "2",
181+
"0111010": "/",
182+
"0101011": "6",
183+
"1100011": "\"",
184+
"1111000": "",
185+
"0110110": "FIGS",
186+
"1011010": "LTRS",
187+
}
188+
189+
mode=figures # variable to switch between letters and figures alphabets
190+
191+
input="101101001101101101001110100110110101110100110100101101101010110101110010110100101110100111001101100101101101101000111100011110011011010101011001011101101010010111011100100011110101010110110101011010111001011010110100101101101010110101101011001011010011101110001101100101110101101010110011011100001101101101101010101101101000111010110110010111010110101100101100110111101000101011101110001101101101001010111001011101110001010111001011100011011"
192+
193+
for w in range(0, len(input), 7): # generate sequence 0, 7, 14 ... 441
194+
word = input[w:w+7] # take 7 characters starting at i
195+
if mode[word] == "FIGS":
196+
mode = figures
197+
elif mode[word] == "LTRS":
198+
mode = letters
199+
else:
200+
print(mode[input[w:w+7]], end="") # print letter from alphabet that corresponds to the sequence
201+
202+
```
203+
204+
The only thing not mentioned before is I used `'` instead of `BELL` character because its not clear what that one means and
205+
single quote grammatically made sense.
206+
207+
## Epilogue
208+
209+
* Official website: [https://downunderctf.com/](https://downunderctf.com/)
210+
* Official writeups: https://github.com/DownUnderCTF/Challenges_2024_Public
211+
212+
*[LTRS]: Letter shift
213+
*[FIGS]: Figure shift
214+
*[CR]: Carriage return

solve/transmissions/solve.py

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
letters={
2+
"1000111": "A",
3+
"1110010": "B",
4+
"0011101": "C",
5+
"1010011": 'D',
6+
7+
"1010110": "E",
8+
"0011011": "F",
9+
"0110101": "G",
10+
11+
"1101001": "H",
12+
"1001101": "I",
13+
"0010111": "J",
14+
"0011110": "K",
15+
"1100101": "L",
16+
17+
"0111001": "M",
18+
"1011001": "N",
19+
"1110001": "O",
20+
"0101101": "P",
21+
"0101110": 'Q',
22+
"1010101": "R",
23+
24+
"1001011": "S",
25+
"1110100": "T",
26+
"1001110": "U",
27+
"0111100": "V",
28+
"0100111": "W",
29+
"0111010": "X",
30+
"0101011": "Y",
31+
"1100011": "Z",
32+
"1011100": " ",
33+
34+
"1111000": "",
35+
"0110110": "FIGS",
36+
"1011010": "LTRS",
37+
}
38+
39+
figures={
40+
"1010011": '$',
41+
"1000111": "-",
42+
"1110001": "9",
43+
"1010110": "3",
44+
"1011100": " ",
45+
"0011101": ":",
46+
"0011011": "!",
47+
"0110101": "&",
48+
"1101001": "#",
49+
"1100101": ")",
50+
"1001101": "8",
51+
"0010111": "`",
52+
"0011110": "(",
53+
"0111001": ".",
54+
"1011001": ",",
55+
"0101101": "0",
56+
"0101110": '1',
57+
"1010101": "4",
58+
"1001011": "'",
59+
"1110100": "5",
60+
"1001110": "7",
61+
"0111100": ";",
62+
"0100111": "2",
63+
"0111010": "/",
64+
"0101011": "6",
65+
"1100011": "\"",
66+
"1111000": "",
67+
"0110110": "FIGS",
68+
"1011010": "LTRS",
69+
}
70+
71+
mode=figures # variable to switch between letters and figures alphabets
72+
73+
input="101101001101101101001110100110110101110100110100101101101010110101110010110100101110100111001101100101101101101000111100011110011011010101011001011101101010010111011100100011110101010110110101011010111001011010110100101101101010110101101011001011010011101110001101100101110101101010110011011100001101101101101010101101101000111010110110010111010110101100101100110111101000101011101110001101101101001010111001011101110001010111001011100011011"
74+
75+
for w in range(0, len(input), 7): # generate sequence 0, 7, 14 ... 441
76+
word = input[w:w+7] # take 7 characters starting at i
77+
if mode[word] == "FIGS":
78+
mode = figures
79+
elif mode[word] == "LTRS":
80+
mode = letters
81+
else:
82+
print(mode[input[w:w+7]], end="") # print letter from alphabet that corresponds to the sequence

0 commit comments

Comments
 (0)