Introduction #
Fencry is a simple Iterative Hash based Symmetric Encryption algorithm, where the Decryption key are depends on Encrypted value itself. These Keys are not part of seclists or other gigantic wordlist, its generate by value itself.
Fencry inspired by Money Heist, Mr. Robots, and Women. You can try it by yourself on codeberg repo.
_____ _____
| __|| __|___ ___ ___ __ _
| __|| __| | _| _| | |
|___\ |_____|_|_|___|__\\_ |
/________|
info [at] zuh.reBase Evidence #
Lets say you have a “locked” door and 5 random keys, but there is just one key for locked door valid! to open this door you need to “bruteforce” or guessing by using 5 random keys.
Lets say, you trying each key with 1key/second to open the door! the worst scenario is you need 5 second time because the valid key is the last one.
But, it is too easy isn’t? what if we pretend to be a “badguy”, in a badguy perspective
Just tried those all aight? ~ badguy
If it too easy.. what if we give it more additional terms or rules, the rules suppose to make it harder. What if we need the “other” key for the “primary” key to open the locked door? so… the key are depends on the other keys. To make these key usable we need to open this key using the other key, but the key its generated by the key itself.
ParrentKey --gen--> ChildKey --gen--> ChildKey and so on.. Kind of infinity, y’all.
So, the last key will be the result of last iterative encrypted value that we supply.
Back to the our locked door, lets say we need 5 second to open the door by using 5 keys.
But now terms was applied! to open the door we need to use 5 key but those keys will gonna have a “child” key, and the child will gonna be the encrypted value we supplied.
letsay do 2 iteration:
"abc" --encrypt--> "cba" --encrypt--> "bac" “bac” is the last encrypted value, and the last value are the last key.
So, the idea is when the badguy try to crack the key, he need to crack the child first. Then iterate into a parrent key, this process will gonna waste his sources.
Back to the door, let say the term was applied. We have a 5 key and each key will gonna have a 2 child, so the total will be 15 keys. But there is 1 parrent keys valid. So, by now the worst scenario is, they badguy need to find a valid key (valid parrent key) by 15 second in total to open our locked door. That 3x wasted resource than before.
a b c d e
/\ /\ /\ /\ /\
b c c d d e e a a b
# b is valid (parent key)
# 15 keys in totalI mean, what if we iterate the parrent into “n” number, if the attacker need to crack the child first. Then he need to crack those “n child” to obtain the valid parrent. That the point.
Can you imagine what if the parrenkey iterate into 10 times, 100 times? 1.000? 10.000.000? or even infinity times? (utopia ofcourse) Then what if one of those child key got damaged? if one or more of those keys are damaged, there is no plan B to continuing cracking process. Because whole keys are generate by its parrent, because it generated by its parrent they need each other (interconnecting).
Fencry Demo #
How to Encrypt #
graph LR;
startEncryption-->inputValue;
inputValue-->computeHash;
computeHash-->check;
check--yes-->increment;
check--not-->maxIteration;
increment-->computeHash;
maxIteration-->outEncrypted;
outEncrypted-->ended;
$ val=".";time for i in {1..1001}; do val=$(printf "%s" "$val" | md5sum | awk '{print $1}'); echo "$val"; done | tee wlt.txt | sort -r | head -n 1 | base64 | tee key.txtIts called one liner of code, this code will generates a hash value from val variable, and passthrough the value into loop process for x times, but in cases we use 1001 times.
Then the 1001 hash lists will generates by val variable, and then these list (keys) are use to convert its own key to become or reverse to default val variable.
valvalue contain just.(dot).timeto calculate how many times is it to generate whole keys.forloop, the iteration of this algorithm.awkto delimited the output.teeto passthrough the output into file.sortto reverse sorting, and grep the last line.headcapture just 1 lines.
ZmZmYTQ4Yjc4ODcyZjg5Mzk1MzQ0YmUyYzBmMjMxNGYK
real 0m14.110s
user 0m9.291s
sys 0m15.464s$ ls wlt.txt key.txt -lah
-rw-r--r-- 1 root root 45 Dec 8 17:34 key.txt
-rw-r--r-- 1 root root 33K Dec 8 17:34 wlt.txt
$ wc -l wlt.txt
1001 wlt.txtkey.txtisZmZmYTQ4Yjc4ODcyZjg5Mzk1MzQ0YmUyYzBmMjMxNGYK, generate by base64 encode that encoding the last hash.wlt.txtlist of output, that contain fully of key are need by the value.
And then lets see our key that have generate by itself.
┌[ user@lnxs: fencry ]
└$ cat wlt.txt | sort -r | head -n10
fffa48b78872f89395344be2c0f2314f
ffd9053c6820e66c28c90d666f9a3f88
ff62a592e555cd64e4b11f72385f21b4
ff44494ba6aa2e40a6f98f98ad4cb55d
fee83d5d4302aa5ef18f50d5d936fcd8
fe9577bbd8164167564ed45fa45c7145
fe8e3dd4031e67f358e3f87e7dc52e01
fd824fb5813833b0b54450f34a7d6969
fd482a4828879f1493522adee37bb056
fd2d506e82809676288701f6a5813aa6
┌[ user@lnxs: fencry ]
└$ cat key.txt
ZmZmYTQ4Yjc4ODcyZjg5Mzk1MzQ0YmUyYzBmMjMxNGYK
┌[ user@lnxs: fencry ]
└$ grep -r `cat key.txt | base64 -d`
wlt.txt:fffa48b78872f89395344be2c0f2314fHow to Decrypt #
graph LR;
startDecryption;
startDecryption-->loadValue;
loadValue-->check;
check--not-->fail;
check--yes-->success;
success-->outDecrypted;
outDecrypted-->check2;
check2--not-->loadValue;
check2--yes-->ended;
Lets try to reverse or crack this algorithm, using hashcat.
┌[ user@lnxs: fencry ]
└$ cat key.txt | base64 -d | tee last.hash
fffa48b78872f89395344be2c0f2314f
┌[ user@lnxs: fencry ]
└$ hashcat -a 0 -m 0 last.hash wlt.txt --show
fffa48b78872f89395344be2c0f2314f:4bbe15e9323101d5b14d8a90e3a2c5d2Lets see how it generated and interconnected by itself.
┌[ user@lnxs: fencry ]
└$ hashcat -a 0 -m 0 wlt.txt wlt.txt --show | wc -l
1001
┌[ user@lnxs: fencry ]
└$ cat wlt.txt | md5sum | awk '{print $1}'
674caa962d4312c7210636cca346b459What about if there is damaged or lost on those key? Lets give it try.
┌[ user@lnxs: fencry ]
└$ cat wlt.txt | md5sum |awk '{print $1}'; wc -l wlt.txt
86797c6a6f81b5a817520ef10ee6a690
1000 wlt.txtI make changes into this file, and lets see how the hashcat perform!
┌[ user@lnxs: fencry ]
└$ hashcat -a 0 -m 0 wlt.txt wlt.txt --left
Hashfile 'wlt.txt' on line 1 (.8dd39384bbc8071086d720db7fe7f523): Token length exception
* Token length exception: 1/1000 hashes
This error happens if the wrong hash type is specified, if the hashes are
malformed, or if input is otherwise not as expected (for example, if the
--username option is used but no username is present)
┌[ user@lnxs: fencry ]
└$ hashcat -a 0 -m 0 wlt.txt wlt.txt --show | wc -l
1006
┌[ user@lnxs: fencry ]
└$ wc -l wlt.txt
1000 wlt.txtAs you can see, if there any changes apply into those file there is no will valid anymore. We just have 1000 hash, but it return 1006 and hashcat complaining about line 1 on those list, because it changed and 1 list have removed.
Now, where is the default value?? the . (point/dot). We just remove the first line of key, maybe it a default. Lets regenerate!
┌[ user@lnxs: fencry ]
└$ val=".";for i in {1..1001}; do val=$(printf "%s" "$val" | md5sum | awk '{print $1}'); echo "$val"; done | tee wlt.txt | sort -r | head -n 1 | base64 | tee key.txt
ZmZmYTQ4Yjc4ODcyZjg5Mzk1MzQ0YmUyYzBmMjMxNGYK
┌[ user@lnxs:fencry ]
└$ echo . | tee dot.txt
.
┌[ user@lnxs: fencry ]
└$ cat dot.txt
.
┌[ user@lnxs: fencry ]
└$ hashcat -a 0 -m 0 wlt.txt dot.txt --potfile-disable --quiet
5058f1af8388633f609cadb75a75dc9d:. # it show just . (dot)
┌[ user@lnxs: fencry ]
└$ grep "5058f1af8388633f609cadb75a75dc9d" -r
wlt.txt:5058f1af8388633f609cadb75a75dc9dIts a return 5058f1af8388633f609cadb75a75dc9d:. (dot/point) or the default input value.
Conclusion #
graph LR; Fencry --> wholeKeys; wholeKeys --> Fencry;
Those demos are demonstrated with available key lists, but what if there is no key available? and how many loop they are implement? what if there applying self damages to his own keys?
Thats is Fencry found, when I was on parking place, Fencry really depends on whole its own keys, because it’s interconnected “the parrent and child”. If keys got damaged or lost there is no recoverable plan. A simple Iterative Hash based Symmetric Encryption algorithm, Fencry found out on parking park. Inspired by Money Heist, Mr. robot, and W2omen.