{"id":436,"date":"2024-06-24T19:01:09","date_gmt":"2024-06-24T18:01:09","guid":{"rendered":"https:\/\/fin3ss3g0d.net\/?p=436"},"modified":"2024-06-24T19:01:11","modified_gmt":"2024-06-24T18:01:11","slug":"crack-faster-hack-smarter-custom-hashcat-module-for-apache-shiro-1-sha-512","status":"publish","type":"post","link":"https:\/\/fin3ss3g0d.net\/index.php\/2024\/06\/24\/crack-faster-hack-smarter-custom-hashcat-module-for-apache-shiro-1-sha-512\/","title":{"rendered":"Crack Faster, Hack Smarter: Custom Hashcat Module for Apache Shiro 1\u00a0SHA-512"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"436\" class=\"elementor elementor-436\">\n\t\t\t\t<div class=\"elementor-element elementor-element-0480228 e-flex e-con-boxed e-con e-parent\" data-id=\"0480228\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-dd10936 elementor-widget elementor-widget-text-editor\" data-id=\"dd10936\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<section class=\"section section--body\">\n<div class=\"section-divider\">&nbsp;<img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*Dn1yk9bSTbZclOIbFImXGw.png\" data-image-id=\"1*Dn1yk9bSTbZclOIbFImXGw.png\" data-width=\"975\" data-height=\"556\" data-is-featured=\"true\" style=\"font-style: inherit; font-weight: inherit; text-align: var(--text-align); font-size: 16px; color: var( --e-global-color-text ); font-family: var( --e-global-typography-text-font-family ), Sans-serif; background-color: var(--ast-global-color-5);\"><\/div>\n<div class=\"section-content\">\n<div class=\"section-inner sectionLayout--insetColumn\">\n<h3 class=\"graf graf--h3\">Introduction<\/h3>\n<p class=\"graf graf--p\">During a recent assessment, we identified a server running Nexus Repository 3 that was vulnerable to CVE-2024\u20134956. This led to us pillaging data from the system and ultimately extracting Apache Shiro 1 SHA-512 password hashes to the web application from this data. Apache Shiro\u2019s version 1 SHA-512 hashing implementation involves salting the input data with a secure, randomly generated value and performing the hash operation iteratively (typically thousands of times) to enhance security against brute-force attacks. In simpler terms, it is a salted, iterated SHA-512 hashing mechanism. In this post, I\u2019ll describe the steps taken to identify the hashing algorithm and how I created a Hashcat module capable of cracking it. This will guide you through the process of creating a custom module to effectively crack these hashes.<\/p>\n<h3 class=\"graf graf--h3\">Sonatype Repository 3<\/h3>\n<p class=\"graf graf--p\">Before we continue, it\u2019s important to note that the Apache Shiro 1 SHA-512 algorithm is used by Sonatype Repository 3 to hash user credentials for the web application database, as of the time of writing. Since there is a public mirror of the code base available on GitHub, it is possible to view exactly how the application hashes credentials. You can clone the repository from the following <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/sonatype\/nexus-public\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/sonatype\/nexus-public\">URL<\/a>. If we clone that repository and do a recursive <strong class=\"markup--strong markup--p-strong\">grep <\/strong>command for the text \u201c<strong class=\"markup--strong markup--p-strong\">shiro.crypto<\/strong>\u201d, we will get the following results shown below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*5kwiQFGb340xGinKCfLG4A.png\" data-image-id=\"1*5kwiQFGb340xGinKCfLG4A.png\" data-width=\"975\" data-height=\"194\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">Out of these results, the file responsible for performing password hashing is <strong class=\"markup--strong markup--p-strong\">DefaultSecurityPasswordService.java<\/strong>, which can be accessed <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/sonatype\/nexus-public\/blob\/main\/components\/nexus-security\/src\/main\/java\/org\/sonatype\/nexus\/security\/internal\/DefaultSecurityPasswordService.java\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/sonatype\/nexus-public\/blob\/main\/components\/nexus-security\/src\/main\/java\/org\/sonatype\/nexus\/security\/internal\/DefaultSecurityPasswordService.java\">here<\/a>. We can look at the relevant parts of the file below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*lChPOk-spiPCfBy7kLYhxA.png\" data-image-id=\"1*lChPOk-spiPCfBy7kLYhxA.png\" data-width=\"1266\" data-height=\"1609\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">The key pieces of information to take away here are the hash algorithm (SHA-512), iterations (1024), the constructor for the class, and the <strong class=\"markup--strong markup--p-strong\">hashPassword<\/strong> method. We can see in the constructor that the <strong class=\"markup--strong markup--p-strong\">passwordService<\/strong> member (of type <strong class=\"markup--strong markup--p-strong\">PasswordService<\/strong>) is set to a new instance of the <strong class=\"markup--strong markup--p-strong\">DefaultPasswordService<\/strong> class. A new <strong class=\"markup--strong markup--p-strong\">DefaultHashService<\/strong> object is created, then configured with the hash algorithm and iterations. The <strong class=\"markup--strong markup--p-strong\">passwordService<\/strong> member then calls the <strong class=\"markup--strong markup--p-strong\">setHashService<\/strong> method using the <strong class=\"markup--strong markup--p-strong\">hashService<\/strong> object. The <strong class=\"markup--strong markup--p-strong\">hashPassword<\/strong> method simply calls the <strong class=\"markup--strong markup--p-strong\">hashPassword<\/strong> method of the <strong class=\"markup--strong markup--p-strong\">passwordService<\/strong> member. The relevant code for the <strong class=\"markup--strong markup--p-strong\">DefaultPasswordService<\/strong> class is shown below and can be accessed via the following <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/apache\/shiro\/blob\/main\/core\/src\/main\/java\/org\/apache\/shiro\/authc\/credential\/DefaultPasswordService.java\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/apache\/shiro\/blob\/main\/core\/src\/main\/java\/org\/apache\/shiro\/authc\/credential\/DefaultPasswordService.java\">URL<\/a>.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*7sD6ZjCfuSAOdz3aJmmvQA.png\" data-image-id=\"1*7sD6ZjCfuSAOdz3aJmmvQA.png\" data-width=\"975\" data-height=\"1213\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">Here we can see the default constructor sets up the class using some defaults, which have been overridden with a custom <strong class=\"markup--strong markup--p-strong\">HashService<\/strong> class object previously shown. We can also see the implementation of <strong class=\"markup--strong markup--p-strong\">hashPassword<\/strong>, which ultimately ends up calling <strong class=\"markup--strong markup--p-strong\">computeHash<\/strong> of the <strong class=\"markup--strong markup--p-strong\">hashService<\/strong> member (of type <strong class=\"markup--strong markup--p-strong\">DefaultHashService<\/strong>). The implementation for <strong class=\"markup--strong markup--p-strong\">computeHash<\/strong> in the <strong class=\"markup--strong markup--p-strong\">DefaultHashService<\/strong> class can be seen below and accessed at the following <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/apache\/shiro\/blob\/main\/crypto\/hash\/src\/main\/java\/org\/apache\/shiro\/crypto\/hash\/DefaultHashService.java\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/apache\/shiro\/blob\/main\/crypto\/hash\/src\/main\/java\/org\/apache\/shiro\/crypto\/hash\/DefaultHashService.java\">URL<\/a>.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*HIJID9ShrsGLBO6jeLB5ZA.png\" data-image-id=\"1*HIJID9ShrsGLBO6jeLB5ZA.png\" data-width=\"975\" data-height=\"892\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">We can see there is an attempt to obtain a <strong class=\"markup--strong markup--p-strong\">HashSpi<\/strong> object using the algorithm name, which if successful will call the <strong class=\"markup--strong markup--p-strong\">newHashFactory<\/strong> method on the object, followed by the <strong class=\"markup--strong markup--p-strong\">generate<\/strong> method and return the result. The SHA-512 algorithm will end up creating a new <strong class=\"markup--strong markup--p-strong\">SimpleHashFactory<\/strong> and using its <strong class=\"markup--strong markup--p-strong\">generate<\/strong> method. The <strong class=\"markup--strong markup--p-strong\">generate<\/strong> implementation is shown below and can be accessed at the following <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/apache\/shiro\/blob\/main\/crypto\/hash\/src\/main\/java\/org\/apache\/shiro\/crypto\/hash\/SimpleHashProvider.java\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/apache\/shiro\/blob\/main\/crypto\/hash\/src\/main\/java\/org\/apache\/shiro\/crypto\/hash\/SimpleHashProvider.java\">URL<\/a>.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*d9bhJsRytR5dgMRNQujOyQ.png\" data-image-id=\"1*d9bhJsRytR5dgMRNQujOyQ.png\" data-width=\"1013\" data-height=\"1145\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">The generate method will ultimately end up calling <strong class=\"markup--strong markup--p-strong\">createSimpleHash<\/strong>, which creates a new <strong class=\"markup--strong markup--p-strong\">SimpleHash<\/strong> class object using the algorithm name, sets the iterations, salt and returns it. The relevant parts of the <strong class=\"markup--strong markup--p-strong\">SimpleHash<\/strong> class are shown below and can be accessed here at the following <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/apache\/shiro\/blob\/main\/crypto\/hash\/src\/main\/java\/org\/apache\/shiro\/crypto\/hash\/SimpleHash.java\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/apache\/shiro\/blob\/main\/crypto\/hash\/src\/main\/java\/org\/apache\/shiro\/crypto\/hash\/SimpleHash.java\">URL<\/a>.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*_QOWfbU7rZ-zqkjxKMzeRQ.png\" data-image-id=\"1*_QOWfbU7rZ-zqkjxKMzeRQ.png\" data-width=\"1262\" data-height=\"1215\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">We can see the constructor sets the algorithm to be used for future hashing, with the core hashing methods being <strong class=\"markup--strong markup--p-strong\">setBytes<\/strong> and <strong class=\"markup--strong markup--p-strong\">hash<\/strong>, and <strong class=\"markup--strong markup--p-strong\">hash<\/strong> having multiple overloads. The main cryptographic operations involve creating an initial hash using the salt and password bytes, then repeating the hashing process using the previous digest until the iteration count has been reached. Another example of creating an Apache Shiro 1 SHA-512 hash using Java is available in this <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/fin3ss3g0d\/Shiro1Tools\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/fin3ss3g0d\/Shiro1Tools\">repository<\/a> and can be seen below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*Bx-BDnroyCRMyBBXM0t3yQ.png\" data-image-id=\"1*Bx-BDnroyCRMyBBXM0t3yQ.png\" data-width=\"975\" data-height=\"1171\"><\/figure>\n<h3 class=\"graf graf--h3\">Previous Research<\/h3>\n<p class=\"graf graf--p\">At the time of our assessment, cracking support was very limited with not much information about cracking the algorithm available on the Internet. Searching the title, body, and comments of all Hashcat issues had no mention of the hashing implementation, almost as if it didn\u2019t exist. We were able to come across one post on the Hashcat forum <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/hashcat.net\/forum\/thread-5976.html\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/hashcat.net\/forum\/thread-5976.html\">here<\/a> from 2016, which seemed to be the only mention of it by anyone associated with Hashcat. It is also discussing a SHA-256 version of Apache Shiro 1, not to be confused with what our research is focused on, which is a SHA-512 implementation.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*SpHKImBfoc82dPTqm9nx5g.png\" data-image-id=\"1*SpHKImBfoc82dPTqm9nx5g.png\" data-width=\"975\" data-height=\"635\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">At first, I found this to be confusing because there are plenty of salted and iterated hashes supported by Hashcat in 2024. Thinking about it further, the only explanation I can think of is that in 2016 at the time of the post, Hashcat did not have the capabilities to crack a salted and iterated hash of this nature. The Hashcat kernel structure in 2024 is actually designed around iterated hashes, forcing an author of a kernel to implement a method in the kernel called <em class=\"markup--em markup--p-em\">loop<\/em> where the iterated cryptographic work is done.<\/p>\n<p class=\"graf graf--p\">Additionally, although there were a couple gists written in <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/gist.github.com\/gquere\/365cfcceef9ac8d145cc59bbf2c27648\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/gist.github.com\/gquere\/365cfcceef9ac8d145cc59bbf2c27648\">Java<\/a> and <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/gist.github.com\/gquere\/8dc40c5a6a900215102e6ac94716b33d\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/gist.github.com\/gquere\/8dc40c5a6a900215102e6ac94716b33d\">C<\/a> floating around, the cracking performance left more to be desired as both of these examples run on the CPU.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*I2ReXWF38wX443tWUAZAqQ.png\" data-image-id=\"1*I2ReXWF38wX443tWUAZAqQ.png\" data-width=\"975\" data-height=\"556\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">Wanting to increase cracking performance by taking advantage of a multiple GPU hash cracking rig as well as Hashcat features such as advanced rule support, this led to the journey of creating a custom Hashcat module for the Apache Shiro 1 hashing implementation.<\/p>\n<h3 class=\"graf graf--h3\">Creating the Hashcat&nbsp;Module<\/h3>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*LefpJVv02zwI-CfxjWwY8w.png\" data-image-id=\"1*LefpJVv02zwI-CfxjWwY8w.png\" data-width=\"975\" data-height=\"556\"><\/figure>\n<h3 class=\"graf graf--h3\">Initial Thoughts<\/h3>\n<p class=\"graf graf--p\">Looking at the standalone C cracking implementation, it\u2019s apparent that creating a Hashcat module for this hashing implementation should be straightforward, or at least the core cracking logic was already laid out for me. It is an iterated SHA-512 hash with a salt. Could this be that difficult to crack to the point where Hashcat maintainers decided they wouldn\u2019t create a module altogether? Surely, it couldn\u2019t be, could it? I can think of more computationally demanding algorithms for certain. So, why hadn\u2019t it been done before? Has there never been enough of a need\/demand? I never got an answer to these questions throughout this research, but we got the module we wanted so I guess it doesn\u2019t really matter anyways. Looking at some of the Hashcat OpenCL code, there were even libraries for the SHA-512 algorithm. Everything that was needed to create the module was already contained within the repository. My confidence level began to rise for being able to create a working module.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*0uMUqhJd9x6DDwIG\" data-image-id=\"0*0uMUqhJd9x6DDwIG\" data-width=\"1024\" data-height=\"1024\"><\/figure>\n<h3 class=\"graf graf--h3\">First Steps<\/h3>\n<p class=\"graf graf--p\">Before we get started, you can access the module in my Hashcat fork <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/fin3ss3g0d\/hashcat\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/fin3ss3g0d\/hashcat\">here<\/a> with module 12150 (will require building from source) and follow along with code discussion.<\/p>\n<p class=\"graf graf--p\">You will notice if you try to research the topic of creating a Hashcat module, not much exists outside of the Hashcat repository itself. I was able to find <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/www.thesubtlety.com\/post\/how-to-write-a-hashcat-module\/\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/www.thesubtlety.com\/post\/how-to-write-a-hashcat-module\/\">this<\/a> blog from 2020 which was helpful but did not cover creating an OpenCL kernel from scratch, which was necessary in our case. The Hashcat repository has extremely thorough documentation for creating your own module (also called a plugin by Hashcat developers) available <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md\">here<\/a>, and it is official documentation\/advice from the developers themselves. It is a full-blown guide walking you through the entire process of creating your own module and gives you some necessary prerequisite knowledge. Using this guide, if you have the necessary C programming knowledge to implement the algorithm you will be able to create your own module fairly easily. More advice would be to remain patient when you are going on this journey, do not expect instant results on the first day. There is a learning curve associated with this task and you have to learn the lay of the land first before you can have success creating a module. If you study the plugin development guide, it will give you all of the necessary information you need to create your own module.<\/p>\n<p class=\"graf graf--p\">Ultimately, we will be creating two files which will be the module C code file and the OpenCL kernel code file. The module C code registers the module with Hashcat itself and handles everything except for the raw cryptographic operations of the algorithm you are trying to implement. The raw cryptographic operations are implemented in the OpenCL kernel file. This is a brief explanation while the plugin development guide goes into much further detail. We will start by covering the module C code.<\/p>\n<h3 class=\"graf graf--h3\">Creating the Module C&nbsp;Code<\/h3>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*0VYyMwOCKiImYeRRGxqohQ.png\" data-image-id=\"1*0VYyMwOCKiImYeRRGxqohQ.png\" data-width=\"975\" data-height=\"556\"><\/figure>\n<h4 class=\"graf graf--h4\">Background and Beginning of&nbsp;Module<\/h4>\n<p class=\"graf graf--p\">The beginning of the module is setting up some necessary configurations that will modify the behavior of the module and will instruct Hashcat how to operate. The beginning of the Apache Shiro 1 module is shown below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*BvRQT7wKz7WobaaQWEmwuQ.png\" data-image-id=\"1*BvRQT7wKz7WobaaQWEmwuQ.png\" data-width=\"975\" data-height=\"477\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">Every Hashcat module will follow the same structure in the beginning of its code, and each of the methods shown above are mandatory for every module to implement as they provide Hashcat the necessary information it needs to run the module. A module can also implement other methods that aren\u2019t required or shown above. You can find the documentation for each of these methods below:<\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_attack_exec\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_attack_exec\">module_attack_exec<\/a><\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_dgst_pos0---module_dgst_pos3\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_dgst_pos0---module_dgst_pos3\">module_dgst_pos0\u200a\u2014\u200amodule_dgst_pos3<\/a><\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_dgst_size\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_dgst_size\">module_dgst_size<\/a><\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_hash_category\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_hash_category\">module_hash_category<\/a><\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_hash_name\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_hash_name\">module_hash_name<\/a><\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_kern_type\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_kern_type\">module_kern_type<\/a><\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_opti_type\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_opti_type\">module_opti_type<\/a><\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_opts_type\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_opts_type\">module_opts_type<\/a><\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_salt_type\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_salt_type\">module_salt_type<\/a><\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_st_hash\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_st_hash\">module_st_hash<\/a><\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_st_pass\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_st_pass\">module_st_pass<\/a><\/p>\n<p class=\"graf graf--p\"><br><\/p><p class=\"graf graf--p\">Below are some snippets of the documentation for <strong class=\"markup--strong markup--p-strong\">module_opti_type<\/strong> and <strong class=\"markup--strong markup--p-strong\">module_opts_type<\/strong>.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*KRHSwtBpLsa24ElcEmjYIg.png\" data-image-id=\"1*KRHSwtBpLsa24ElcEmjYIg.png\" data-width=\"975\" data-height=\"898\"><\/figure>\n<figure class=\"graf graf--figure\"><br><\/figure>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*-cAedNJNuO5YDXdDS9Fs7g.png\" data-image-id=\"1*-cAedNJNuO5YDXdDS9Fs7g.png\" data-width=\"975\" data-height=\"877\"><\/figure>\n<h4 class=\"graf graf--h4\">Remaining Methods<\/h4>\n<p class=\"graf graf--p\">In order to complete this module, there were only five more methods to implement:<\/p>\n<p class=\"graf graf--p\">\u00b7 <strong class=\"markup--strong markup--p-strong\">module_tmp_size<\/strong>: Returns the size of the <strong class=\"markup--strong markup--p-strong\">tmps<\/strong> structure<\/p>\n<p class=\"graf graf--p\">\u00b7 <strong class=\"markup--strong markup--p-strong\">module_pw_max<\/strong>: Returns a size that is the maximum length for any given password this algorithm produces<\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_hash_decode\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_hash_decode\"><strong class=\"markup--strong markup--p-strong\">module_hash_decode<\/strong><\/a><\/p>\n<p class=\"graf graf--p\">\u00b7 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_hash_encode\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#module_hash_encode\"><strong class=\"markup--strong markup--p-strong\">module_hash_encode<\/strong><\/a><\/p>\n<p class=\"graf graf--p\">\u00b7 <strong class=\"markup--strong markup--p-strong\">module_init<\/strong>: Register all the functions that you have programmed by assigning it to module_ctx, initializing the module<\/p>\n<h4 class=\"graf graf--h4\">The tmps Structure<\/h4>\n<p class=\"graf graf--p\">An important structure to explain at this point would be the <strong class=\"markup--strong markup--p-strong\">tmps<\/strong> structure, which has a definition of: \u201c<em class=\"markup--em markup--p-em\">void *<\/em><strong class=\"markup--strong markup--p-strong\"><em class=\"markup--em markup--p-em\">tmps<\/em><\/strong><em class=\"markup--em markup--p-em\">: This is the generic context buffer. It is available only in slow hash kernel mode. In slow hash mode you want to read and write this buffer. There is one entry for each work item.\u201c<\/em> Not to get ahead of ourselves before we talk about the kernel in more depth, but below is more context on the <strong class=\"markup--strong markup--p-strong\">tmps<\/strong> structure on the kernel side of things.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*xklCniy5l7OTpfduOWXJyQ.png\" data-image-id=\"1*xklCniy5l7OTpfduOWXJyQ.png\" data-width=\"975\" data-height=\"150\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">We\u2019ll talk more about this structure later as it is a significant part of the module. At this point, we would then begin developing the five methods listed above assuming our mandatory methods are in place. Below is an example of our <strong class=\"markup--strong markup--p-strong\">tmps<\/strong> structure along with the implementation for <strong class=\"markup--strong markup--p-strong\">module_tmp_size <\/strong>and <strong class=\"markup--strong markup--p-strong\">module_pw_max<\/strong>.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*uu6DnQp7QZbD3Xw1jvXwTg.png\" data-image-id=\"1*uu6DnQp7QZbD3Xw1jvXwTg.png\" data-width=\"975\" data-height=\"302\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">We define our <strong class=\"markup--strong markup--p-strong\">tmps<\/strong> structure in the module C code and return its size in the <strong class=\"markup--strong markup--p-strong\">module_tmp_size <\/strong>method so the kernel knows its size and how large of a buffer to allocate for the structure. The structure can be broken down as follows:<\/p>\n<p class=\"graf graf--p\">\u00b7 <strong class=\"markup--strong markup--p-strong\">dgst<\/strong>: Temporary hash digest buffer<\/p>\n<p class=\"graf graf--p\">\u00b7 <strong class=\"markup--strong markup--p-strong\">out<\/strong>: Final output hash to use during comparisons<\/p>\n<h4 class=\"graf graf--h4\">The module_hash_decode Method<\/h4>\n<p class=\"graf graf--p\">This brings us to the <strong class=\"markup--strong markup--p-strong\">module_hash_decode <\/strong>method which can be described as: <em class=\"markup--em markup--p-em\">\u201cThe decoder function is the function that is called again and again for every line in your hashfile. We also call this sometimes the hash parser. Here you have to program the logic which decodes the line into its components and then stores them in the standardized data structure which hashcat understands.\u201c<\/em> The method can be described as accomplishing the following goals shown below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*yUmtCWrTOMXcdpT0dm82nA.png\" data-image-id=\"1*yUmtCWrTOMXcdpT0dm82nA.png\" data-width=\"975\" data-height=\"419\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">The above might sound like a lot, but in our case it\u2019s really not. The <strong class=\"markup--strong markup--p-strong\">tokenizer<\/strong> is a means of extracting the necessary data from each hash string we decode during this method such as the salt and hash bytes. Here\u2019s an example of our <strong class=\"markup--strong markup--p-strong\">module_hash_decode <\/strong>method below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*UqRMzMlbsN93JP-5JacZsQ.png\" data-image-id=\"1*UqRMzMlbsN93JP-5JacZsQ.png\" data-width=\"975\" data-height=\"710\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">With the salt, hash, and iteration data extracted during the <strong class=\"markup--strong markup--p-strong\">tokenizer<\/strong> phase, we can then prepare the salt and digest buffers as shown below which finishes the method.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*IrX-ZG8su3A9vz4lDxOPJQ.png\" data-image-id=\"1*IrX-ZG8su3A9vz4lDxOPJQ.png\" data-width=\"975\" data-height=\"1110\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">At this point, the salt buffer is prepared with the salt bytes and iterations. The digest buffer containing the hash bytes is also prepared which is used in hash comparisons. For example, the kernel will generate a hash based on an entry in a wordlist and compare that hash to this one. If they match, you know you cracked the hash. Be aware that you will need to manually manage endianness throughout this process, hence the byte swap shown above. In this case, we needed to convert the raw buffer bytes to 64-bit integer format for storing the digest. This is how the final digest is stored by the Hashcat crypto library in our case for SHA-512.<\/p>\n<h4 class=\"graf graf--h4\">The module_hash_encode Method<\/h4>\n<p class=\"graf graf--p\">The next method implemented in the module is <strong class=\"markup--strong markup--p-strong\">module_hash_encode <\/strong>which can be explained as seen below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*A-MkUCzvFZN96lTSb5PSzw.png\" data-image-id=\"1*A-MkUCzvFZN96lTSb5PSzw.png\" data-width=\"975\" data-height=\"323\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">The implementation is shown below, in this case we could simply use the original hash buffer that was read from the input hash file.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*eWuKEhdseDa319thWzsLLg.png\" data-image-id=\"1*eWuKEhdseDa319thWzsLLg.png\" data-width=\"975\" data-height=\"402\"><\/figure>\n<h4 class=\"graf graf--h4\">Wrapping Things&nbsp;Up<\/h4>\n<p class=\"graf graf--p\">The last method to implement was <strong class=\"markup--strong markup--p-strong\">module_init <\/strong>which can be explained as shown below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*sr_u5AXhuvuXJw_FxyjDCQ.png\" data-image-id=\"1*sr_u5AXhuvuXJw_FxyjDCQ.png\" data-width=\"975\" data-height=\"271\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">I won\u2019t show the implementation for our module, but it is straightforward, and you can find plenty of examples throughout the Hashcat source code as every module has it implemented. At this point, we are ready to jump into the kernel code!<\/p>\n<h3 class=\"graf graf--h3\">Creating the&nbsp;Kernel<\/h3>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*LaeYonFRQVsViVhLzBP-QQ.png\" data-image-id=\"1*LaeYonFRQVsViVhLzBP-QQ.png\" data-width=\"975\" data-height=\"556\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">As previously mentioned, the second file we are required to create is the OpenCL file which is our kernel. Shown below is some introductory information about the kernel from the Hashcat documentation.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*CqnyqSkUfCiXTkRpP7V2Kg.png\" data-image-id=\"1*CqnyqSkUfCiXTkRpP7V2Kg.png\" data-width=\"975\" data-height=\"671\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">Before we continue any further, let\u2019s take a step back for a second and talk about what OpenCL is and what an OpenCL kernel is. We will refer to the overall OpenCL file as a kernel as well as individual methods inside of the file. Hashcat uses OpenCL (Open Computing Language) for its kernels, which are the core components responsible for performing the actual hash computations. The&nbsp;<strong class=\"markup--strong markup--p-strong\">.cl<\/strong> file extension indicates OpenCL source files.<\/p>\n<h4 class=\"graf graf--h4\">What is&nbsp;OpenCL?<\/h4>\n<p class=\"graf graf--p\">OpenCL is a framework for writing programs that execute across heterogeneous platforms, including CPUs, GPUs, and other processors. It allows developers to write code that can run on different types of hardware, making it versatile for high-performance computing tasks.<\/p>\n<h4 class=\"graf graf--h4\">Kernel Programming in&nbsp;OpenCL<\/h4>\n<p class=\"graf graf--p\"><strong class=\"markup--strong markup--p-strong\">C-like Syntax<\/strong>: The syntax of OpenCL kernels is very similar to the C programming language. This is because OpenCL is based on a subset of ISO C99, with some extensions and restrictions to accommodate the parallel nature of the hardware it targets.<\/p>\n<p class=\"graf graf--p\"><strong class=\"markup--strong markup--p-strong\">Parallel Computing<\/strong>: OpenCL is designed to exploit the parallelism of GPUs and other hardware accelerators. This makes it highly suitable for tasks like hash computation, which can benefit from being parallelized.<\/p>\n<h4 class=\"graf graf--h4\">Components of an OpenCL&nbsp;Program<\/h4>\n<p class=\"graf graf--p\"><strong class=\"markup--strong markup--p-strong\">Host Code<\/strong>: Written in a standard programming language like C or C++, the host code sets up the OpenCL environment, compiles the OpenCL kernel code, and manages data transfer between the host and the device.<\/p>\n<p class=\"graf graf--p\"><strong class=\"markup--strong markup--p-strong\">Kernel Code<\/strong>: Written in OpenCL C, this code runs on the OpenCL-compatible device (such as a GPU). The kernel code is what you see in the&nbsp;<strong class=\"markup--strong markup--p-strong\">.cl<\/strong> files.<\/p>\n<h4 class=\"graf graf--h4\">OpenCL Background Summary<\/h4>\n<p class=\"graf graf--p\">Before starting this journey, I was a complete noob to OpenCL, so I thought leaving this information here would be beneficial for anybody attempting to go down this path. Since we are trying to create a kernel for the module, it is helpful to know how it works from a technological perspective. Now that we know what we are dealing with, let\u2019s dive into the implementation.<\/p>\n<h4 class=\"graf graf--h4\">Hashcat Kernel Background<\/h4>\n<p class=\"graf graf--p\">Shown below is documentation from Hashcat explaining what a slow hash type kernel is, along with information about the three methods you need to implement inside the kernel. This documentation can be accessed <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#kernel-slow-hash-type\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#kernel-slow-hash-type\">here<\/a>. The Apache Shiro 1 kernel is a slow hash type kernel due to the algorithm being so demanding that the PCI Express Bottleneck is no longer relevant as it is with fast hash types. This is largely due to the fact the hash is iterated.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*8-pTtoeGICGlpN1B0m5Fsw.png\" data-image-id=\"1*8-pTtoeGICGlpN1B0m5Fsw.png\" data-width=\"975\" data-height=\"904\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">Below is further documentation about the three kernels and the sequence in which you will typically interact with the <strong class=\"markup--strong markup--p-strong\">tmps<\/strong> context buffer.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*KyoLQMXPuIPReW3_keu4Pg.png\" data-image-id=\"1*KyoLQMXPuIPReW3_keu4Pg.png\" data-width=\"975\" data-height=\"344\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">Another important thing to know when developing your kernel is what macro you should use for each of the methods. A list of the macros can be seen below and accessed <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#kernel-parameters\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#kernel-parameters\">here<\/a>. The Apache Shiro 1 module will use the <strong class=\"markup--strong markup--p-strong\">KERN_ATTR_TMPS(t) <\/strong>macro for all of the kernels since they only use a <strong class=\"markup--strong markup--p-strong\">tmps<\/strong> structure.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*q16Z3WV-ly9foLmyThjSvA.png\" data-image-id=\"1*q16Z3WV-ly9foLmyThjSvA.png\" data-width=\"975\" data-height=\"419\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">The last important thing you will need to know when developing a kernel are the kernel parameters (documentation link shared above). As discussed previously, OpenCL programs allow data transfer between a host and a device. All of the parameters you see below are accessible to every kernel. A good example of this is how we extracted the salt in the module C code during the <strong class=\"markup--strong markup--p-strong\">module_hash_decode <\/strong>method. This ends up going in a buffer called <strong class=\"markup--strong markup--p-strong\">salt_bufs<\/strong>. The buffer is then passed to the kernel so the kernel code can interact with the salt. Once we start going through the kernel code for the Apache Shiro 1 module and you see some working examples, these will start to make more sense. A snippet of the kernel parameters Hashcat documentation is shown below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*-McogVXE8Rt_8XUgMqUqeA.png\" data-image-id=\"1*-McogVXE8Rt_8XUgMqUqeA.png\" data-width=\"975\" data-height=\"852\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">At this point, now that we understand the structure of a kernel, the three methods that we need to implement and what their purposes are along with some necessary prerequisite knowledge, we are ready to begin developing the kernel.<\/p>\n<h4 class=\"graf graf--h4\">The init&nbsp;Method<\/h4>\n<p class=\"graf graf--p\">In order to understand what we need to do in this method, we can refer to the standalone C cracking implementation for inspiration <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/fin3ss3g0d\/Shiro1Tools\/blob\/main\/shiro-crack\/shiro1.c\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/fin3ss3g0d\/Shiro1Tools\/blob\/main\/shiro-crack\/shiro1.c\">here<\/a>.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*nvjRi6M5PiEpoycMNZg0YA.png\" data-image-id=\"1*nvjRi6M5PiEpoycMNZg0YA.png\" data-width=\"975\" data-height=\"1275\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">The piece of code highlighted above is what we will ultimately need to replicate in our <strong class=\"markup--strong markup--p-strong\">init<\/strong> method of our kernel. This will create an initial SHA-512 hash digest using the salt and password. How we can replicate this in our <strong class=\"markup--strong markup--p-strong\">init<\/strong> method of our kernel is shown below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*UWRtK4PUMO-Jqsg5vQHk0A.png\" data-image-id=\"1*UWRtK4PUMO-Jqsg5vQHk0A.png\" data-width=\"975\" data-height=\"773\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">Let\u2019s break this down a little bit. Firstly, we are using a pre-existing Hashcat helper file for SHA-512 (<strong class=\"markup--strong markup--p-strong\">inc_hash_sha512.cl<\/strong>) which already contains the necessary methods we need for the kernel of this algorithm. This is where all of the <strong class=\"markup--strong markup--p-strong\">sha512<\/strong> prefixed methods are coming from as well as the <strong class=\"markup--strong markup--p-strong\">sha512_ctx_t <\/strong>structure. Overall, the method should look really similar to the OpenSSL standalone C cracking application. A question you might have is what is going on with the swap methods? In this particular case, we are converting data between 32-bit and 64-bit integer format as required by the algorithm, which really comes down to how the structures and methods for the cryptographic operations want the data. After updating the <strong class=\"markup--strong markup--p-strong\">sha512_ctx_t <\/strong>structure with the salt and password, we call <strong class=\"markup--strong markup--p-strong\">sha512_final <\/strong>and update the <strong class=\"markup--strong markup--p-strong\">tmps dgst <\/strong>and <strong class=\"markup--strong markup--p-strong\">out<\/strong> buffers with the resulting hash digest. We are now ready to implement the <strong class=\"markup--strong markup--p-strong\">loop<\/strong> method.<\/p>\n<h4 class=\"graf graf--h4\">The loop&nbsp;Method<\/h4>\n<p class=\"graf graf--p\">As shown earlier, this method is where the iterative cryptographic work will take place since this is an iterated hash algorithm. In this case, we will continue creating a new hash based on the previous hash value until the iteration count is reached. The code highlighted from the standalone C cracking application can be used as inspiration for what we will need to implement.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*mUuTT1d3nF_z--3NaNdhww.png\" data-image-id=\"1*mUuTT1d3nF_z--3NaNdhww.png\" data-width=\"975\" data-height=\"1275\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">The relevant portions of the implementation for the kernel loop method are shown below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*NR6BqSL2Kyh_RS-a58DAyA.png\" data-image-id=\"1*NR6BqSL2Kyh_RS-a58DAyA.png\" data-width=\"975\" data-height=\"1340\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">In the beginning of the method, we convert our hash digest contained in the <strong class=\"markup--strong markup--p-strong\">tmps dgst <\/strong>buffer from <strong class=\"markup--strong markup--p-strong\">u64<\/strong> to <strong class=\"markup--strong markup--p-strong\">u32<\/strong>. This is because the <strong class=\"markup--strong markup--p-strong\">sha512_update <\/strong>method is expecting our data to be in <strong class=\"markup--strong markup--p-strong\">u32<\/strong> format and if we try to use the <strong class=\"markup--strong markup--p-strong\">u64<\/strong> data by performing a simple cast, we will produce inaccurate hashes due to the cryptographic operations being performed on data which is not in the expected endianness. We then perform the hashing loop, similarly to the standalone C cracking example. In this case, <strong class=\"markup--strong markup--p-strong\">LOOP_CNT<\/strong> instructs the method how many times to perform the iterative cryptographic operations. Once <strong class=\"markup--strong markup--p-strong\">LOOP_CNT<\/strong> equals the total number of times the hash was supposed to be iterated, the <strong class=\"markup--strong markup--p-strong\">comp<\/strong> method will be called. At the end of the method, we update the <strong class=\"markup--strong markup--p-strong\">out <\/strong>buffer of <strong class=\"markup--strong markup--p-strong\">tmps<\/strong> with the last generated digest which will be used for the comparison in the <strong class=\"markup--strong markup--p-strong\">comp<\/strong> method.<\/p>\n<h4 class=\"graf graf--h4\">The comp&nbsp;Method<\/h4>\n<p class=\"graf graf--p\">This method performs the hash comparison logic, which will essentially check to see if the produced hash from the kernel matches the target hash digest we are trying to crack. The standalone C cracking example simply used <strong class=\"markup--strong markup--p-strong\">memcmp<\/strong> to check and see if the target digest buffer equaled the generated hash buffer. Hashcat has a much more sophisticated way of performing hash comparison which utilizes a bloom filter and an additional binary tree search. An explanation of this can be seen below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*-uTst6s2MOl5fql5sBMzDA.png\" data-image-id=\"1*-uTst6s2MOl5fql5sBMzDA.png\" data-width=\"975\" data-height=\"196\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">As mentioned above, we will follow suit on how to use the <strong class=\"markup--strong markup--p-strong\">COMPARE_M<\/strong> macro. We will assign the final digest to <strong class=\"markup--strong markup--p-strong\">r0<\/strong>\u200a\u2014\u200a<strong class=\"markup--strong markup--p-strong\">r3<\/strong> which needs to be in <strong class=\"markup--strong markup--p-strong\">u32<\/strong> format, then call the <strong class=\"markup--strong markup--p-strong\">#include<\/strong> <strong class=\"markup--strong markup--p-strong\">COMPARE_M<\/strong> macro. The Apache Shiro 1 <strong class=\"markup--strong markup--p-strong\">comp<\/strong> kernel is shown below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*8erAQjT3-JhjjMPjgnFmEQ.png\" data-image-id=\"1*8erAQjT3-JhjjMPjgnFmEQ.png\" data-width=\"975\" data-height=\"763\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">As you can see, we convert the final digest contained in <strong class=\"markup--strong markup--p-strong\">out <\/strong>of <strong class=\"markup--strong markup--p-strong\">tmps<\/strong> to <strong class=\"markup--strong markup--p-strong\">u32<\/strong> (or as much of it as can fit in the four comparison variables) and then call the <strong class=\"markup--strong markup--p-strong\">COMPARE_M<\/strong> macro which will do the bloom filter comparison along with an additional binary tree search for<em class=\"markup--em markup--p-em\"> light speed<\/em> comparisons. At this point, we are done creating the kernel and the module and it is ready for use!<\/p>\n<h3 class=\"graf graf--h3\">Testing the&nbsp;Module<\/h3>\n<h4 class=\"graf graf--h4\">Test Suite Background<\/h4>\n<p class=\"graf graf--p\">Once we have our module kernel and C code put together and we believe we are ready to test it, Hashcat comes with its own testing mechanism called the Test Suite. A snippet of the <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#test-suite\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#test-suite\">documentation<\/a> for the Test Suite can be seen below. The Test Suite is explained in detail at the provided link, but the idea is to provide a way to ensure that a module is working correctly (both the C code and OpenCL kernel).<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*rnQDV7UUpLlEeuTRNAWuCg.png\" data-image-id=\"1*rnQDV7UUpLlEeuTRNAWuCg.png\" data-width=\"975\" data-height=\"676\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">This is done by using a higher-level programming language, in this case Perl, to perform the cryptographic operations. The Test Suite can either test cracking data generated by the test module with the low-level module or verify that the reported cracked data from the low-level module is accurate. While everyone has a different level of knowledge when it comes to cryptography and programming, cryptographic implementations between two programming languages are the same. This means that although the code will look different due to the different syntax of the programming languages, the actual cryptographic operations on the data will remain the same.<\/p>\n<p class=\"graf graf--p\">Why is this a good testing strategy? If we can verify that we can crack data generated by the Perl test module, it is highly likely that our cryptographic operations in our kernel are accurate and true to the algorithm. Additionally, we can conclude that our methods in the module C code are working as expected, providing a way to test the entire module.<\/p>\n<p class=\"graf graf--p\">Before we continue, let\u2019s discuss the test scripts which automate the testing process. Throughout this process, you are going to be working closely with two scripts which are <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#testpl\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#testpl\"><strong class=\"markup--strong markup--p-strong\">test.pl<\/strong><\/a> and <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#testsh\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/docs\/hashcat-plugin-development-guide.md#testsh\"><strong class=\"markup--strong markup--p-strong\">test.sh<\/strong><\/a>. The <strong class=\"markup--strong markup--p-strong\">test.sh <\/strong>script comes with different command line arguments that allow you to change the behavior of testing and automates most of the testing process by executing Hashcat commands generated by <strong class=\"markup--strong markup--p-strong\">test.pl<\/strong>. You can think of it as a wrapper around <strong class=\"markup--strong markup--p-strong\">test.pl<\/strong>. Everything except <strong class=\"markup--strong markup--p-strong\">verify <\/strong>tests will be automated by <strong class=\"markup--strong markup--p-strong\">test.sh<\/strong>.<\/p>\n<h4 class=\"graf graf--h4\">Perl Test Module Development<\/h4>\n<p class=\"graf graf--p\">As you can see in the screenshot above, there are three methods our test module must implement and they are <strong class=\"markup--strong markup--p-strong\">module_constraints<\/strong>, <strong class=\"markup--strong markup--p-strong\">module_generate_hash<\/strong>, and <strong class=\"markup--strong markup--p-strong\">module_verify_hash<\/strong>. There is more <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/tools\/test_modules\/README.md\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/hashcat\/hashcat\/blob\/master\/tools\/test_modules\/README.md\">documentation<\/a> for test modules and an explanation of these methods is provided below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*i3p-ei8aCJmdrh9TUj4xvA.png\" data-image-id=\"1*i3p-ei8aCJmdrh9TUj4xvA.png\" data-width=\"975\" data-height=\"732\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">As you can see, this documentation provides links to various Perl modules that you can look at as examples. I encourage you to try to find a module that is closest to the module you are trying to create as that will contain the most relevant example code. The <strong class=\"markup--strong markup--p-strong\">module_constraints<\/strong> to <strong class=\"markup--strong markup--p-strong\">module_generate_hash<\/strong> implementations for our module can be seen below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*_aZAnKDOTdRfqSTm0QHAeg.png\" data-image-id=\"1*_aZAnKDOTdRfqSTm0QHAeg.png\" data-width=\"975\" data-height=\"1035\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">As shown above, <strong class=\"markup--strong markup--p-strong\">module_constraints<\/strong> returns the minimum and maximum length for a password hashed using this algorithm as well as the size for generated salts, which is 16 bytes. Also shown is <strong class=\"markup--strong markup--p-strong\">module_generate_hash<\/strong>, which takes three arguments being: a password to hash, the salt to use for the hash, and the number of iterations to perform on the hash. It then generates a hash using these arguments and returns it, which will be used as part of testing with <strong class=\"markup--strong markup--p-strong\">test.sh<\/strong>\/<strong class=\"markup--strong markup--p-strong\">test.pl<\/strong>. This method should generate a hash for your algorithm, preferably using Perl cryptography libraries and the arguments passed to the method. The arguments that are passed are controlled by the <strong class=\"markup--strong markup--p-strong\">test.pl<\/strong>\/<strong class=\"markup--strong markup--p-strong\">test.sh <\/strong>programs and based on which test is being performed. It is important to make sure your Perl implementation is accurate according to the specification for the algorithm, otherwise all your testing will be inaccurate. You should test it independently from Hashcat and verify generated hashes are accurate and make sure your logic for <strong class=\"markup--strong markup--p-strong\">module_verify_hash<\/strong> is working correctly before performing a test with the Test Suite.<\/p>\n<h4 class=\"graf graf--h4\">Running test.sh<\/h4>\n<p class=\"graf graf--p\">At this point, we are ready to run <strong class=\"markup--strong markup--p-strong\">test.sh<\/strong> to test cracking using the module and will focus on <strong class=\"markup--strong markup--p-strong\">module_verify_hash<\/strong> later. If you are a Windows user developing\/testing your module on a Windows host, you might have been like me at the beginning of this process and had a reaction similar to the one below regarding the <strong class=\"markup--strong markup--p-strong\">test.sh <\/strong>script.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*qXx1fJpfOXgwWaLX\" data-image-id=\"0*qXx1fJpfOXgwWaLX\" data-width=\"1792\" data-height=\"1024\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">No need to fear though as we can still test our module on Windows using WSL\/WSL2 or Cygwin using the <strong class=\"markup--strong markup--p-strong\">test.sh<\/strong> script and providing \u201c<strong class=\"markup--strong markup--p-strong\">win<\/strong>\u201d for the <strong class=\"markup--strong markup--p-strong\">-o <\/strong>flag. Our command line for running <strong class=\"markup--strong markup--p-strong\">test.sh<\/strong> is displayed below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*bKuBIGTc_aYA-Xc8oKH57A.png\" data-image-id=\"1*bKuBIGTc_aYA-Xc8oKH57A.png\" data-width=\"975\" data-height=\"177\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">Here is an explanation of these flags and their values:<\/p>\n<p class=\"graf graf--p\">\u00b7 <strong class=\"markup--strong markup--p-strong\">-m 12150<\/strong>: specifically test using the <strong class=\"markup--strong markup--p-strong\">m12150.pm<\/strong> test module<\/p>\n<p class=\"graf graf--p\">\u00b7 <strong class=\"markup--strong markup--p-strong\">-a all<\/strong>: test all attack modes<\/p>\n<p class=\"graf graf--p\">\u00b7 <strong class=\"markup--strong markup--p-strong\">-t all<\/strong>: test <strong class=\"markup--strong markup--p-strong\">single<\/strong> and <strong class=\"markup--strong markup--p-strong\">multi<\/strong> hash modes<\/p>\n<p class=\"graf graf--p\">\u00b7 <strong class=\"markup--strong markup--p-strong\">-P<\/strong>: use pure kernels instead of optimized kernels since our module\u2019s kernel is pure without an optimized version<\/p>\n<p class=\"graf graf--p\">\u00b7 <strong class=\"markup--strong markup--p-strong\">-o win<\/strong>: use the Windows operating system (adds&nbsp;.exe file extension to Hashcat binary to run with WSL\/WSL2\/Cygwin)<\/p>\n<p class=\"graf graf--p\"><br><\/p><p class=\"graf graf--p\">The output shown in our screenshot from the <strong class=\"markup--strong markup--p-strong\">test.sh<\/strong> script indicates success for all tests. Since everything was found\/matched and nothing timed out or was skipped, all tests passed. A success from this test command means the module was able to successfully crack hashes generated by the Perl test module. If you were getting results showing hashes were not found\/matched, timeouts, or hashes being skipped, these would be indicators of failed tests. Now onto the <strong class=\"markup--strong markup--p-strong\">module_verify_hash<\/strong> method.<\/p>\n<h4 class=\"graf graf--h4\">Running Verify&nbsp;Test<\/h4>\n<p class=\"graf graf--p\">Since we require a sample of cracked hashes to perform <strong class=\"markup--strong markup--p-strong\">verify<\/strong> tests, they are not automated by <strong class=\"markup--strong markup--p-strong\">test.sh<\/strong> and are run post-crack. The flow for performing a <strong class=\"markup--strong markup--p-strong\">verify<\/strong> test would be to: generate known hashes, crack them to a <strong class=\"markup--strong markup--p-strong\">pot file<\/strong>, and then run <strong class=\"markup--strong markup--p-strong\">test.pl <\/strong>in verify mode while supplying the hash file, hash mode, <strong class=\"markup--strong markup--p-strong\">pot file<\/strong>, and output file as arguments. The purpose of this test is to verify if cracked hashes are being accurately marked. Our implementation for <strong class=\"markup--strong markup--p-strong\">module_verify_hash <\/strong>is shown below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*vLVA2Wz5kQLYM4XOkHU7Nw.png\" data-image-id=\"1*vLVA2Wz5kQLYM4XOkHU7Nw.png\" data-width=\"975\" data-height=\"727\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">As you can see, it will take a line from the <strong class=\"markup--strong markup--p-strong\">pot file<\/strong> and extract the password, salt, and number of iterations from it. From there, it will generate a new hash using <strong class=\"markup--strong markup--p-strong\">module_generate_hash<\/strong>. Next, <strong class=\"markup--strong markup--p-strong\">test.pl<\/strong> will perform a comparison of the newly generated hash against all hashes in the original hash file. If there is not a match, it is an indicator that the module is reporting false positives for cracked hashes and there is likely an issue with the <strong class=\"markup--strong markup--p-strong\">comp <\/strong>method of your kernel. Below is an example of generating hashes to be cracked and used for a <strong class=\"markup--strong markup--p-strong\">verify <\/strong>test using <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/fin3ss3g0d\/Shiro1Tools\/tree\/main\/shiro-hash-generator\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/fin3ss3g0d\/Shiro1Tools\/tree\/main\/shiro-hash-generator\">shiro-hash-generator<\/a>.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*zDXluv9SXKOBLL0vVbOSGg.png\" data-image-id=\"1*zDXluv9SXKOBLL0vVbOSGg.png\" data-width=\"975\" data-height=\"431\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">We can then perform the crack using the command below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*I41JYYcDkoNiRHuuNj-nXA.png\" data-image-id=\"1*I41JYYcDkoNiRHuuNj-nXA.png\" data-width=\"975\" data-height=\"200\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">Following this command, the crack results will be stored in <strong class=\"markup--strong markup--p-strong\">test.potfile <\/strong>in &lt;<strong class=\"markup--strong markup--p-strong\">DIGEST<\/strong>&gt;:&lt;<strong class=\"markup--strong markup--p-strong\">PASSWORD<\/strong>&gt; format. We can then perform our <strong class=\"markup--strong markup--p-strong\">verify <\/strong>test with <strong class=\"markup--strong markup--p-strong\">test.pl<\/strong> which is shown below.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*J_WuLuE-yHC6mVZN0KEK1A.png\" data-image-id=\"1*J_WuLuE-yHC6mVZN0KEK1A.png\" data-width=\"975\" data-height=\"567\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">Looking at the documentation for <strong class=\"markup--strong markup--p-strong\">verify <\/strong>above, we can see that if a hash in the <strong class=\"markup--strong markup--p-strong\">pot file<\/strong> matches an entry in the hashes file, it will be written to the out file indicating a successful verification. After running <strong class=\"markup--strong markup--p-strong\">test.pl<\/strong>, the contents of <strong class=\"markup--strong markup--p-strong\">log.txt<\/strong> are displayed, which contains all of our <strong class=\"markup--strong markup--p-strong\">pot file <\/strong>entries. This result indicates a successful test and that our module is accurately marking hashes as cracked. This concludes testing our module using the Hashcat Test Suite!<\/p>\n<h3 class=\"graf graf--h3\">Conclusion<\/h3>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*HRwxLrwPGkXooG4HDrRXpg.png\" data-image-id=\"1*HRwxLrwPGkXooG4HDrRXpg.png\" data-width=\"975\" data-height=\"556\"><\/figure>\n<h3 class=\"graf graf--h3\">From Weeks to Hours: Hashcat Module Performance<\/h3>\n<p class=\"graf graf--p\">When we discuss performance of the Hashcat module versus the standalone C implementation, the <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/download.weakpass.com\/wordlists\/1948\/weakpass_3a.7z\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/download.weakpass.com\/wordlists\/1948\/weakpass_3a.7z\">weakpass_3a<\/a> wordlist was going to take multiple weeks for one hash to complete after modifying the <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/fin3ss3g0d\/Shiro1Tools\/blob\/main\/shiro-crack\/shiro1.c\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/fin3ss3g0d\/Shiro1Tools\/blob\/main\/shiro-crack\/shiro1.c\">C program<\/a> to take an input hash as a commandline argument. The hash cracking rig we are using (which has 10 NVIDIA RTX 3090\u2019s) was able to perform a crack using the same wordlist against 16 hashes in 1 hour and 45 minutes with a speed of testing hashes at 21613.7 kH\/s (21,613,700 per second) using the Hashcat module.<\/p>\n<p class=\"graf graf--p\"><br><\/p>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*ipwrPdqcZB3O6_svACe-gw.png\" data-image-id=\"1*ipwrPdqcZB3O6_svACe-gw.png\" data-width=\"975\" data-height=\"356\"><\/figure>\n<h3 class=\"graf graf--h3\">Takeaways<\/h3>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*3OiBGJANu1tsF2qf\" data-image-id=\"0*3OiBGJANu1tsF2qf\" data-width=\"1792\" data-height=\"1024\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">Overall, there are some key pieces of information to take away here:<\/p>\n<ul class=\"postList\">\n<li class=\"graf graf--li\">The Apache Shiro 1 SHA-512 hashing algorithm used to have a limited attack surface due to the lack of Hashcat support or similar project that can utilize GPU hardware to crack the algorithm; this is no longer true.<\/li>\n<li class=\"graf graf--li\">Sonatype\u2019s default iteration count is relatively low at 1024 iterations per hash and is actually below the Apache Shiro default iteration, making it a fairly inexpensive algorithm with decent cracking times.<\/li>\n<li class=\"graf graf--li\">Sonatype hashes user credentials for the web application database using this algorithm, if a system is vulnerable to a LFI\/path traversal (i.e. CVE-2024\u20134956) vulnerability, you can extract these hashes from OrientDB&nbsp;<strong class=\"markup--strong markup--li-strong\">.pcl<\/strong> files and then crack them with the Hashcat module. Any other means of gaining access to these files is valid such as compromising a system where these files have been backed up, compromising a system through a different vulnerability, etc.<\/li>\n<li class=\"graf graf--li\">We learned how to create a moderately complex Hashcat module as well as where to find the official documentation for plugin development that can be applied to different algorithms if we come across a situation such as this in the future. We also learned how to test our module to make sure it is working correctly.<\/li>\n<\/ul>\n<figure class=\"graf graf--figure\"><br><\/figure>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*wAkH3KDBhYVmBpfSY0CmCA.png\" data-image-id=\"1*wAkH3KDBhYVmBpfSY0CmCA.png\" data-width=\"975\" data-height=\"556\"><\/figure>\n<p class=\"graf graf--p\"><br><\/p>\n<p class=\"graf graf--p\">The advice I will give at the end of this piece of writing is to keep calm and hack the planet!<\/p>\n<\/div>\n<\/div>\n<\/section>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>&nbsp; Introduction During a recent assessment, we identified a server running Nexus Repository 3 that was vulnerable to CVE-2024\u20134956. This [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1],"tags":[],"class_list":["post-436","post","type-post","status-publish","format-standard","hentry","category-blog"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/posts\/436","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/comments?post=436"}],"version-history":[{"count":3,"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/posts\/436\/revisions"}],"predecessor-version":[{"id":439,"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/posts\/436\/revisions\/439"}],"wp:attachment":[{"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/media?parent=436"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/categories?post=436"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/tags?post=436"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}