💾 Archived View for 0x80.org › gemlog › 2014-09-27-vortex-14-15.gmi captured on 2022-04-28 at 17:41:00. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2021-12-03)
-=-=-=-=-=-=-
Continuing previous series of vortex here[1].
Bad Encryption
Based on something seen in the “real world”, it has weak encryption usage, used over a TCP/IP connection. This level requires you to apply some logic to the challenge at hand. You must login to vortex.labs.overthewire.org to complete this level.
The > indicates traffic “from the server, to the client”, and the < indicates traffic “from the client, to the server”.
If you need some hints, consider how you can divide and conquer the problem. For example, does it look like symmetric encryption, or asymmetric encryption? How can you further classify them?
So we get this file
zeus:l14 # hexdump -C raw 00000000 3e 20 73 69 6c 6c 79 6c 65 76 65 6c 2d 2d 50 db |> sillylevel--P.| 00000010 5b 09 6c ce f6 98 0a 3c 20 fb 76 3e 64 d3 72 94 |[.l....< .v>d.r.| 00000020 8f a6 a9 4d 43 c8 a4 85 b8 09 c6 c2 fa 69 51 96 |...MC........iQ.| 00000030 0a 3e 20 fb 76 3e 64 d3 72 ab bf 93 8f 64 21 ae |.> .v>d.r....d!.| 00000040 d8 e3 be 0a |....| 00000044
We can split The lines form the beginning of > and < to see what was sent/recieved, and we get three files, a,b, and c.
zeus:l14 # cat a | rax2 -S 73696c6c796c6576656c2d2d50db5b096ccef6980a zeus:l14 # cat b | rax2 -S fb763e64d372948fa6a94d43c8a485b809c6c2fa6951960a zeus:l14 # cat c | rax2 -S fb763e64d372abbf938f6421aed8e3be0a
This says we recieved a from server and sent b then recieved c. This data is encrypted. The first one is probably the authentication/key. After some testing with various ciphers I find that the used one is RC4 and the key is in a after the username/plaintext which is 50db5b096ccef698. We use the key to decrypt the rest
#!/usr/bin/env python2 def rc4crypt(data, key): x = 0 box = range(256) for i in range(256): x = (x + box[i] + ord(key[i % len(key)])) % 256 box[i], box[x] = box[x], box[i] x = 0 y = 0 out = [] for char in data: x = (x + 1) % 256 y = (y + box[x]) % 256 box[x], box[y] = box[y], box[x] out.append(chr(ord(char) ^ box[(box[x] + box[y]) % 256])) return ''.join(out) if __name__ == '__main__': fd = open("raw", "r") dd = fd.readlines() rckey = dd[0][len("> sillylevel--"):].strip("\x0a") print "rckey : %s" % rckey.encode("hex") print rc4crypt(dd[1][2:], rckey) print rc4crypt(dd[2][2:], rckey)
and result is
rckey : 50db5b096ccef698 LOGIN level15:3J=oL5fcea LOGIN SUCCESSFUL>
Weak Encryption
You have found an encrypted file, decrypt it (some reversing, crypt and general analysis needed, and if you’re lazy, the password is 8-bytes long and contains values between A and Z). You must login to vortex.labs.overthewire.org to complete this level.
I connect and I find a binary that does encryption/decryption and an encrypted file ending with .tar.Z. This extension refer to a file compressed with tar and the older utility compress not to mix it with gzip it uses a slightly different format.
Let us take a look at how it does encryption/decryption.
so it opens a file, reads its content, taking each byte doing a ~ then xoring it with a key[i&7]. The &7 tell us that the password is 8 bytes long. So we need to find a password 8 bytes long that does the decryption. How ? Well, let us take a look at how a regular tar.z file of similar size "469 bytes" look like.
zeus:l15 # hexdump -C As.tar.Z | head 00000000 1f 9d 90 41 e6 00 18 48 b0 a0 c1 83 08 13 2a 5c |...A...H......*\| 00000010 c8 b0 a1 43 84 30 22 c2 b0 41 83 06 00 89 18 2f |...C.0"..A...../| 00000020 62 8c a8 11 63 0c 19 32 3e 02 f8 48 23 46 0c 1a |b...c..2>..H#F..| 00000030 11 67 d4 b0 71 31 46 4a 8b 20 60 3c 9c 49 b3 a6 |.g..q1FJ. `<.I..| 00000040 cd 9b 00 ea cc a1 13 46 0e 08 10 00 e4 bc 79 43 |.......F......yC| 00000050 07 67 42 a1 44 8d 2a 5d ca b4 a9 d3 a7 50 67 06 |.gB.D.*].....Pg.| 00000060 11 32 84 48 91 a9 55 af 52 b5 8a 95 eb 56 ad 59 |.2.H..U.R....V.Y| 00000070 bb 82 f5 1a f6 ab d8 b3 66 d3 96 5d 4b b6 ed d8 |........f..]K...| 00000080 b7 68 d9 c2 55 eb 36 6e 5d ba 73 e5 da cd 7b 57 |.h..U.6n].s...{W| 00000090 2f de bd 80 ff 0a f6 4b b8 af 61 be 88 03 17 4e |/......K..a....N|
So if we take an encrypted file and ~ every byte then xor it with a sample. This will result in the key used to encrypt. Code that does this.
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <unistd.h> uint8_t *read_sample(const char *sample_name, size_t enc_sz); uint8_t *read_sample(const char *sample_name, size_t enc_sz) { uint8_t *res; size_t res_sz; FILE *fd; fd = fopen(sample_name, "rb"); if (fd == NULL) { perror("fopen"); return NULL; } fseek(fd, 0, SEEK_END); res_sz = ftell(fd); if (res_sz != enc_sz) { printf("Invalid size\n"); fclose(fd); return NULL; } fseek(fd, 0, SEEK_SET); res = malloc(res_sz * sizeof(uint8_t)); if (res == NULL) { perror("malloc"); return NULL; } if (fread(res, res_sz, sizeof(uint8_t), fd) <= 0) { return NULL; } fclose(fd); return res; } int main(int argc, char *argv[]) { uint8_t *enc; uint8_t *sample; size_t enc_sz; FILE *fd; int i; if (argc != 2) { printf("Usage : %s <filename>\n", argv[0]); return -1; } fd = fopen(argv[1], "rb"); if (fd == NULL) return -1; fseek(fd, 0, SEEK_END); enc_sz = ftell(fd); fseek(fd, 0, SEEK_SET); enc = malloc(enc_sz * sizeof(uint8_t)); if (enc == NULL) return -1; if (fread(enc, enc_sz, sizeof(uint8_t), fd) <= 0) { return -1; } sample = read_sample("./As.tar.Z", enc_sz); if (sample == NULL) { printf("Unable to read sample\n"); return -1; } for (i = 0; i < enc_sz; i++) { enc[i] = ~enc[i]; enc[i] ^= sample[i]; } write(1, enc, enc_sz); free(enc); free(sample); return 0; }
we run and see the output
zeus:l15 # gcc solution.c -o solution -m32 -Wall zeus:l15 # ./solution ./vortex15.tar.Z.enc | hexdump -C 00000000 5a 51 53 73 79 fc 62 2a cd fd 0f eb 67 bf 89 bc |ZQSsy.b*....g...| 00000010 91 41 53 d1 42 64 42 c9 76 58 61 f5 84 46 4e 0f |.AS.BdB.vXa..FN.| 00000020 fc 5d fa 83 a4 45 40 73 5c 21 17 e8 53 a6 07 c9 |.]...E@s\!..S...| 00000030 6b 73 2d 65 01 b6 83 07 d1 6a 52 bd 4d 3c e3 21 |ks-e.....jR.M<.!| 00000040 1a 5c 72 d8 41 7d 41 24 52 59 53 61 95 f2 27 48 |.\r.A}A$RYSa..'H| 00000050 e9 9e 40 79 70 2f b9 15 b3 e2 fe 8a e6 75 f8 d7 |..@yp/.......u..| 00000060 da 30 31 d7 49 4e 07 4d 46 49 a3 d1 01 c5 41 78 |.01.IN.MFI....Ax| 00000070 22 59 bb 00 41 c7 09 c5 4b c2 55 45 49 f4 ea 07 |"Y..A...K.UEI...| 00000080 da 4c ca 23 5d 1c d3 23 0f d1 48 b8 51 a4 5b b1 |.L.#]..#..H.Q.[.| 00000090 79 14 f1 f1 aa 66 fd 78 40 13 ee 55 be 98 88 c2 |y....f.x@..U....| 000000a0 8d cf ee bb b6 a5 82 42 92 66 fa ee 3e be a5 b4 |.......B.f..>...| 000000b0 9d 0e 23 ea 77 f7 9c ba c7 ea ec 7c d9 f9 37 a7 |..#.w......|..7.| 000000c0 99 f6 48 4e c4 dc 38 b1 b8 98 d8 1a 07 32 5f 33 |..HN..8......2_3| 000000d0 2e b2 96 d1 ae 64 32 b8 40 25 bf 58 0d 07 dc 56 |.....d2.@%.X...V| 000000e0 e7 c6 fd 6a e6 09 d4 17 67 39 c4 b8 95 ac 06 e2 |...j....g9......| 000000f0 24 62 33 19 40 99 e4 26 7d 51 76 aa 74 68 9a b4 |$b3.@..&}Qv.th..| 00000100 e3 71 d5 42 a4 b6 a3 35 0f f9 4f 5f 1d 3c 32 a0 |.q.B...5..O_.<2.| 00000110 43 dc 16 38 ff 46 da 73 7b 29 85 cc 3a fb 43 38 |C..8.F.s{)..:.C8| 00000120 4b b2 4c d9 98 dd c0 9a ca 90 9d 0c da 1b 9d a9 |K.L.............| 00000130 bc cb 6c 1f 58 62 ca 6f e4 69 f1 de 6f 96 ca a6 |..l.Xb.o.i..o...| 00000140 c5 26 79 5e 3f a0 55 9f 57 51 51 6a b9 f4 c0 4e |.&y^?.U.WQQj...N| 00000150 5e 55 03 11 40 4d 73 61 1a 52 56 79 01 44 43 5f |^U..@Msa.RVy.DC_| 00000160 4a 1e 74 51 41 44 43 41 5a 51 53 51 41 44 43 41 |J.tQADCAZQSQADCA| 00000170 5a 51 53 51 a1 15 63 41 5a 55 93 f5 84 44 43 41 |ZQSQ..cAZU...DCA| 00000180 5a 51 53 51 41 44 43 41 5a 51 53 51 41 44 43 41 |ZQSQADCAZQSQADCA|
So where is the key ? Well first to know exactly what does it start with we look the beginning that causes the header to be a valid compress format and it starts with ZQ then somewhere around the end of each entry or file, we'll have a the key repeating due to similarities/padding/..etc. We find 8 bytes of a repeating pattern that starts with ZQ. Key is ZQSQADCA
and
zeus:l15 # ./vortex15 ./vortex15.tar.Z.enc ZQSQADCA | tar xzvf - congrats.txt zeus:l15 # cat congrats.txt How did you like that level? I'd like to thank all the commercial (and not) products which has given me ideas for levels because of some of the stuff they do. This text is mainly just padding :) The password is "oY7jl4Yh," .. enjoy :)