Closed bojtalepenye closed 1 month ago
Hello, thanks for opening an issue. Hopefully, I can offer some assistance.
For a demonstration:
$ cat pass.lst
love@123
@123love
$ cat retain.txt
love
Create retain masks:
$ ptt -f pass.lst -tf retain.txt -t mask-retain | tee retained.mask
?s?d?d?dlove
love?s?d?d?d
Then swap on them with matching values:
$ cat swap.lst
$333
#888
#123
$ ptt -f retained.mask -tf swap.lst -t mask-swap
#123love
$333love
love$333
love#888
love#123
#888love
In the example with BlackCar?s?l?l?l
and $123
these do not swap because the converted mask for $123
is ?s?d?d?d
. If you had a wordlist like...
$ cat swap.lst
!lol
@heh
*luv
$ echo 'BlackCar?s?l?l?l' | ptt -t mask-swap -tf swap.lst
BlackCar@heh
BlackCar*luv
BlackCar!lol
The swaps would be performed.
Please let me know if this helps and I can go ahead and add these examples to the official documentation for all users.
Yes, thank you very muh. :D Okay, so basically, you first need to specify the retained mask, and THEN comes the swap list. I was able to replicate similiar small swaps now, but sometimes, it works in unusual ways. Like here:
ubuntu@DESKTOP-HGOIUS1:~/go/bin$ cat custom_mask
BlackCar?s?l?l?l
Hello?l?l?l?l?l?l?l
ubuntu@DESKTOP-HGOIUS1:~/go/bin$
And if I try to do this with a wordlist called kippo.txt (https://weakpass.com/wordlist/1185), then I get these wierd masks back. This (mask-swap) shouldn't even output masks right?
ubuntu@DESKTOP-HGOIUS1:~/go/bin$ ./ptt -f custom_mask -tf kippo.txt -t mask-retain
?u?l?l?l?l?u?l?l?ss?s?l?s?l?s?l
?u?l?l?lo?s?l?s?l?s?l?s?l?s?l?s?l?s?l
?u?ll?l?l?s?l?s?l?s?l?s?l?s?l?s?l?s?l
?u?la?l?l?u?l?l?s?l?s?l?s?l?s?l
?u?l?l?l?l?u?lr?s?l?s?l?s?l?s?l
?u?l?lck?u?l?l?s?l?s?l?s?l?s?l
?u?l?l?lk?u?l?l?s?l?s?l?s?l?s?l
?u?l?l?l?l?uar?s?l?s?l?s?l?s?l
?u?l?lc?l?u?l?l?s?l?s?l?s?l?s?l
?u?lac?l?u?l?l?s?l?s?l?s?l?s?l
?u?l?l?l?l?u?l?l??l?s?l?s?l?s?l
?u?l?l?l?l??l?s?l?s?l?s?l?s?l?s?l?s?l
?ul?l?l?l?u?l?l?s?l?s?l?s?l?s?l
?ue?l?l?l?s?l?s?l?s?l?s?l?s?l?s?l?s?l
?u?lll?l?s?l?s?l?s?l?s?l?s?l?s?l?s?l
ubuntu@DESKTOP-HGOIUS1:~/go/bin$
Or maybe I totally misunderstood this attack, and this is what hashcat attacks directly, but shouldn't the swap list (kippo.txt) fill the masks when it finds approritate candidates for it that match? Feel free to correct me (I am here to learn).
I'd like to perform this technique with larger data on larger wordlists. Could you recommend me a how big of a wordlist should I use?
And by the way, I wanted to ask a question regarding why token swapping doesn't work inside a sinlge wordlist. From my understanding. This is the general process: (1) wordlist -> create retain mask file (2) swap list -> mask-swap
If I interpret this picture correctly, why doesn't it just do this instead: (1) wordlist -> tokenize passwords/find password patterns (2) swap password patterns inside the wordlist.
Why not just skip the "creating a retain mask file and then using that file with another wordlist to swap tokens" step, and instead just perform all of this inside a single wordlist?
Thanks,
Glad that was helpful, and I am thrilled you mentioned this, actually.
Starting from the first questions:
In this example, ptt -f custom_mask -tf kippo.txt -t mask-retain
the mode is using the custom_mask
file as input for the mask-retain
so the output will be partial masks. To fix this, change the mode to mask-swap
to perform swaps with the partial masks in custom_mask
already.
$ cat custom_mask | ptt -tf kippo.txt -t mask-swap | head
[*] Creating file buffer...
[*] All content done loading.
[*] This transformation mode requires a retain mask file to use for swapping.
[*] Task complete with 7266 unique results.
Hellowjdwogh
Hellogetpaid
Hellopekurar
Hellodirnrhd
Helloaksksla
Hellomahakal
Hellotbcmcom
Hellosundeep
Helloesedong
Hellostarwei
I'd like to perform this technique with larger data on larger wordlists. Could you recommend me a how big of a wordlist should I use?
It very much depends on several factors. The target speed, hardware available, and the patterns being targeted. I would generally suggest making smaller samples and seeing how they perform, and continuously refining the input to the mask-swap
mode until a balance is struck. The -r
, -k
, and mask-match
options may help here as you can keep filtering until the feedback loop is just right.
I wanted to ask a question regarding why token swapping doesn't work inside a sinlge wordlist.
So there is/was two ways to implement this technique. Mostly due to my own inconsistencies and refining over time.
Back in maskcat
there were two options for swapping.
mask-swap
and rely on partial masks from mask-retain
Method 1 was the first method created/used/implemented, but had a unique issue. If the masks were too complex, swaps would end up "drifiting" away from the source material and create a lot of noise or high entropy candidates that did not really look like the source material anymore.
Because the attack is designed to create a large amount of material that replicates the source, this was vital to its core function. If the user failed to supply quality input, the output would be suboptimal. This is why mask-match
was generally recommended to isolate patterns before swapping, so a user could know how the swaps would likely take place.
Then in maskcat
a user (Shooter3k
) suggested the concept of the retain
mode which would create partial masks. This was done completely independently of the swapping concept, but I realized it solved one of its key issues, the ability to target how metadata was moved around and preserving key structure before the swaps.
This ended up being implemented into the logic of the second method, which is the current implementation. In this method, a user could control exactly where the swap would occur and what components should not be swapped under any conditions. This was a small change that added the additional pre-processing step of making partial masks with mask-retain
before mask-swap
.
One key concept of token swapping is to simulate the target for key spaces that are very difficult to target with other methods. A simple example is gigantic repetitive keyspaces like digits. A keyspace of ?l?l?l?l?l?d?d?d?d?d?d?d?d?d?d?d?d
is challenging to enumerate unless the target material is likely to share metadata from each other. In this manner, we go from a large keyspace to staying within the "cluster" and making the processing much more efficient.
In the case of simulating non-repetitive material, by using partial masks, you can identify common metadata then use retain
to make sure it is always present and end up with higher quality results that still simulate the target more so than if it may have gotten swapped out at random.
There's a bit of history to it, which is why I am glad you gave me a chance to discuss it. As far as the future goes, because the first method used to exist in maskcat
it would be straightforward to port over to ptt
if the users would like it. My goal was to increase the likelihood of a user reaching the intended outcome at the risk of additional complexity to the path to get there. A simpler option maybe to just update the reference material that you shared an image of ๐.
Please let me know if this cleared things up a bit or if there is anything else I can explain. Please don't hesitate to ask any additional questions as well. I do not mind reopening the issue and adding to the documentation.
I am sorry, I miswrote it. I was actually going to submit not the retain-mask command but the mask-swap command. Sorry, that is why I was asking why were masks in my output. ๐
On that note though, the right command (./ptt -f masks -tf kippo.txt -t mask-swap
) gets the job done, and does the swapping correctly. Keep in mind, I am just showing a few of the generated candidates here, but I with that mask swap, I noticed some still had masks.
bnnbnns
humbugr
bsmooth
cemans
dgi?l?lr?l
gwames
malisar
rukzwf
?lrguy?l?l
sswallow
brosso
nakais
lab?l?lr?l
bjurist
bgalaxy
bmilica
Again, these are just a few candidates of the numerous many more mask-swap generated. Should the masks be there? Does mask-swap performs the swap if for example I have a retained mask like this, and mask-swap only finds a suitable token for ?d?d?d
and not for ?s
:
partial?d?d?dmask?s
Would it fill the ?d?d?d
mask and just leave ?s
on its own?
That might explain why there were masks in the output, but I may be wrong here.
PS: I am actually writing a book about Hash Cracking and have been deepdiving hash cracking for over 2 years now. In the password analysis section, I wrote about PACK (Password Analysis and Cracking Kit), but a few months ago, I came across your website and your GitHub profile. I read many of your posts about password security and hash cracking. But let me tell you, when I downloaded PTT first, and started playing around with it, I was left shocked. Heck, PACK was written 11 years ago, and here is PTT doing much more than what PACK could have ever imagined doing. Amazing job!
One more thing. I created many diagrams (in the book), but specifically I am now talking about this diagram:
I did not put this in directly (still, you have been given full credit), but I may have upgraded it a little bit๐ , plus created another entierly new diagram explaining mask-retain.
Anyway, my question is: Since technically thats not how mask-swap works anymore, should the diagram be changed? I am not asking you to create a new and update it on your website, and I completely understand why the change has been made (giving users more control is always appreciated), but I need to know if I need to change it. I mean, it does explain very well what mask-swap is about, but if I leave it be, mask-swap can be seen as an attack on it's own (which it is not, becuase it stems from mask-retain; it is a 2 step process).
And thanks again. This technique is so unique; I absolutely love it! I have done keyboard walk attacks, Purple Rain attacks, and other wild ones, but this is new.
Thank you for the kind words, and I'm thrilled that PTT has been a great tool for you. I hope the tool can continue to grow and eventually reach a stable version for everyone to enjoy.
As far as the mask-swap
that still has masks, no, this is not intentional and is something I can look into for v0.3.5
. In the past, I had an additional filter to ensure the output was not a mask, and it seems it may be needed again.
The code for mask-swap
lives in /pkg/mask/mask.go:445
and it only attempts one swap per partial mask, I believe I played with a recursive version in the past, but the time per candidate was not optimal for the use case and could still leave partial masks. Will investigate and tidy it up a bit.
EDIT: Issuing fix.
Additionally, about the diagrams, I appreciate the mention and happy to hear you found it valuable. In my opinion, I think it is better to replicate the attack narrative rather than the tool-specific implementation. I believe the core concept extends beyond the tool and if the original diagram is someone's "aha moment" then that would be worth it. The conversation has inspired me to go back and update the blog post a bit when I have time. I probably intend to keep the original and then make another for the second version to help reiterate the key points of what is attempting to be accomplished.
Reopening the issue to take a look at some changes for the mask-swap
mode and stay tuned.
I believe all outstanding mask-swap
issues should be resolved with 0c943089d6b2b5c96e97e967fc0f275a94004889.
Please let me know if you encounter any other issues!
Sure; will do ๐
Maybe I am missing something, but I think I know how this works, despite that, I just CANNOT get this tool to function for me properly. Here is what I want to do. I want to do the mask swapping (toke swapping attack). The first step is to creat partial mask files with mask-retain.
Step 1:
This outputs the following:
Now. Onto step 2.
Step 2: Mask swapping:
And... Nothing. Absolutely nothing. If you look at the very first mask, which would require a 5 character long, lowercase password to be swapped, nothing happens. 1000.txt has at least one password like that. For example: "crazy"
Now, here is where it gets interesting: I have mask file with one line: BlackCar?s?l?l?l I'd need to have a special character and three lowecase characters, right? Wrong:
This is what is in the "custom_wordlist" file:
It would really be amazing if somebody could clear this for me and tell me how token-swapping works. I'd like to generate a lot of password candidates with it. Thanks,