Article

Cracking SAP password – Cracking bcode

16-01-2015

Cracking BCODE

We can use the weakness of the BCODE algorithm to our advantage when we create ad-hoc wordlists. There are some simple operations we can perform on our wordlists; we can use vi regular expressions to accomplish these operations. For example, let’s suppose we have a wordlist with names called names.txt, the command we would execute are:

$ vi names.txt
:%s/^\(.\{8}\).\+/\1/g
:sort u
:%s/.*/\U&/g
:w names_bcode.txt
:q!

What we have done with the commands above is rather clear: we opened the wordlist file “names.txt“, trunked every word longer than 8 characters, sorted everything and removed the doubled entries with “unique“, then we converted to uppercase every lowercase character and we saved the result in “names_bcode.txt“, also we keep the original file as we could reuse it as it is.

Now we can start the cracking process using john with its rules that will be applied to our wordlists. A good list of rules was made by KoreLogic so add them to john.conf and while you are at it you can add custom rules tailored to our environments. Use your intuition and the knowledge, if any, of previous cracked passwords in the same environment to create custom rules. Also, it may sounds silly but, if you are performing an in-house pentest then take a good look around you and notice every word you find around you, that is room names, especially server room names, company’s slogan. It happened to me to find out that one of the server room name was combined with numbers in a password. Seems like there’s a strong limit on system administrators’ creativity when it comes down to choose a password. Note that the special characters that can be used in a SAP password are: !"@ $%&/()=?'`*+~#-_.,;:{[]}\<>| and space. The grave accent (À, à, È, è, etc.) is used only in the PASSCODE.

[List.Rules:Append2Num]
cAz"[0-9][0-9]"
Az"[0-9][0-9]"

[List.Rules:Prepend2Num]
cA0"[0-9][0-9]"
A0"[0-9][0-9]"

[List.Rules:Append3Num]
cAz"[0-9][0-9][0-9]"
Az"[0-9][0-9][0-9]"

[List.Rules:Prepend3Num]
cA0"[0-9][0-9][0-9]"
A0"[0-9][0-9][0-9]"

[List.Rules:AppendSpecial]
cAz"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
Az"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"

[List.Rules:PrependSpecial]
cA0"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
A0"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"

[List.Rules:Append2Special]
cAz"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
Az"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"

[List.Rules:Prepend2Special]
cA0"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~*][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
A0"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~*][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"

[List.Rules:AppendNumSpecial]
cAz"[0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
Az"[0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"

[List.Rules:PrependNumSpecial]
cA0"[0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
A0"[0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"

[List.Rules:AppendSpecialNum]
cAz"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ][0-9]"
Az"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ][0-9]"

[List.Rules:PrependSpecialNum]
cA0"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ][0-9]"
A0"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ][0-9]"

[List.Rules:AppendYearSpecial]
cAz"19[0-9][0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
Az"19[0-9][0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
cAz"20[01][0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
Az"20[01][0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"

[List.Rules:PrependYearSpecial]
cA0"19[0-9][0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
A0"19[0-9][0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
cA0"20[01][0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
A0"20[01][0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"

[List.Rules:AppendSpecialYear]
cAz"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]19[0-9][0-9]"
Az"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]19[0-9][0-9]"
cAz"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]20[01][0-9]"
Az"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]20[01][0-9]"

[List.Rules:PrependSpecialYear]
cA0"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]19[0-9][0-9]"
A0"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]19[0-9][0-9]"
cA0"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]20[01][0-9]"
A0"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]20[01][0-9]"

[List.Rules:AppendSpecialYearSpecial]
cAz"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]19[0-9][0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
Az"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]19[0-9][0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
cAz"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]20[01][0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"
Az"[!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]20[01][0-9][!$@#%.^&()_+\-={}|\[\]\\;':,/\<\>?`~* ]"

[List.Rules:Bcode2Passcode]
-c >2<4T[z0]T[z1]T[z2]
-c >3<5T[z0]T[z1]T[z2]T[z3]
-c >4<6T[z0]T[z1]T[z2]T[z3]T[z4]
-c >5<7T[z0]T[z1]T[z2]T[z3]T[z4]T[z5]
-c >6<8T[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]
-c >7<9T[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]

To test out the rules we can create a test file that will be used as wordlist and then execute john like this:

# echo "TEST" > wordlist
# john -w=wordlist.txt --rules=Bcode2Passcode --stdout | less

Let's then use the wordlist we created with the custom rules:

# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb -w=names_bcode.txt sap_qla_bcode.hash
# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules -w=names_bcode.txt sap_qla_bcode.hash
# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules=single-extra -w=names_bcode.txt sap_qla_bcode.hash
# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules=Append2Num -w=names_bcode.txt sap_qla_bcode.hash
# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules=Prepend2Num -w=names_bcode.txt sap_qla_bcode.hash
# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules=Append3Num -w=names_bcode.txt sap_qla_bcode.hash
# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules=Prepend3Num -w=names_bcode.txt sap_qla_bcode.hash
# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules=AppendSpecial -w=names_bcode.txt sap_qla_bcode.hash
# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules=PrependSpecial -w=names_bcode.txt sap_qla_bcode.hash
# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules=Append2Special -w=names_bcode.txt sap_qla_bcode.hash
# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules=Prepend2Special -w=names_bcode.txt sap_qla_bcode.hash
# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules=AppendNumSpecial -w=names_bcode.txt sap_qla_bcode.hash
[...]

When rules gets complex and the output longer, as in the case of adding 4 or more character at the start or the end of the word in a wordlist, we can truncate the resulting word to 4 characters then sort and unique as we did before with the 8 characters wordlist. This way we can avoid many redundant operations.

We could also optimize John the Ripper, of course, this is not the scope of this article however we can whet your appetite by looking at OpenMP to make john work with parallel processes.

We suggest the creation of a script that will run john with subsequent wordlist in a screen so we can ease ourselves from tracking out the cracking process. Before we get to other techniques, it is a good idea to reuse found passwords as wordlists to push through john's classic rules:

# vi sap_qla_bcode.pot
:%s/^.\{-}://g
:sort u
:w sap_qla_bcode.wrd
:q!

# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules -w=sap_qla_bcode.wrd sap_qla_bcode.hash
# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --rules=single-extra -w=sap_qla_bcode.wrd sap_qla_bcode.hash

You can repeat this process more than once, even for the sapg format.

When wordlists are not enough

Once we have tried your luck with wordlists and the permutations done by the rules, we can proceed with the next attack: Markov Chains. These chains, using a stochastic process, can be used to find new patterns (that can further be used to perform computations) that are missed by simply using wordlists. The steps needed to execute Markov chains are easy; first, we create a stats file:

# cat sap_qla_bcode.pot | sed 's/^[^:]*://g' > markov_pwd.txt
# calc_stat markov_pwd.txt qla_bcode.stats
# vi john.conf
:%s/Statsfile = .\+/Statsfile = PAHT/TO/qla_bcode.stats
:wq

You can find the calc_stat tool on the "run" directory on where you installed john. Then launch john with the following parameters:

# john --pot=sap_qla_bcode.pot --session=sap_qla_bcode --format=sapb --markov=300:0:0:8 sap_qla_bcode.hash

During this phase you can also use another tool: oclHashcat. The latest version of this tool sports algorithms to crack SAP password, both for CODVN B and CODVN F/G. In order to use this tool however we need to make a little change on the hash file, that is because oclHashcat expect a SAP file in the USERNAME$HASH format.

# cat sap_qla_bcode.hash | sed -e 's/:.*\$/$/g' > sap_qla_bcode_oclhc.hash
# cudaHashcat64.bin --session=sap_qla_bcode -o found_sap_qla_bcode.txt --increment --increment-min=3 --increment-max=8 -a 3 -m 7700 --remove sap_qla_bcode_oclhc.hash -1 ?u?d?s ?1?1?1?1?1?1?1?1

We have now created the file that oclHascat can load the BCODE from, then we launched oclHashcat to test out every possible combination, starting from 3 characters to a maximum of 8 characters, using as charset only uppercase characters, numbers and special characters. Since we launch oclHascat in bruteforce mode, it is convenient to remove, before, from the file, the passwords already cracked with john; these passwords are contained in the pot file sap_qla_boce.pot.

Of course, all these techniques can be optimized by removing less-frequently used characters or by trying first only letters and numbers to reduce the number of hashes to crack and save time on unnecessary complex operations.

Indeed, before we try with a pure bruteforce, we can also run oclhashcat using masks optimized based on the passwords we have already found. In order to do that, download the tool here PACK then use it to generate the masks in oclhashcat format, then extrapolate the most used masks:

# cat sap_qla_bcode.pot | sed 's/^[^:]*://g' > pwd_bcode.txt

python ~/PACK-0.0.4/statsgen.py pwd_bcode.txt -o pwd_bcode.masks
python ~/PACK-0.0.4/maskgen.py pwd_bcode.masks -t 172800 --showmasks --optindex -q

where t stands for the time measured in seconds, that is 172800 seconds = 48 hours = 2 days, this way we can set a fixed amount of time that we are willing to "wait" using this method.

Cracking SAP password saga

1. Introduction
2. ABAP Algorithms - BCODE and PASSCODE
3. How to retrieve hashes from a SAP ABAP System
4. The Wordlist
5. Cracking BCODE
6. Cracking PASSCODE
7. How to retrieve hashes from SAP Portal JAVA Application
8. Conclusions

Co-Author: Panfilo Salutari

L'hai trovato interessante?