peplum-john 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3557101f19534057d6928e39832552c6d3f752efc61ab5818f32dc12c4bf73fa
4
+ data.tar.gz: 9f52968910d916f5f29066a21d68afa0d12b9e0e1839145d77c907e4ab485437
5
+ SHA512:
6
+ metadata.gz: 3dea930e2f89973e7bd90830352d709db0274aceb90daad387760c6f3e83df2422f488ed262c0a22aeb76993fc6c24e0639e959a3fa11f6e8e52a382b5ca210c
7
+ data.tar.gz: 3bbf00ab6898ce84806a4dc92e082705ec1134ec32d656c4d7e2a861006cc86652a30074d8f38ede56680ac935f14cbd5cf26e2f1f5dbe1093e406e34ec38671
data/bin/console ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "peplum/john"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ require "irb"
11
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,44 @@
1
+ require 'json'
2
+ require 'tmpdir'
3
+ require 'net/http'
4
+
5
+ def response
6
+ if @last_response['Content-Type'].include? 'json'
7
+ data = JSON.load( @last_response.body )
8
+ else
9
+ data = @last_response.body
10
+ end
11
+ {
12
+ code: @last_response.code,
13
+ data: data
14
+ }
15
+ end
16
+
17
+ def response_data
18
+ response[:data]
19
+ end
20
+
21
+ def request( method, resource = nil, parameters = nil )
22
+ uri = URI( "http://127.0.0.1:7331/#{resource}" )
23
+
24
+ Net::HTTP.start( uri.host, uri.port) do |http|
25
+ case method
26
+ when :get
27
+ uri.query = URI.encode_www_form( parameters ) if parameters
28
+ request = Net::HTTP::Get.new( uri )
29
+
30
+ when :post
31
+ request = Net::HTTP::Post.new( uri )
32
+ request.body = parameters.to_json
33
+
34
+ when :delete
35
+ request = Net::HTTP::Delete.new( uri )
36
+
37
+ when :put
38
+ request = Net::HTTP::Put.new( uri )
39
+ request.body = parameters.to_json
40
+ end
41
+
42
+ @last_response = http.request( request )
43
+ end
44
+ end
data/examples/rest.rb ADDED
@@ -0,0 +1,57 @@
1
+ require 'peplum/john'
2
+ require 'pp'
3
+ require_relative 'rest/helpers'
4
+
5
+ # Boot up our REST server for easy integration.
6
+ rest_pid = Peplum::John::Application.spawn( :rest, daemonize: true )
7
+ at_exit { Cuboid::Processes::Manager.kill rest_pid }
8
+
9
+ # Wait for the REST server to boot up.
10
+ while sleep 1
11
+ begin
12
+ request :get
13
+ rescue Errno::ECONNREFUSED
14
+ next
15
+ end
16
+
17
+ break
18
+ end
19
+
20
+ # Assign an Agent to the REST service for it to provide us with Instances.
21
+ john_agent = Peplum::John::Application.spawn( :agent, daemonize: true )
22
+ request :put, 'agent/url', john_agent.url
23
+ at_exit { john_agent.shutdown rescue nil }
24
+
25
+ # Create a new Instance and run with the following options.
26
+ request :post, 'instances', {
27
+ peplum: {
28
+ objects: %w(
29
+ 6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090
30
+ 36f583dd16f4e1e201eb1e6f6d8e35a2ccb3bbe2658de46b4ffae7b0e9ed872e
31
+ ),
32
+ max_workers: 2
33
+ },
34
+ payload: {
35
+ format: 'raw-sha256'
36
+ }
37
+ }
38
+
39
+ # The ID is used to represent that instance and allow us to manage it from here on out.
40
+ instance_id = response_data['id']
41
+
42
+ while sleep( 1 )
43
+ # Continue looping while instance status is 'busy'.
44
+ request :get, "instances/#{instance_id}"
45
+ break if !response_data['busy']
46
+ end
47
+
48
+ puts '*' * 88
49
+
50
+ # Get the report.
51
+ request :get, "instances/#{instance_id}/report.json"
52
+
53
+ # Print out the report.
54
+ puts JSON.pretty_generate( JSON.load( response_data['data'] ) )
55
+
56
+ # Shutdown the Instance.
57
+ request :delete, "instances/#{instance_id}"
data/examples/rpc.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'pp'
2
+ require 'peplum/john'
3
+
4
+ # Spawn an Agent as a daemon.
5
+ john_agent = Peplum::John::Application.spawn( :agent, daemonize: true )
6
+ at_exit { john_agent.shutdown rescue nil }
7
+
8
+ # Spawn and connect to an Instance.
9
+ john = Peplum::John::Application.connect( john_agent.spawn )
10
+ # Don't forget this!
11
+ at_exit { john.shutdown }
12
+
13
+ john.run(
14
+ peplum: {
15
+ objects: %w(
16
+ 6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090
17
+ 36f583dd16f4e1e201eb1e6f6d8e35a2ccb3bbe2658de46b4ffae7b0e9ed872e
18
+ ),
19
+ max_workers: 2
20
+ },
21
+ payload: {
22
+ format: 'raw-sha256'
23
+ }
24
+ )
25
+
26
+ # Waiting to complete.
27
+ sleep 1 while john.running?
28
+
29
+ # Hooray!
30
+ puts JSON.pretty_generate( john.generate_report.data )
@@ -0,0 +1,144 @@
1
+ require 'tmpdir'
2
+ require 'fileutils'
3
+
4
+ module Peplum
5
+ class John
6
+ class Application
7
+
8
+ module Payload
9
+
10
+ # For some reason doesn't work when specifying sane directories.
11
+ HASHES_FILE = "hashes.#{Process.pid}.txt"
12
+ at_exit { FileUtils.rm_f HASHES_FILE }
13
+
14
+ POT_FILE = "hashes.#{Process.pid}.pot"
15
+ at_exit { FileUtils.rm_f POT_FILE }
16
+
17
+ JOHN = 'john-the-ripper'
18
+
19
+ FORMATS = Set.new(%w(descrypt bsdicrypt md5crypt md5crypt-long bcrypt scrypt LM AFS
20
+ tripcode AndroidBackup adxcrypt agilekeychain aix-ssha1 aix-ssha256
21
+ aix-ssha512 andOTP ansible argon2 as400-des as400-ssha1 asa-md5
22
+ AxCrypt AzureAD BestCrypt BestCryptVE4 bfegg Bitcoin BitLocker
23
+ bitshares Bitwarden BKS Blackberry-ES10 WoWSRP Blockchain cardano
24
+ chap Clipperz cloudkeychain dynamic_n cq CRC32 cryptoSafe sha1crypt
25
+ sha256crypt sha512crypt Citrix_NS10 dahua dashlane diskcryptor Django
26
+ django-scrypt dmd5 dmg dominosec dominosec8 DPAPImk dragonfly3-32
27
+ dragonfly3-64 dragonfly4-32 dragonfly4-64 Drupal7 eCryptfs eigrp
28
+ electrum ENCDataVault-MD5 ENCDataVault-PBKDF2 EncFS enpass EPI
29
+ EPiServer ethereum fde Fortigate256 Fortigate FormSpring FVDE geli
30
+ gost gpg HAVAL-128-4 HAVAL-256-3 hdaa hMailServer hsrp IKE ipb2
31
+ itunes-backup iwork KeePass keychain keyring keystore known_hosts
32
+ krb4 krb5 krb5asrep krb5pa-sha1 krb5pa-md5 krb5tgs krb5-17 krb5-18
33
+ krb5-3 kwallet lp lpcli leet lotus5 lotus85 LUKS MD2 mdc2
34
+ MediaWiki monero money MongoDB scram Mozilla mscash mscash2 MSCHAPv2
35
+ mschapv2-naive mssql mssql05 mssql12 multibit mysqlna mysql-sha1
36
+ mysql net-ah nethalflm netlm netlmv2 net-md5 netntlmv2 netntlm
37
+ netntlm-naive net-sha1 nk notes md5ns nsec3 NT NT-long o10glogon
38
+ o3logon o5logon ODF Office oldoffice OpenBSD-SoftRAID openssl-enc
39
+ oracle oracle11 Oracle12C osc ospf Padlock Palshop Panama
40
+ PBKDF2-HMAC-MD4 PBKDF2-HMAC-MD5 PBKDF2-HMAC-SHA1 PBKDF2-HMAC-SHA256
41
+ PBKDF2-HMAC-SHA512 PDF PEM pfx pgpdisk pgpsda pgpwde phpass PHPS
42
+ PHPS2 pix-md5 PKZIP po postgres PST PuTTY pwsafe qnx RACF
43
+ RACF-KDFAES radius RAdmin RAKP rar RAR5 Raw-SHA512 Raw-Blake2
44
+ Raw-Keccak Raw-Keccak-256 Raw-MD4 Raw-MD5 Raw-MD5u Raw-SHA1
45
+ Raw-SHA1-AxCrypt Raw-SHA1-Linkedin Raw-SHA224 Raw-SHA256 Raw-SHA3
46
+ Raw-SHA384 restic ripemd-128 ripemd-160 rsvp RVARY Siemens-S7
47
+ Salted-SHA1 SSHA512 sapb sapg saph sappse securezip 7z Signal SIP
48
+ skein-256 skein-512 skey SL3 Snefru-128 Snefru-256 LastPass SNMP
49
+ solarwinds SSH sspr Stribog-256 Stribog-512 STRIP SunMD5 SybaseASE
50
+ Sybase-PROP tacacs-plus tcp-md5 telegram tezos Tiger timeroast
51
+ tc_aes_xts tc_ripemd160 tc_ripemd160boot tc_sha512 tc_whirlpool vdi
52
+ OpenVMS vmx VNC vtp wbb3 whirlpool whirlpool0 whirlpool1 wpapsk
53
+ wpapsk-pmk xmpp-scram xsha xsha512 zed ZIP ZipMonster plaintext
54
+ has-160 HMAC-MD5 HMAC-SHA1 HMAC-SHA224 HMAC-SHA256 HMAC-SHA384
55
+ HMAC-SHA512 AndroidBackup-opencl agilekeychain-opencl ansible-opencl
56
+ axcrypt-opencl axcrypt2-opencl bcrypt-opencl Bitcoin-opencl
57
+ BitLocker-opencl bitwarden-opencl blockchain-opencl cloudkeychain-opencl
58
+ md5crypt-opencl cryptosafe-opencl sha1crypt-opencl sha256crypt-opencl
59
+ sha512crypt-opencl dashlane-opencl descrypt-opencl diskcryptor-opencl
60
+ diskcryptor-aes-opencl dmg-opencl electrum-modern-opencl EncFS-opencl
61
+ enpass-opencl ethereum-opencl ethereum-presale-opencl FVDE-opencl
62
+ geli-opencl gpg-opencl iwork-opencl KeePass-opencl keychain-opencl
63
+ keyring-opencl keystore-opencl krb5pa-md5-opencl krb5pa-sha1-opencl
64
+ krb5tgs-opencl krb5asrep-aes-opencl lp-opencl lpcli-opencl LM-opencl
65
+ lotus5-opencl mscash-opencl mscash2-opencl mysql-sha1-opencl
66
+ notes-opencl NT-opencl ntlmv2-opencl NT-long-opencl o5logon-opencl
67
+ ODF-opencl office-opencl oldoffice-opencl OpenBSD-SoftRAID-opencl
68
+ PBKDF2-HMAC-SHA256-opencl PBKDF2-HMAC-SHA512-opencl PBKDF2-HMAC-MD4-opencl
69
+ PBKDF2-HMAC-MD5-opencl PBKDF2-HMAC-SHA1-opencl pem-opencl pfx-opencl
70
+ pgpdisk-opencl pgpsda-opencl pgpwde-opencl phpass-opencl pwsafe-opencl
71
+ RAKP-opencl rar-opencl RAR5-opencl raw-MD4-opencl raw-MD5-opencl
72
+ raw-SHA1-opencl raw-SHA256-opencl raw-SHA512-free-opencl
73
+ raw-SHA512-opencl salted-SHA1-opencl sappse-opencl 7z-opencl SL3-opencl
74
+ solarwinds-opencl ssh-opencl sspr-opencl strip-opencl TrueCrypt-opencl
75
+ telegram-opencl tezos-opencl timeroast-opencl vmx-opencl wpapsk-opencl
76
+ wpapsk-pmk-opencl XSHA512-free-opencl XSHA512-opencl zed-opencl
77
+ ))
78
+
79
+ def run( hashes, options )
80
+ validate( options )
81
+
82
+ File.open( HASHES_FILE, 'w+', 0666 ) do |f|
83
+ hashes.each do |hash|
84
+ f.puts hash
85
+ end
86
+ end
87
+
88
+ _run options
89
+ end
90
+
91
+ # Distribute `objects` into `chunks` amount of groups, one for each worker.
92
+ #
93
+ # @param [Array] objects All objects that need to be processed.
94
+ # @param [Integer] chunks Amount of object groups that should be generated.
95
+ #
96
+ # @return [Array<Array<Object>>] `objects` split in `chunks` amount of groups
97
+ # @abstract
98
+ def group( objects, chunks )
99
+ objects.chunk chunks
100
+ end
101
+
102
+ # Merge result `data` for reporting.
103
+ #
104
+ # @param [Array] data Report data from workers.
105
+ # @abstract
106
+ def merge( data )
107
+ f = data.pop
108
+ data.each { |d| f.merge! d }
109
+ f
110
+ end
111
+
112
+ private
113
+
114
+ def executable
115
+ @executable ||= `which #{JOHN}`.strip
116
+ return @executable if !@executable.empty?
117
+
118
+ fail Error, 'Could not locate John The Ripper executable!'
119
+ end
120
+
121
+ def _run( options )
122
+ `#{executable} --no-log --pot=#{POT_FILE} --format=#{options['format']} #{HASHES_FILE} 2> /dev/null`
123
+ `#{executable} --format=#{options['format']} #{HASHES_FILE} 2> /dev/null`
124
+
125
+ results = {}
126
+ File.open( POT_FILE , 'r' ) do |f|
127
+ line = f.readline
128
+ hash, password = line.split( '$' ).last.split( ':' )
129
+ results[hash] = password.strip
130
+ end
131
+ results
132
+ end
133
+
134
+ def validate( options )
135
+ fail ArgumentError, 'Missing hash format' if !options['format']
136
+ fail ArgumentError, "Unknown format: options['format']" if FORMATS.include? options['format']
137
+ end
138
+
139
+ extend self
140
+ end
141
+
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'peplum'
4
+
5
+ module Peplum
6
+ class John
7
+
8
+ class Application < Peplum::Application
9
+ require_relative "application/payload"
10
+
11
+ provision_memory 100 * 1024 * 1024
12
+ provision_disk 100 * 1024 * 1024
13
+
14
+ def payload
15
+ Payload
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Peplum
4
+ class John
5
+ VERSION = "0.2.0"
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'peplum'
4
+
5
+ module Peplum
6
+ class John
7
+
8
+ require_relative "john/version"
9
+
10
+ class Error < Peplum::Error; end
11
+
12
+ require_relative "john/application"
13
+
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/peplum/john/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "peplum-john"
7
+ spec.version = Peplum::John::VERSION
8
+ spec.authors = ["Tasos Laskos"]
9
+ spec.email = ["tasos.laskos@ecsypno.com"]
10
+
11
+ spec.summary = "Peplum-powered John the Ripper."
12
+ spec.description = "A distributed approach to the John the Ripper password recovery tool"
13
+ spec.homepage = "http://ecsypno.com/"
14
+ spec.required_ruby_version = ">= 2.6.0"
15
+
16
+ spec.files = Dir.glob( 'bin/*')
17
+ spec.files += Dir.glob( 'lib/**/*')
18
+ spec.files += Dir.glob( 'examples/**/*')
19
+ spec.files += %w(peplum-john.gemspec)
20
+
21
+
22
+ spec.add_dependency "peplum"
23
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: peplum-john
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Tasos Laskos
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-05-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: peplum
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: A distributed approach to the John the Ripper password recovery tool
28
+ email:
29
+ - tasos.laskos@ecsypno.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - bin/console
35
+ - bin/setup
36
+ - examples/rest.rb
37
+ - examples/rest/helpers.rb
38
+ - examples/rpc.rb
39
+ - lib/peplum/john.rb
40
+ - lib/peplum/john/application.rb
41
+ - lib/peplum/john/application/payload.rb
42
+ - lib/peplum/john/version.rb
43
+ - peplum-john.gemspec
44
+ homepage: http://ecsypno.com/
45
+ licenses: []
46
+ metadata: {}
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 2.6.0
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubygems_version: 3.4.13
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: Peplum-powered John the Ripper.
66
+ test_files: []