Cracking simple XOR cipher with simulated annealing, part II: MATLAB

Previously

I've found that file in MATLAB installation for Windows (version 710 AKA 2010a). Named matinfoxml.enc:

00000000: 21 23 63 77 71 3c 6d 7f 6f 6f 72 75 73 21 39 2b  !#cwq<m.oorus!9+
00000010: 33 2c 39 25 23 20 76 7b 69 75 75 7c 72 22 27 6a  3,9%# v{iuu|r"'j
00000020: 6f 73 7f 6f 7e 68 57 73 6e 68 25 10 21 6c 69 75  os.o~hWsnh%.!liu
00000030: 79 69 78 6e 3d 7e 72 6e 20 3e 2a 2a 25 3e 3b 6c  yixn=~rn >**%>;l
00000040: 78 6e 68 73 72 72 26 38 2f 32 2e 38 3d 7a 77 7f  xnhsrr&8/2.8=zw.
00000050: 65 52 7a 77 78 21 39 5b 78 6e 74 69 6d 7d 78 7f  eRzwx!9[xntim}x.
00000060: 42 48 74 75 71 7e 74 62 3f 3c 69 7f 71 79 7a 69  BHtuq~tb?<i.qyzi
00000070: 78 21 39 48 2f 2c 2a 2a 7c 3e 3b 74 7c 71 7e 27  x!9H/,**|>;t|q~'
00000080: 3f 5d 7e 68 72 6f 6b 7b 7e 79 3b 4e 72 73 77 78  ?]~hrok{~y;Nrswx
00000090: 72 64 39 24 17 20 78 75 70 6c 74 74 78 72 6f 53  rd9$. xuplttxroS
000000a0: 59 22 2b 26 32 7f 74 77 6d 73 75 7f 73 68 52 5e  Y"+&2.twmsu.shR^
000000b0: 23 16 27 7e 78 6c 7e 74 79 79 75 79 64 3c 79 73  #.'~xl~tyyuyd<ys
000000c0: 69 21 39 2b 3f 3c 75 7b 70 79 26 38 50 5d 4f 56  i!9+?<u{py&8P]OV
000000d0: 5c 5e 39 3a 6b 79 69 69 74 73 75 27 3f 2b 35 2b  \^9:kyiitsu'?+5+
000000e0: 2d 3e 34 24 21 33 6b 68 72 78 6e 79 69 22 11 26  ->4$!3khrxnyi".&
000000f0: 6d 6e 74 7e 68 7f 6f 3a 7f 75 6f 27 3f 2b 2b 38  mnt~h.o:.uo'?++8
00000100: 3d 6a 7e 68 6e 75 74 74 20 3e 28 34 28 3e 3b 7c  =j~hnutt >(4(>;|
00000110: 71 79 63 54 7c 71 7e 27 3f 5d 7e 68 72 6f 6b 7b  qycT|q~'?]~hrok{
00000120: 7e 79 44 58 71 73 78 71 6e 79 6f 38 3d 6e 7e 76  ~yDXqsxqnyo8=n~v
00000130: 78 7d 68 7f 20 3e 49 28 2d 2d 2b 7b 3f 3c 75 7b  x}h. >I(--+{?<u{
00000140: 70 79 26 38 5c 79 69 75 6e 6c 7a 79 78 3c 59 76  py&8\yiunlzyx<Yv
00000150: 72 7f 70 69 78 68 39 24 17 20 78 75 70 6c 74 74  r.pixh9$. xupltt
00000160: 78 72 6f 53 59 22 2a 26 32 7f 74 77 6d 73 75 7f  xroSY"*&2.twmsu.
...

Clearly, some simple cipher: low-entropy file.

I modified my previous Python code to change behaviour about digits:

--- SA_XOR.py.prev      2024-05-10 17:23:28.000000000 +0300
+++ SA_XOR.py   2024-09-19 10:54:00.000000000 +0300
@@ -8,7 +8,7 @@

 # requires https://github.com/perrygeo/simanneal

-KEYLEN=17
+KEYLEN=4

 def xor_strings(s,t):
     # https://en.wikipedia.org/wiki/XOR_cipher#Example_implementation
@@ -35,7 +35,7 @@
 BONUS_FOR_SPACE=8
 BONUS_FOR_DIGRAM=8
 BONUS_FOR_TRIGRAM=16
-PENALTY_FOR_DIGIT=-10
+BONUS_FOR_DIGIT=3

 cnt=0
 def fitness(state):
@@ -48,7 +48,7 @@
         if p in b"qwertyuiopasdfghjklzxcvbnm":
             fitness=fitness+BONUS_FOR_LOWERCASE
         if p in b"0123456789":
-            fitness=fitness+PENALTY_FOR_DIGIT
+            fitness=fitness+BONUS_FOR_DIGIT
         if (p>=0x20 and p<=0x7E) or p==0xA or p==0xD:
             fitness=fitness+BONUS_FOR_PRINTABLE

Found 4-byte XOR key:

state/key:
00000000: 1D 1C 1B 1A                                       ....
decrypted:
00000000: 3C 3F 78 6D 6C 20 76 65  72 73 69 6F 6E 3D 22 31  <?xml version="1
00000010: 2E 30 22 3F 3E 3C 6D 61  74 69 6E 66 6F 3E 3C 70  .0"?><matinfo><p
00000020: 72 6F 64 75 63 74 4C 69  73 74 3E 0A 3C 70 72 6F  roductList>.<pro
00000030: 64 75 63 74 20 62 69 74  3D 22 31 30 38 22 20 76  duct bit="108" v
00000040: 65 72 73 69 6F 6E 3D 22  32 2E 35 22 20 66 6C 65  ersion="2.5" fle
00000050: 78 4E 61 6D 65 3D 22 41  65 72 6F 73 70 61 63 65  xName="Aerospace
00000060: 5F 54 6F 6F 6C 62 6F 78  22 20 72 65 6C 65 61 73  _Toolbox" releas
00000070: 65 3D 22 52 32 30 31 30  61 22 20 6E 61 6D 65 3D  e="R2010a" name=
00000080: 22 41 65 72 6F 73 70 61  63 65 20 54 6F 6F 6C 62  "Aerospace Toolb
00000090: 6F 78 22 3E 0A 3C 63 6F  6D 70 6F 6E 65 6E 74 49  ox">.<componentI
000000A0: 44 3E 30 3C 2F 63 6F 6D  70 6F 6E 65 6E 74 49 44  D>0</componentID
000000B0: 3E 0A 3C 64 65 70 65 6E  64 65 6E 63 79 20 62 69  >.<dependency bi
000000C0: 74 3D 22 31 22 20 6E 61  6D 65 3D 22 4D 41 54 4C  t="1" name="MATL
000000D0: 41 42 22 20 76 65 72 73  69 6F 6E 3D 22 37 2E 31  AB" version="7.1
000000E0: 30 22 2F 3E 3C 2F 70 72  6F 64 75 63 74 3E 0A 3C  0"/></product>.<
000000F0: 70 72 6F 64 75 63 74 20  62 69 74 3D 22 37 30 22  product bit="70"
00000100: 20 76 65 72 73 69 6F 6E  3D 22 33 2E 35 22 20 66   version="3.5" f
00000110: 6C 65 78 4E 61 6D 65 3D  22 41 65 72 6F 73 70 61  lexName="Aerospa
00000120: 63 65 5F 42 6C 6F 63 6B  73 65 74 22 20 72 65 6C  ce_Blockset" rel
00000130: 65 61 73 65 3D 22 52 32  30 31 30 61 22 20 6E 61  ease="R2010a" na
00000140: 6D 65 3D 22 41 65 72 6F  73 70 61 63 65 20 42 6C  me="Aerospace Bl
00000150: 6F 63 6B 73 65 74 22 3E  0A 3C 63 6F 6D 70 6F 6E  ockset">.<compon
00000160: 65 6E 74 49 44 3E 31 3C  2F 63 6F 6D 70 6F 6E 65  entID>1</compone
00000170: 6E 74 49 44 3E 0A 3C 64  65 16                    ntID>.<de.

I spent only ~10 minutes on that. Without digging into MATLAB code. Also, fancy video recorded.

Of course, this is not (a real) encryption, but rather, obfuscation.

All files

(the post first published at 20240919.)


List of my other blog posts.

Subscribe to my news feed,

Yes, I know about these lousy Disqus ads. Please use adblocker. I would consider to subscribe to 'pro' version of Disqus if the signal/noise ratio in comments would be good enough.