3
$\begingroup$

I'm currently reverse engineering a binary that uses Blowfish. A sample input would be:

08 00 01 00 1C FB 19 00

When this data is encrypted and then decrypted, I get the following results:

encrypt: 47 D2 23 7A 57 2B 9F B0 3F B5 1E BE C6 66 54 0C
decrypt: 08 00 01 00 1C FB 19 00 94 14 EC 29 EE 4E 06 00

I'm confused about how the padding is added here. Multiple things:

  • why is there padding (2nd block) in the first place, when input is 8 bytes, which is the blowfish block size?
  • using a padding of 6 bytes seems arbitrary, why is 0x06 not on the last byte without a null character?

I had a look at the different types of cryptographic padding, and none really seem to match.

Perhaps this is something related to the block cipher mode of operation?

I've tried a couple of blowfish implementations but so far they don't seem to match.

Does this look familiar to anyone?

edit:

I've been asked why I assume this is a padding. Well, the binary does the following:

0063A1E5  |.  66:8B4C28 FE  MOV CX,WORD PTR DS:[EAX+EBP-2]
0063A1EA  |.  66:83F9 08    CMP CX,8
0063A1EE  |. /76 04         JBE SHORT <some address>
0063A1F0  |. |33C0          XOR EAX,EAX
0063A1F2  |. |5D            POP EBP
0063A1F3  |. |C3            RETN

So it's bailing when this short is bigger or equal than 8 (the block size).

It also makes sense when you consider the following:

[[08 00] 01 00 1C FB 19 00] [94 14 EC 29 EE 4E] [06 00]
    ^         ^                      ^             ^
 data size    |                    padding     pad size
          data block               6 bytes!
$\endgroup$
  • 1
    $\begingroup$ If the message is the full size of a block, a new block contains the padding. If you don't see a padding what will you think? The message ended? Usually, the IV is written first. Why don't you try with 1,2,3,4,5,6,7,8,9,10,12,13,14,and 15 bytes messages? $\endgroup$ – kelalaka Oct 16 '18 at 16:30
  • $\begingroup$ @kelalaka That was my assumption, that no padding would be required if the input was the same as the block size, though in hindsight obviously wrong. I'm less confused about the additional block, than I am about the type of padding used here. I'll try with a couple of different messages. $\endgroup$ – Daniel Sloof Oct 16 '18 at 16:44
  • $\begingroup$ @kelalaka I can only assume it's a custom crypto implementation, since the padding isn't PKCS#5 (pads like 06 06), it's not ANSI X.923 (pads like 00 06), it's not space or zero padding. $\endgroup$ – Daniel Sloof Oct 16 '18 at 19:34
  • $\begingroup$ If you want to figure out what is it, try the messages from 1 to 16 bytes. I will reveal itself, I hope. $\endgroup$ – kelalaka Oct 16 '18 at 19:37
  • $\begingroup$ How do we know it is padding and not just memory that is behind the decrypted plaintext? You haven't posted any code, and it does indeed not look like padding at all. Maybe the padding has already been removed or maybe the plaintext size was known in advance. $\endgroup$ – Maarten Bodewes Oct 17 '18 at 13:18
4
$\begingroup$

That looks like a rather stupid proprietary padding method which uses 16 bit little endian encoding - as usual for x86 based CPU's.

It seems to fill the rest with random padding, possibly to try and avoid leaking information using padding Oracle attacks.

It is a good idea to check that the size is not bigger than 8, otherwise a bad ciphertext could remove more bytes than there are in the plaintext. The code would have problems if the last partial plaintext block is 7 bytes because the padding uses two bytes and would not fit.

Possibly the code assumes statically sized packet's in the first place, so the encryption and decryption doesn't fail horribly.


I'm not sure we can say much more than that given the information in the question. The code sucks, but that's to be expected if it still deploys Blowfish - a cipher that the author himself doesn't recommend anymore.

$\endgroup$
  • $\begingroup$ Thanks for your answer. It also struck me as odd that it checks for 8 rather than 7 bytes. I suppose it really is some bad proprietary/custom implementation. I had hoped to just be able to use the same library that the original author used. Leaving question open for a bit, if there's no sudden epiphany I will accept this answer :) $\endgroup$ – Daniel Sloof Oct 17 '18 at 14:24
  • $\begingroup$ I was wrong with regards to the test, it checks if it is below or equal to 8, which is OK-ish (it leaves zero as an option). I read "bigger" instead of "below", showing that my x86 skills are waning :| I'm not sure if the code is completely invulnerable to padding oracles by the way. $\endgroup$ – Maarten Bodewes Oct 17 '18 at 14:37
  • $\begingroup$ It looks closest to ISO 10126 padding (which was withdrawn), but using a short instead of a single byte. Why, I have no clue :) $\endgroup$ – Daniel Sloof Oct 17 '18 at 14:40
  • $\begingroup$ You're right, it looks kind of like ISO padding. I would not look too deeply for clues while there may be none to be found. The author seems to have been rather clueless :) $\endgroup$ – Maarten Bodewes Oct 17 '18 at 14:43
  • $\begingroup$ Ended up just implementing the padding manually. Thanks for thinking along! $\endgroup$ – Daniel Sloof Oct 17 '18 at 15:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.