$plugins['authad'] = '0'; $plugins['authldap'] = '1'; $plugins['authmysql'] = '0'; $plugins['authpgsql'] = '0';
Writeup author: Radu Caragea
Task text:
Please upload 5 Windows console executable files with the same MD5 but with different printed outputs (file type: MS Windows, PE32 executable, console) The output for the files should be: File1: All Eindbazen are wearing wooden shoes File2: All Eindbazen live in a windmill File3: All Eindbazen grow their own tulips File4: All Eindbazen smoke weed all day File5: All Eindbazen are cheap bastards NOTE: The goal of this challenge is NOT to attack this webservice, this is NOT a WEB challenge.
First of all I'm not really a crypto person so I learned a lot during this challenge which, unfortunately, I didn't manage to finish during the contest.
The first attempt was to use some sort of derivative of the evilize proof-of-concept tool http://www.mscs.dal.ca/~selinger/md5collision/ which produces 'good' and 'evil' binaries that each do something else by replacing some blocks inside the binary. It didn't seem to scale for more than 2 outputs so I had to find something else. Hashclash http://code.google.com/p/hashclash/ seemed like a good alternative but it took about 4 hours for one collision so this clearly wasn't the intended solution.
The approach that yielded success was the one presented at http://cryptography.hyperlink.cz/MD5_collisions.html, which can produce blocks that collide into the same MD5.
The usefulness of collision blocks is that, because of the M-D construction, you have the following:
If MD5(BlockA) = MD5(BlockB) (even if SHA1(BlockA) != SHA1(BlockB) ) Given any binary data D: MD5(BlockA + D) = MD5(BlockB + D) (where + is the concatenation operator)
(This means that we could create an executable and append it to the 2 collision blocks and have 2 new executables with the same MD5 but unfortunately these wouldn't respect the PE format so they wouldn't run)
However, the converse is not true:
If MD5(BlockA) = MD5(BlockB) (even if SHA1(BlockA) != SHA1(BlockB) ) Given any binary data D, usually: MD5(D + BlockA) != MD5(D + BlockB) (where + is the concatenation operator)
Why is this the case? The reason is that the collision blocks were created using an IV that does not coincide with the md5 digest of the data D. Fortunately, we can give the program that creates collisions arguments to set up the IV. This means that we can have 2 executables that are identical except for a final appended block (but still have the same MD5). To setup the IV from a file I used the following:
#include <stdio.h> #include <openssl/md5.h> #include <sys/stat.h> #include <sys/mman.h> #include <stdlib.h> #include <fcntl.h> int main(int argc, char **argv) { int fin; struct stat st; void *p = NULL; MD5_CTX ctx; unsigned char final[16]; if (argv[1] == NULL) { printf("./partial_md5 </path/to/file>\n"); exit(-1); } fin = open(argv[1], O_RDONLY); if (fin < 0 ) { printf("Can't open %s\n", argv[1]); exit(-1); } stat(argv[1], &st); if (st.st_size % 64 != 0) { printf("Filesize is not a multiple of blocksize (64B)!\n"); printf("Pad it with %ld more bytes!\n", 64 - (st.st_size % 64) ); exit(-1); } p = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fin, 0); if (!p) { printf("Mmap failed\n"); exit(-1); } MD5_Init(&ctx); MD5_Update(&ctx, p, st.st_size); printf("Partial MD5 is %08X %08X %08X %08X\n", ctx.A, ctx.B, ctx.C, ctx.D); MD5_Final(final, &ctx); printf("Final MD5 is %08X %08X %08X %08X\n", ctx.A, ctx.B, ctx.C, ctx.D); return 0; }
This can be made to scale relatively easily:
Given any binary data D: Generate 2 collision block suffixes: A1 and A2: MD5(D + A1) = MD5(D + A2) Generate 2 more collision block suffixes: B1 and B2: MD5(D + A1 + B1) = MD5(D + A2 + B1) = MD5(D + A1 + B2) = MD5(D + A2 + B2) (once the md5 compression function is applied to either D+A1 or D+A2 it yields the same thing Generate 2 more collision block suffixes C1 and C2: MD5(D + A1 + B1 + C1) = MD5(D + A2 + B1 + C1) = MD5(D + A1 + B2 + C1) = MD5(D + A2 + B2 + C1) = MD5(D + A1 + B1 + C2) = MD5(D + A2 + B1 + C2) = MD5(D + A1 + B2 + C2) = MD5(D + A2 + B2 + C2)
So you can have N collisions with logN collision block generation calls.
A quick and dirty solution is to create an executable that prints the requested strings according to the executable name. Uploading this to the site will satisfy the conditions: different SHA1 sums but equal MD5 sums. However, there is no guarantee that the executables preserve their given names.
A more complex solution that actually leads to something resembling the 'evilize' tool is one that makes the collisions inside the binary rather than at the end.
#include <stdio.h> /* this initialization doesn't work with cl.exe, only gcc. */ //unsigned char buff[] = { [0 ... 4095] = 0x69}; unsigned char buff[4096] = "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"; int magic_pos1 = 0xDEADBEEF; int magic_pos2 = 0xDEADCAFE; int magic_pos3 = 0xDEADBABE; int magic_byte1 = 0x31415925; int magic_byte2 = 0x12344321; int magic_byte3 = 0xABCDDABC; int main() { int *buffer = (int *)buff; if(buffer[magic_pos1] == magic_byte1 && buffer[magic_pos2] == magic_byte2 && buffer[magic_pos3] == magic_byte3 ) puts("All Eindbazen are wearing wooden shoes"); if(buffer[magic_pos1] == magic_byte1 && buffer[magic_pos2] == magic_byte2 && buffer[magic_pos3] != magic_byte3 ) puts("All Eindbazen live in a windmill"); if(buffer[magic_pos1] == magic_byte1 && buffer[magic_pos2] != magic_byte2 && buffer[magic_pos3] == magic_byte3 ) puts("All Eindbazen grow their own tulips"); if(buffer[magic_pos1] == magic_byte1 && buffer[magic_pos2] != magic_byte2 && buffer[magic_pos3] != magic_byte3 ) puts("All Eindbazen smoke weed all day"); if(buffer[magic_pos1] != magic_byte1 && buffer[magic_pos2] == magic_byte2 && buffer[magic_pos3] == magic_byte3 ) puts("All Eindbazen are cheap bastards"); if(buffer[magic_pos1] != magic_byte1 && buffer[magic_pos2] == magic_byte2 && buffer[magic_pos3] != magic_byte3 ) puts("Mos Craciun si prietenii sai"); if(buffer[magic_pos1] != magic_byte1 && buffer[magic_pos2] != magic_byte2 && buffer[magic_pos3] == magic_byte3 ) puts("To be or not to be"); if(buffer[magic_pos1] != magic_byte1 && buffer[magic_pos2] != magic_byte2 && buffer[magic_pos3] != magic_byte3 ) puts("That is the question"); return 0; }
Note: magic_byte should actually be magic_dword, initially I didn't have everything scripted
Having a large enough buffer means that we can insert the three collision blocks inside it after compile time without any issues. The binary is thus split in three parts:
The key here is that we can use the previous approach to create 8 signatures that collide into the same MD5 when appended to the prefix. After that we can add absolutely anything to the suffix (or modify it) and the collisions are preserved. This is where the magic values come in handy, we can select what output to print by replacing them with suitable values.
root@dmns:x86_64 [example] # ./split_replace.py base.exe First three arguments should be </path/to/main_exec> <signature byte (e.g 69)> <signature byte count> root@dmns:x86_64 [example] # ./split_replace.py base.exe 69 4096 Wrote base.exe.prefix Now run ./suffix_collision.sh base.exe.prefix root@dmns:x86_64 [example] # ../suffix_collision.sh base.exe.prefix [*] Creating two suffix blocks that collide into the same MD5 for the prefix [base.exe.prefix] Partial MD5 is D9C1930D E11B6193 AE34C75F C4072C43 Final MD5 is 312D1F08 8A337C8E 67FABB21 66F2D2B0 [*] Removing previous collisions [*] Starting collision search Init vector : 0xD9C1930D,0xE11B6193,0xAE34C75F,0xC4072C43 Start from X=344122AB ... Generating block 1 ... The first block collision took : 1.070000 sec Block 1 to disk: 0 Block 2 to disk: 0 The second block collision took : 0.080000 sec The first and the second blocks together took : 1.150000 sec Generation completed. mkdir: cannot create directory 'base.exe.prefix.collision': File exists [*] Done. [*] Testing to see if it actually worked First difference is at offset X and has value Y -0000010: 8b7dbe4c .}.L e667a52e91b05ae5306638f9d4261289 base.exe.prefix.collision/binary_A e667a52e91b05ae5306638f9d4261289 base.exe.prefix.collision/binary_B root@dmns:x86_64 [example] # ../suffix_collision.sh base.exe.prefix.collision/binary_A [*] Creating two suffix blocks that collide into the same MD5 for the prefix [base.exe.prefix.collision/binary_A] Partial MD5 is 8299ACA2 B8587451 89614383 6C1B057D Final MD5 is 2EA567E6 E55AB091 F9386630 891226D4 [*] Removing previous collisions [*] Starting collision search Init vector : 0x8299ACA2,0xB8587451,0x89614383,0x6C1B057D Start from X=34624688 ... Generating block 1 ... The first block collision took : 4.780000 sec Block 1 to disk: 0 Block 2 to disk: 0 The second block collision took : 0.590000 sec The first and the second blocks together took : 5.370000 sec Generation completed. [*] Done. [*] Testing to see if it actually worked First difference is at offset X and has value Y -0000010: c52e5463 ..Tc 66eddd0eb32a970940025189fe461bf1 base.exe.prefix.collision/binary_A.collision/binary_A 66eddd0eb32a970940025189fe461bf1 base.exe.prefix.collision/binary_A.collision/binary_B root@dmns:x86_64 [example] # ../suffix_collision.sh base.exe.prefix.collision/binary_A.collision/binary_A [*] Creating two suffix blocks that collide into the same MD5 for the prefix [base.exe.prefix.collision/binary_A.collision/binary_A] Partial MD5 is 9C2E3256 5B66CB52 9EDC29AC 38CBB1DF Final MD5 is 0EDDED66 09972AB3 89510240 F11B46FE [*] Removing previous collisions [*] Starting collision search Init vector : 0x9C2E3256,0x5B66CB52,0x9EDC29AC,0x38CBB1DF Start from X=34836A64 ... Generating block 1 ... The first block collision took : 1.890000 sec Block 1 to disk: 0 Block 2 to disk: 0 The second block collision took : 2.700000 sec The first and the second blocks together took : 4.590000 sec Generation completed. [*] Done. [*] Testing to see if it actually worked First difference is at offset X and has value Y -0000010: f75d56da .]V. b5146c88229f4f401b780cade203a639 base.exe.prefix.collision/binary_A.collision/binary_A.collision/binary_A b5146c88229f4f401b780cade203a639 base.exe.prefix.collision/binary_A.collision/binary_A.collision/binary_B
This has created 3 pairs of suffixes. The first one differed from the second at position 0x10, having the value 8b7dbe4c, the next one at position 0x10, having the value c52e5463 and the third one at position 0x10, having the value f75d56da. The blocks have each 128 bytes == 0x80, so the actual offsets from the beginning of the buffer are:
What remains is just a simple pattern search and replace:
root@dmns:x86_64 [example] # ../multiplex.sh 8b7dbe4c c52e5463 f75d56da mkdir: cannot create directory 'output': File exists Signature left is now 3968 bytes long Wrote prefix + collision block + rest of signature to output/A__ Signature left is now 3968 bytes long Wrote prefix + collision block + rest of signature to output/B__ Signature left is now 3840 bytes long Wrote prefix + collision block + rest of signature to output/AA_ Signature left is now 3840 bytes long Wrote prefix + collision block + rest of signature to output/AB_ Signature left is now 3840 bytes long Wrote prefix + collision block + rest of signature to output/BB_ Signature left is now 3840 bytes long Wrote prefix + collision block + rest of signature to output/BA_ Signature left is now 3712 bytes long Wrote prefix + collision block + rest of signature to output/AAA Signature left is now 3712 bytes long Wrote prefix + collision block + rest of signature to output/AAB Signature left is now 3712 bytes long Wrote prefix + collision block + rest of signature to output/ABA Signature left is now 3712 bytes long Wrote prefix + collision block + rest of signature to output/ABB Signature left is now 3712 bytes long Wrote prefix + collision block + rest of signature to output/BAA Signature left is now 3712 bytes long Wrote prefix + collision block + rest of signature to output/BAB Signature left is now 3712 bytes long Wrote prefix + collision block + rest of signature to output/BBA Signature left is now 3712 bytes long Wrote prefix + collision block + rest of signature to output/BBB Magic patching output/AAA Patching efbeadde with 04000000 Patching fecaadde with 24000000 Patching bebaadde with 44000000 Patching 25594131 with 8b7dbe4c Patching 21433412 with c52e5463 Patching bcdacdab with f75d56da Magic patching output/AAB Patching efbeadde with 04000000 Patching fecaadde with 24000000 Patching bebaadde with 44000000 Patching 25594131 with 8b7dbe4c Patching 21433412 with c52e5463 Patching bcdacdab with f75d56da Magic patching output/ABA Patching efbeadde with 04000000 Patching fecaadde with 24000000 Patching bebaadde with 44000000 Patching 25594131 with 8b7dbe4c Patching 21433412 with c52e5463 Patching bcdacdab with f75d56da Magic patching output/ABB Patching efbeadde with 04000000 Patching fecaadde with 24000000 Patching bebaadde with 44000000 Patching 25594131 with 8b7dbe4c Patching 21433412 with c52e5463 Patching bcdacdab with f75d56da Magic patching output/BAA Patching efbeadde with 04000000 Patching fecaadde with 24000000 Patching bebaadde with 44000000 Patching 25594131 with 8b7dbe4c Patching 21433412 with c52e5463 Patching bcdacdab with f75d56da Magic patching output/BAB Patching efbeadde with 04000000 Patching fecaadde with 24000000 Patching bebaadde with 44000000 Patching 25594131 with 8b7dbe4c Patching 21433412 with c52e5463 Patching bcdacdab with f75d56da Magic patching output/BBA Patching efbeadde with 04000000 Patching fecaadde with 24000000 Patching bebaadde with 44000000 Patching 25594131 with 8b7dbe4c Patching 21433412 with c52e5463 Patching bcdacdab with f75d56da Magic patching output/BBB Patching efbeadde with 04000000 Patching fecaadde with 24000000 Patching bebaadde with 44000000 Patching 25594131 with 8b7dbe4c Patching 21433412 with c52e5463 Patching bcdacdab with f75d56da
And the final verification:
root@dmns:x86_64 [example] # for i in `ls output/*magic_fixed`; do md5sum $i; done 73ed3d82cbdcb61ff41e1791e28c91e9 output/AAA.magic_fixed 73ed3d82cbdcb61ff41e1791e28c91e9 output/AAB.magic_fixed 73ed3d82cbdcb61ff41e1791e28c91e9 output/ABA.magic_fixed 73ed3d82cbdcb61ff41e1791e28c91e9 output/ABB.magic_fixed 73ed3d82cbdcb61ff41e1791e28c91e9 output/BAA.magic_fixed 73ed3d82cbdcb61ff41e1791e28c91e9 output/BAB.magic_fixed 73ed3d82cbdcb61ff41e1791e28c91e9 output/BBA.magic_fixed 73ed3d82cbdcb61ff41e1791e28c91e9 output/BBB.magic_fixed root@dmns:x86_64 [example] # for i in `ls output/*magic_fixed`; do wine $i; done All Eindbazen are wearing wooden shoes All Eindbazen live in a windmill All Eindbazen grow their own tulips All Eindbazen smoke weed all day All Eindbazen are cheap bastards Mos Craciun si prietenii sai To be or not to be That is the question