Cracking Sofaware Safe@Office UTM (SBOX) Passwords

The Safe@Office UTM is a fully-integrated stateful inspection firewall, intrusion prevention, VPN and antivirus gateway, specifically designed to meet the needs of small businesses of various sizes.

You can manage the Safe@Office (SBOX) via a web interface or SSH, This product has several passwords stored in its configuration such as:

1. User passwords

2. VPN Passwords

3. Internet connection passwords

When connecting to the device using SSH and running the “show users” command, we can see all configured users and their settings, for example:

exploit@blackbox >ssh admin@sbox.exploit.co.il
admin@sbox.exploit.co.il's password:
Welcome to Safe@Office 500WP, unlimited nodes, Evaluation Version 8.0.42x 00:08:da:77:53:fa
00-08-da-77-53-fa >show users
name user
password {S}PS43OjF5NyBH
adminaccess readonly
vpnaccess false
filteroverride false
hotspotaccess false
rdpaccess false
users-manager false
networkaccess false
expire never

As you can see above the password is encrypted.

In this post I will show the process of decoding the password to its original form.

First of all I must thank Yoni.d for breaking it, sharing it and allowing me to publish his finding.

I will walk through the process Yoni used to crack it and at the end of the post you can download a python script which you can use to decode these passwords.

Lets start…

At first glance the password encoding scheme looks familiar,  It looks like Base64 Encoding.

Well,  Thats too easy right?,  Lets use python to decode it:

>>> import base64
>>> d = base64.b64decode("XH13fXM=")
>>> print d

\}w}s

The result is another encoded string (argh…),  We will also need to find which encoding was used for it.
SBOX allows us to create a password of 5 to 25 chars long,  Lets create a password of 5 chars made all of zeros: “00000“.
Our password will be encoded to: XX90eXY=


Lets decode our newly created password:

>>> import base64
>>> d = base64.b64decode("XX90eXY=")
>>> len(d)
5
>>> print d
]tyv
>>> print repr(d)
']\x7ftyv'

We can see our decoded string length is the same as our original password length which is 5 chars.
This lead us to believe that the encoding used for this password is XOR.

Here’s what we know this far:

1. The password (00000)
2. The password base64 encoded form
3. The password base64 decoded form

If the decoded string was indeed xor’d then the same key is used for encoding and decoding
here hows xor works:

X := X XOR Y
Y := X XOR Y
X := X XOR Y

You can read more about XOR at Wikipedia

We will XOR the 2nd encoded string using “0” in order to find the key that was initially used to encode it.

Lets find the decimal ASCII value of  “0”:

>>> ord("0")
48

We will also convert our decoded base64 string to its ASCII decimal values:

>>> import base64
>>> d = base64.b64decode("XX90eXY=")
>>> for char in d:
...     print ord(char),
...
93 127 116 121 118

Now we will XOR each char with 48 (which is “o“)

>>> for char in d:
...     print ord(char)^48,
...
109 79 68 73 70

Let’s convert these values to ASCII decimal values:

>>> for char in d:
...     x = ord(char)^48
...     print chr(x),
...
m O D I F

Well, The key for our 5 chars password is : “mODIF”
Next step is to create a full 25 chars password made all of zeros in order to find the whole key

Here is the base64 encoded 25 zeros password:

XX90eXZ5dXRWZ0Bif2B1YmRpQ3h1dWRHeQ==

>>> import base64
>>> d = base64.b64decode("XX90eXZ5dXRWZ0Bif2B1YmRpQ3h1dWRHeQ==")
>>> len(d)
25
>>> for char in d:
...     x = ord(char)^48
...     print chr(x),
...
m O D I F I E D f W p R O P E R T Y s H E E T w I

We found the whole key which is:  “mODIFIEDfWpROPERTYsHEETwI
Now that we found the key used to encode our password we can use it to decode it.

>>> import base64,sys
>>> key = ["m" ,"O" ,"D" ,"I" ,"F" ,"I" ,"E" ,"D" ,"f" ,"W" ,"p" ,"R" ,"O" ,"P" ,"E" ,"R" ,"T" ,"Y" ,"s" ,"H" ,"E" ,"E" ,"T" ,"w" ,"I"]
>>> d = base64.b64decode("XX90eXZ5dXRWZ0Bif2B1YmRpQ3h1dWRHeQ==")
>>> count = 0
>>> for char in d:
...     x = ord(char)
...     y = ord(key[count])
...     i = x^y
...     z = chr(i)
...     print z,
...     count += 1
...
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Whoohoo…It worked!

Lets try to decode another password, i created the password: “Passw0rd!” which was encoded to “PS43OjF5NyBH“, lets decode it…

>>> import base64,sys
>>> key = ["m" ,"O" ,"D" ,"I" ,"F" ,"I" ,"E" ,"D" ,"f" ,"W" ,"p" ,"R" ,"O" ,"P" ,"E" ,"R" ,"T" ,"Y" ,"s" ,"H" ,"E" ,"E" ,"T" ,"w" ,"I"]
>>> d = base64.b64decode("PS43OjF5NyBH")
>>> count = 0
>>> for char in d:
...     x = ord(char)
...     y = ord(key[count])
...     i = x^y
...     z = chr(i)
...     print z,
...     count += 1
...
P a s s w 0 r d !

Great it was decoded correctly.

After trying to decode several passwords we’ll encounter an exception with this password: “jhBu1232” which was encoded to “hyeGPHd7dnY=

>>> import base64,sys
>>> key = ["m" ,"O" ,"D" ,"I" ,"F" ,"I" ,"E" ,"D" ,"f" ,"W" ,"p" ,"R" ,"O" ,"P" ,"E" ,"R" ,"T" ,"Y" ,"s" ,"H" ,"E" ,"E" ,"T" ,"w" ,"I"]
>>> d = base64.b64decode("hyeGPHd7dnY=")
>>> count = 0
>>> for char in d:
...     x = ord(char)
...     y = ord(key[count])
...     i = x^y
...     z = chr(i)
...     print z,
...     count += 1
...
ê h  u 1 2 3 2

As you can see some chars wasn’t decoded correctly : “êhÂu1232

Let’s try to figure why by looking at their decimal ASCII values:

>>> for char in d:
...     x = ord(char)
...     y = ord(key[count])
...     i = x^y
...     z = chr(i)
...     print ord(z),
...     count += 1
...
234 104 194 117 49 50 51 50

Ok, our first char of the password was suppose to be “j” which has the value of “106” for some reason our decoder sees it as “234

Let’s subtract these two numbers:

234 – 106 = 128

well it seems that every value that is bigger than 128 will not be decoded correctly as you can see below:

>>> chr(234)
'\xea'
>>> chr(234-128)
'j'
>>> chr(104)
'h'
>>> chr(194)
'\xc2'
>>> chr(194-128)
'B'
>>> chr(117)
'u'
>>> chr(49)
'1'
>>> chr(50)
'2'
>>> chr(51)
'3'
>>> chr(50)
'2

This means we will need to fix the python loop to check for any char that is bigger than 127 and deal with it accordingly.

>>> import base64
>>> key = ["m" ,"O" ,"D" ,"I" ,"F" ,"I" ,"E" ,"D" ,"f" ,"W" ,"p" ,"R" ,"O" ,"P" ,"E" ,"R" ,"T" ,"Y" ,"s" ,"H" ,"E" ,"E" ,"T" ,"w" ,"I"]
>>> d = base64.b64decode("hyeGPHd7dnY=")
>>> count = 0
>>> for char in d:
...     if (ord(char)!=0):
...           x = ord(char)
...           y = ord(key[count])
...           i = x^y
...           if (i > 127) :
...               i = i - 128
...               z = chr(i)
...               print z,
...               count += 1
...           else:
...               z = chr(i)
...               print z,
...               count += 1
...
j h B u 1 2 3 2

Great our encoded password was decoded correctly this time.

You can download the SBOX Password Cracker Python Script Here:

Sofaware SBOX Password Cracker
spc.tar.gz
You need to login to access to the attachmentsTitle: spc.tar.gz (81 clicks)
Caption: Sofaware SBOX Password Cracker
Filename: spc.tar.gz
Size: 865 B

SBOX Password Cracker

SBOX Password Cracker

Post to Twitter

Comments are closed on this post.

Recent Posts