De-compressing unknown file (CTF riddle)

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
cr33p
Posts: 2
Joined: Wed Aug 02, 2017 7:19 am

De-compressing unknown file (CTF riddle)

Post by cr33p »

I am trying to de-c0mpress file that was c0mpressed with unknown algorithm.
I need to find the algorithm.

Here is the file:
https://ufile.io/648r6

The extension of the file is:
Image

I am not sure if this is kind of clue.

This is a c0mpressed PNG file.

I think they are using some kind of LZRW 1, I am not sure.

I succeed to de-compress the IHeader of the file correctly (I verified it with CRC).
This the comparing between them:
Image

This is the algorithm I noticed it worked with:
Image

There is a 1 byte flag every each 8 bytes.
If the flag is > 0 I am checking its bits.
For example:
08 (0000 1000)
00 00 02 58 (00 83) 5A 08 06

The flag is 08 => 0000 1000
So it need to go 5 step forward after the flag => 00 83 ....

The dictionary looks to be built by 2 bytes, for example: 00 83
In binary:
0000 0000 1000 0011

The first 4 bits from the right are might be the length and the rest (12 bits) are probably the absolute offset.
offset length
(0000 0000 1000) (0011)

Check again the the picture of the above algorithm if you still didn't understand.

I wrote decompress algorithm according to the above picture, every 8 bytes checking the flag, if its != 0, I am going to the index it point on and take the length and the offset according to what I wrote.
The problem is that it worked for me only on the first chunk, on rest (IDAT) it didn't work.

I looked to the next flags after the first chunk dictionary (0x0 0x83) and saw a new dictionaries (0x9 0x84):
Image

My algorithm takes the 0x98 as the offset and 0x4 as the length.
Maybe there is something else that the 0x9 is response to.
I tried to calculate it in any way like that:
0x9 + 0x8, 0x9 | 0x8 and etc.
I don't see the pattern.

This is the "best" result I received with my algorithm:
Image

My algorithm:

Code: Select all

Algoritm pesudo code:

data = readFile(filePath)
i = 0
while i < len(data):
   controlbits = data[i] // controlbits is 8 bites
   i += 1
   for bit in controlbits:
      if bit == 0:
         output += data[i]
         i += 1
      else: // bit is 1
         // Example: data[i] = 0x0, data[i+1] = 0x83
         // data[i] = 0000 0000
         // data[i+1] = 1000 0011
         // dict = 0000 0000 1000 0011
         dict = data[i] << 8
         dict |=  data[i+1]

         offset = dict[0:12]
         len = dict[12:16]
         output += output[offset: offset+len]
         i += 2

Any idea ?
Last edited by cr33p on Thu Aug 03, 2017 2:12 pm, edited 1 time in total.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: De-compressing unknown file (CTF riddle)

Post by aluigi »

I have seen that even on encode.ru there were no solutions.
lzrw1 uses a control flag of 16bits while the file you provided has an 8bit one at the beginning, the compression scanner gave no results except for PUYO_LZ10 that produces a file that can be read by some image viewers but it's totally wrong.
cr33p
Posts: 2
Joined: Wed Aug 02, 2017 7:19 am

Re: De-compressing unknown file (CTF riddle)

Post by cr33p »

Yep.

I am trying to find some pattern in the dictionaries, still didn't find something special:

Code: Select all

Offset
00000014:  000083 ; match: dist=8 len=3
0000001A:  000083 ; match: dist=8 len=3
000000AA:  000984 ; match: dist=152 len=4
000000B3:  000984 ; match: dist=152 len=4
000000BB:  000984 ; match: dist=152 len=4
000000C4:  000994 ; match: dist=153 len=4
000000CC:  000995 ; match: dist=153 len=5
000000D5:  0009A4 ; match: dist=154 len=4
000000DD:  0009A4 ; match: dist=154 len=4
000000E6:  0009B3 ; match: dist=155 len=3