Skip to content

Commit bc97642

Browse files
committed
EKO Party writeups
1 parent 96bc1df commit bc97642

File tree

17 files changed

+919
-0
lines changed

17 files changed

+919
-0
lines changed

2017-09-17-ekoparty/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,13 @@ Team: c7f.m0d3, shalom, nazywam, cr019283
66

77
* [Angel (re)](angel)
88
* [OldPC (misc)](oldpc)
9+
* [My first app (web)](my_first_app_web)
10+
* [Warmup (re)](warmup_re)
11+
* [Malbolge (misc)](malbolge_misc)
12+
* [Shopping (pwn)](shopping_pwn)
13+
* [Shopwn (pwn)](shopwn_pwn)
14+
* [Rhapsody (re)](rhapsody_re)
15+
* [ICSS (misc/crypto)](icss_misc)
16+
* [Special (misc)](special_misc)
17+
* [COBOL (re)](cobol_re)
18+
* [Spies (dns)](spies_dns)

2017-09-17-ekoparty/cobol_re/EKO.SAVF

107 KB
Binary file not shown.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# COBOL (RE, 485p, 10 solved)
2+
3+
In the task we get an old [IBM SAVF file](EKO.SAVF).
4+
Unlike last year, where we could just load it to some online tools, this time the file was corrupted.
5+
6+
We quickly had a look around at the file contents, decoded from ebcdic string encoding, but the flag string seemed permutated, so we guessed we actually have to recover the binary and reverse it.
7+
This was a huge mistake.
8+
We wasted quite some time trying to fix this file, which had some checksum failures.
9+
10+
After a while we tried one more time to look at the strings:
11+
12+
```python
13+
import codecs
14+
import ebcdic
15+
16+
def decode():
17+
with codecs.open("EKO.SAVF", 'rb') as input_file:
18+
print(input_file.read().decode('cp1148'))
19+
```
20+
21+
We can see there a nice section:
22+
23+
```
24+
YOU ARE RIGHTWE}m_A4rREg0_RrpUN+0NI04NGsa_O+7UT3313F_+rGO3hODt0_In4DE{OASKE NOPE], YOUR SECRET IS WRONG]
25+
```
26+
27+
And from this we guess that the part:
28+
29+
```
30+
}m_A4rREg0_RrpUN+0NI04NGsa_O+7UT3313F_+rGO3hODt0_In4DE{OASKE
31+
```
32+
33+
Is the mangled flag.
34+
It's clear it's inverted, so we invert it back:
35+
36+
```
37+
EKSAO{ED4nI_0tDOh3OGr+_F3133TU7+O_asGN40IN0+NUprR_0gERr4A_m}
38+
```
39+
40+
We know that the flag starts with `EKO{` so we need to take 2 characters, remove next 2, and again take 2.
41+
We guessed we will check what happens if we proceed like this:
42+
43+
```
44+
EKO{4n0th3r+31TUO_GNINNUR_ERA_EW
45+
```
46+
47+
And inverted:
48+
49+
```
50+
WE_ARE_RUNNING_OUT13+r3ht0n4{OKE
51+
```
52+
53+
So we're on a good track, and we have first half of the flag.
54+
Since the second half is also not random, we decided to do our take-2-leave-2, but with offset of 2:
55+
56+
```
57+
SAEDI_DOOG_F337+as400+pr0gr4m}
58+
}m4rg0rp+004sa+733F_GOOD_IDEAS
59+
```
60+
61+
This way we get a second half of the flag and rest of the message blended in:
62+
63+
```
64+
EKO{4n0th3r+31337+as400+pr0gr4m}
65+
WE_ARE_RUNNING_OUTF_GOOD_IDEAS
66+
```
67+
68+
As can is noticable now, we could have just removed all uppercase and `_` characters from the initial string to get the flag as well.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# ICSS (Misc/Crypto, 471p, 18 solved)
2+
3+
A blackbox crypto challenge.
4+
We get a base64 encoded ciphertext `ypovStywDFkNEotWNc3AxtlL2IwWKuJA1qawdvYynITDDIpknntQR1gB+Nzl` and access to a service which can encrypt for us up to 6 characters of input.
5+
6+
First we need to understand how this encryption works, and for this we played a bit with it, sending specially crafted payloads.
7+
We can notice some things:
8+
9+
1. Encryption goes character by character, there are no blocks. It's easy to see when we add or remove characters.
10+
11+
2. Ciphertext for a character depends on the character itself and on the position where it is in the input. The same character on a different position encrypts differently, but the same character at the same position, even for different plaintexts gives the same encrypted value.
12+
For example:
13+
aaa -> a060a2
14+
aba -> a063a2
15+
16+
So the encryption for the last `a` stayed the same.
17+
18+
3. An exception to above rule is the first character. It affects how rest of the string is encrypted.
19+
20+
Another set of tests we did gave some interesting results.
21+
By sending `\x00\x00\x00\x00\x00\x00` bytes we got `010102030508` which looks like a Fibonacci sequence!
22+
It got even better when we sent `\x01\x00\x00\x00\x00\x00` because we got `00020305080d` which is the same sequence just shifter 1 position further (disregarding the first byte).
23+
If we now send `\x01\x05\x00\x00\x00\x00` we will get `00070305080d` so the sequence is the same but second byte is bigger by 5, which is the value we tried to encrypt.
24+
First byte encryption is unknown, but it depends only on this character, so we don't really care, it can be brute-forced.
25+
26+
We did a bit more checking and it was quite clear that the encryption does something like:
27+
1. Encrypt first byte in some special way
28+
2. Every other byte in position `k` is encrypted as `Fibonacci(first_byte + k) + kth_byte_value`
29+
30+
However, there is some weird stuff happening when overflow is reached, and it seemed some other special cases are present as well for even/odd numbers.
31+
32+
Instead of trying to figure out how to handle those issues, we decided to go the "easy" way instead.
33+
We know that by changing the first byte we can "shift" the Fibonacci sequence for the rest of the encryption, but it means that we basically shift the positions!
34+
By sending `Xa` we can get encrypted byte `a` at positon `1` with starting byte `X`, but if we send `(X+1)a` we will shift the sequence and the result will be the same as encrypted `a` at position `2` with starting byte `X`.
35+
36+
This means that we can pretty much get any encrypted byte at any position we want by encrypting only 2 bytes at a time!
37+
We use this approach with the server as "oracle" serving us the encrypted bytes and we brute-force the flag.
38+
39+
What we want to do:
40+
1. Take a single encrypted character from the encrypted flag we have at k-th position.
41+
2. Encrypt via server every possible character at k-th position and compare it with the one we have. Once they match we know what was the plaintext character.
42+
3. Repeat until we get whole flag.
43+
44+
So we run:
45+
46+
```python
47+
import base64
48+
import string
49+
50+
from crypto_commons.netcat.netcat_commons import nc, send
51+
52+
53+
def brute_character_at_position(position, expected):
54+
for c in string.letters + "{_" + string.digits + string.punctuation:
55+
if int(get_encrypted_char_at_position(c, position), 16) == ord(expected):
56+
return c
57+
return "?"
58+
59+
60+
def get_encrypted_char_at_position(character, position):
61+
return get_ciphertext(chr(ord('E') + position) + character)[2:4]
62+
63+
64+
def get_ciphertext(c):
65+
url = 'icss.ctf.site'
66+
port = 40112
67+
s = nc(url, port)
68+
s.recv(9999)
69+
s.recv(9999)
70+
send(s, c)
71+
s.recv(9999)
72+
result = s.recv(9999)
73+
return base64.b64decode(result).encode("hex")
74+
75+
76+
def main():
77+
flag_ciphertext = base64.b64decode("ypovStywDFkNEotWNc3AxtlL2IwWKuJA1qawdvYynITDDIpknntQR1gB+Nzl")
78+
flag_plaintext = "E"
79+
for i in range(len(flag_ciphertext) - 1):
80+
expected_encrypted_byte = flag_ciphertext[i + 1]
81+
flag_plaintext += brute_character_at_position(i, expected_encrypted_byte)
82+
print(flag_plaintext)
83+
print(flag_plaintext)
84+
85+
86+
main()
87+
```
88+
89+
After a while we finally get: `EKO{Mr_Leon4rd0_PisAno_Big0770_AKA_Fib@nacc!}`
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Malbolge (Web, 238p, 153 solved)
2+
3+
We can connect to a service which asks us for a Malbolge code which will print `Welcome to EKOPARTY!`:
4+
5+
```
6+
$ nc6 malbolge.ctf.site 40111
7+
nc6: using stream socket
8+
Send a malbolge code that print: 'Welcome to EKOPARTY!' (without single quotes)
9+
```
10+
11+
A bit of googling and we find http://www.matthias-ernst.eu/malbolge.html where author created [a program](finder.c) for generating Malbolge programs printing out desired output.
12+
We used it and got:
13+
14+
```
15+
bCBA@?>=<;:9876543210/.-,+*)('&%$#"!~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9y765432+O/.-,+*)i'&}C{"!~w={zyxwYutsrqponmlkjiha'Hdcba`_^]\[ZYXWVUTSRQPONMLKJIHGFED=a;@?>7[|:981U543s10/.',+*#G'&%$#"!~`|u;yxqvun4rqpRhmf,Mchgfedcba`_^]VzZYXWVUTSRQJnNM/KDIBfFEDCBA#?>=<54X810T4321q/.-,+$H('&%$#"bx>|{tyxwvutsrqponmlkd*Kafedc\"m
16+
```
17+
18+
Which in turn gave us the flag: `EKO{0nly4nother3soteric1anguage}`

0 commit comments

Comments
 (0)