In hashcat, there are two broad approaches (and the second is probably better for your use case):
First, you can do this with rules. For the first couple of levels, you can start to do this with multiple calls of a rule ("stacked" rule) file, each line of which simply overwrites (
o) a single character in a single position with another character (
o0c, and then
o1c, etc.) The rules file should also contain the no-op "passthrough" directive
: - so that stacking the rules file multiple times (
-r file etc) will get you one replacement, two replacements, etc.
But the challenge with this method is that the number of possibilities goes up quite quickly -
wl is the word length in characters, and
x is the number of changed characters. Even just replacing a single character in your example 10-character string is 940 possibilities. The first character or two aren't hard for a fast hash like SHA1, but you'll reach a feasibility limit pretty quickly:
940^1 = 940
940^2 = 883600
940^3 = 883600830584000
In practice, only a few million rules will fit within most GPUs' memory. So really, only the first two levels are likely feasible for most software and platforms.
Second, you can do this with masks. Since you have high probability, another approach would be hold most of the string constant while varying the rest. You could do this with a file containing multiple masks, of the following form for a single character:
... and this approach for two characters:
... etc., rotating through all two-character replacements, then all three-character replacements, etc.
If the second (mask) approach is feasible for your use case, it is definitely more efficient - each mask is attacked separately, and has low memory requirements.