pwn 0.5.84 → 0.5.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -3
- data/README.md +3 -3
- data/lib/pwn/aws.rb +1 -1
- data/lib/pwn/ffi/stdio.rb +40 -0
- data/lib/pwn/ffi.rb +2 -2
- data/lib/pwn/plugins.rb +1 -2
- data/lib/pwn/reports.rb +1 -1
- data/lib/pwn/sast.rb +1 -1
- data/lib/pwn/version.rb +1 -1
- data/lib/pwn/www.rb +1 -1
- data/lib/pwn.rb +1 -1
- data/spec/lib/pwn/{plugins/meshtastic_spec.rb → ffi/stdio_spec.rb} +3 -3
- metadata +9 -9
- data/lib/pwn/plugins/meshtastic.rb +0 -265
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fb237056a0ee9908b27a0961e1e0683b8d22dacb80442543abc26c5e810faa1c
|
|
4
|
+
data.tar.gz: 4883a7d72288bf56d59b80e1d6fd292cff3245ac8260c9eb899a89378af11d28
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 512792cf23e0eb392d4e1a56e8e530ec38f99c5c93c99f6535fa861c5091bd391990efaccafa24527a32b8246d49f7c44e5cf89c407a391f3feca428274c1e3e
|
|
7
|
+
data.tar.gz: 9675bb2d5ad1cd1af9dcf4a8396cdf7880478ae739f9b9b606438ed2f7d5dd8c908a5dba45f384cb762c633d5b88beb11d84bcfbb6dd9ba6d5a3d3c4d8d84b41
|
data/Gemfile
CHANGED
|
@@ -47,8 +47,7 @@ gem 'libusb', '0.7.1'
|
|
|
47
47
|
gem 'luhn', '1.0.2'
|
|
48
48
|
gem 'mail', '2.8.1'
|
|
49
49
|
gem 'metasm', '1.0.5'
|
|
50
|
-
gem '
|
|
51
|
-
# gem 'mongo', '2.19.3'
|
|
50
|
+
gem 'mongo', '2.20.0'
|
|
52
51
|
gem 'msfrpc-client', '1.1.2'
|
|
53
52
|
gem 'netaddr', '2.0.6'
|
|
54
53
|
gem 'net-ldap', '0.19.0'
|
|
@@ -84,7 +83,7 @@ gem 'ruby-nmap', '1.0.3'
|
|
|
84
83
|
gem 'ruby-saml', '1.16.0'
|
|
85
84
|
gem 'rvm', '1.11.3.9'
|
|
86
85
|
gem 'savon', '2.15.0'
|
|
87
|
-
gem 'selenium-devtools', '0.
|
|
86
|
+
gem 'selenium-devtools', '0.124.0'
|
|
88
87
|
gem 'serialport', '1.3.2'
|
|
89
88
|
# gem 'sinatra', '4.0.0'
|
|
90
89
|
gem 'slack-ruby-client', '2.3.0'
|
data/README.md
CHANGED
|
@@ -37,7 +37,7 @@ $ cd /opt/pwn
|
|
|
37
37
|
$ ./install.sh
|
|
38
38
|
$ ./install.sh ruby-gem
|
|
39
39
|
$ pwn
|
|
40
|
-
pwn[v0.5.
|
|
40
|
+
pwn[v0.5.85]:001 >>> PWN.help
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
[](https://youtu.be/G7iLUY4FzsI)
|
|
@@ -52,7 +52,7 @@ $ rvm use ruby-3.3.0@pwn
|
|
|
52
52
|
$ gem uninstall --all --executables pwn
|
|
53
53
|
$ gem install --verbose pwn
|
|
54
54
|
$ pwn
|
|
55
|
-
pwn[v0.5.
|
|
55
|
+
pwn[v0.5.85]:001 >>> PWN.help
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
If you're using a multi-user install of RVM do:
|
|
@@ -62,7 +62,7 @@ $ rvm use ruby-3.3.0@pwn
|
|
|
62
62
|
$ rvmsudo gem uninstall --all --executables pwn
|
|
63
63
|
$ rvmsudo gem install --verbose pwn
|
|
64
64
|
$ pwn
|
|
65
|
-
pwn[v0.5.
|
|
65
|
+
pwn[v0.5.85]:001 >>> PWN.help
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
PWN periodically upgrades to the latest version of Ruby which is reflected in `/opt/pwn/.ruby-version`. The easiest way to upgrade to the latest version of Ruby from a previous PWN installation is to run the following script:
|
data/lib/pwn/aws.rb
CHANGED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'ffi'
|
|
4
|
+
|
|
5
|
+
module PWN
|
|
6
|
+
module FFI
|
|
7
|
+
# This plugin is a wrapper for the standard I/O functions in libc.
|
|
8
|
+
module Stdio
|
|
9
|
+
extend FFI::Library
|
|
10
|
+
|
|
11
|
+
ffi_lib FFI::Library::LIBC
|
|
12
|
+
|
|
13
|
+
attach_function(:puts, [:string], :int)
|
|
14
|
+
attach_function(:printf, %i[string varargs], :int, convention: :default)
|
|
15
|
+
attach_function(:scanf, %i[string varargs], :int)
|
|
16
|
+
|
|
17
|
+
# Author(s):: 0day Inc. <request.pentest@0dayinc.com>
|
|
18
|
+
|
|
19
|
+
public_class_method def self.authors
|
|
20
|
+
"AUTHOR(S):
|
|
21
|
+
0day Inc. <request.pentest@0dayinc.com>
|
|
22
|
+
"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Display Usage for this Module
|
|
26
|
+
|
|
27
|
+
public_class_method def self.help
|
|
28
|
+
puts "USAGE:
|
|
29
|
+
#{self}.puts string
|
|
30
|
+
#{self}.printf(\"format string\", str, int, etc)
|
|
31
|
+
|
|
32
|
+
scanf_buffer = FFI::MemoryPointer.new(:char, 100)
|
|
33
|
+
#{self}.scanf(\"format string\", scanf_buffer)
|
|
34
|
+
|
|
35
|
+
#{self}.authors
|
|
36
|
+
"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/pwn/ffi.rb
CHANGED
|
@@ -5,9 +5,9 @@ module PWN
|
|
|
5
5
|
# into memory only when they're needed. For more information, see:
|
|
6
6
|
# http://www.rubyinside.com/ruby-techniques-revealed-autoload-1652.html
|
|
7
7
|
module FFI
|
|
8
|
-
|
|
8
|
+
autoload :Stdio, 'pwn/ffi/stdio'
|
|
9
9
|
|
|
10
|
-
# Display a List of Every PWN
|
|
10
|
+
# Display a List of Every PWN::FFI Module
|
|
11
11
|
|
|
12
12
|
public_class_method def self.help
|
|
13
13
|
constants.sort
|
data/lib/pwn/plugins.rb
CHANGED
|
@@ -37,7 +37,6 @@ module PWN
|
|
|
37
37
|
autoload :JSONPathify, 'pwn/plugins/json_pathify'
|
|
38
38
|
autoload :Log, 'pwn/plugins/log'
|
|
39
39
|
autoload :MailAgent, 'pwn/plugins/mail_agent'
|
|
40
|
-
autoload :Meshtastic, 'pwn/plugins/meshtastic'
|
|
41
40
|
autoload :Metasploit, 'pwn/plugins/metasploit'
|
|
42
41
|
autoload :MonkeyPatch, 'pwn/plugins/monkey_patch'
|
|
43
42
|
autoload :MSR206, 'pwn/plugins/msr206'
|
|
@@ -75,7 +74,7 @@ module PWN
|
|
|
75
74
|
autoload :Vsphere, 'pwn/plugins/vsphere'
|
|
76
75
|
autoload :XXD, 'pwn/plugins/xxd'
|
|
77
76
|
|
|
78
|
-
# Display a List of Every PWN
|
|
77
|
+
# Display a List of Every PWN::Plugins Module
|
|
79
78
|
|
|
80
79
|
public_class_method def self.help
|
|
81
80
|
constants.sort
|
data/lib/pwn/reports.rb
CHANGED
data/lib/pwn/sast.rb
CHANGED
|
@@ -50,7 +50,7 @@ module PWN
|
|
|
50
50
|
autoload :Version, 'pwn/sast/version'
|
|
51
51
|
autoload :WindowLocationHash, 'pwn/sast/window_location_hash'
|
|
52
52
|
|
|
53
|
-
# Display a List of
|
|
53
|
+
# Display a List of Every PWN::SAST Module
|
|
54
54
|
|
|
55
55
|
public_class_method def self.help
|
|
56
56
|
constants.sort
|
data/lib/pwn/version.rb
CHANGED
data/lib/pwn/www.rb
CHANGED
data/lib/pwn.rb
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
require 'spec_helper'
|
|
4
4
|
|
|
5
|
-
describe PWN::
|
|
5
|
+
describe PWN::FFI::Stdio do
|
|
6
6
|
it 'should display information for authors' do
|
|
7
|
-
authors_response = PWN::
|
|
7
|
+
authors_response = PWN::FFI::Stdio
|
|
8
8
|
expect(authors_response).to respond_to :authors
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
it 'should display information for existing help method' do
|
|
12
|
-
help_response = PWN::
|
|
12
|
+
help_response = PWN::FFI::Stdio
|
|
13
13
|
expect(help_response).to respond_to :help
|
|
14
14
|
end
|
|
15
15
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pwn
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.85
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- 0day Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-04-
|
|
11
|
+
date: 2024-04-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -487,19 +487,19 @@ dependencies:
|
|
|
487
487
|
- !ruby/object:Gem::Version
|
|
488
488
|
version: 1.0.5
|
|
489
489
|
- !ruby/object:Gem::Dependency
|
|
490
|
-
name:
|
|
490
|
+
name: mongo
|
|
491
491
|
requirement: !ruby/object:Gem::Requirement
|
|
492
492
|
requirements:
|
|
493
493
|
- - '='
|
|
494
494
|
- !ruby/object:Gem::Version
|
|
495
|
-
version:
|
|
495
|
+
version: 2.20.0
|
|
496
496
|
type: :runtime
|
|
497
497
|
prerelease: false
|
|
498
498
|
version_requirements: !ruby/object:Gem::Requirement
|
|
499
499
|
requirements:
|
|
500
500
|
- - '='
|
|
501
501
|
- !ruby/object:Gem::Version
|
|
502
|
-
version:
|
|
502
|
+
version: 2.20.0
|
|
503
503
|
- !ruby/object:Gem::Dependency
|
|
504
504
|
name: msfrpc-client
|
|
505
505
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -996,14 +996,14 @@ dependencies:
|
|
|
996
996
|
requirements:
|
|
997
997
|
- - '='
|
|
998
998
|
- !ruby/object:Gem::Version
|
|
999
|
-
version: 0.
|
|
999
|
+
version: 0.124.0
|
|
1000
1000
|
type: :runtime
|
|
1001
1001
|
prerelease: false
|
|
1002
1002
|
version_requirements: !ruby/object:Gem::Requirement
|
|
1003
1003
|
requirements:
|
|
1004
1004
|
- - '='
|
|
1005
1005
|
- !ruby/object:Gem::Version
|
|
1006
|
-
version: 0.
|
|
1006
|
+
version: 0.124.0
|
|
1007
1007
|
- !ruby/object:Gem::Dependency
|
|
1008
1008
|
name: serialport
|
|
1009
1009
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -1763,6 +1763,7 @@ files:
|
|
|
1763
1763
|
- lib/pwn/banner/radare2.rb
|
|
1764
1764
|
- lib/pwn/banner/white_rabbit.rb
|
|
1765
1765
|
- lib/pwn/ffi.rb
|
|
1766
|
+
- lib/pwn/ffi/stdio.rb
|
|
1766
1767
|
- lib/pwn/plugins.rb
|
|
1767
1768
|
- lib/pwn/plugins/android.rb
|
|
1768
1769
|
- lib/pwn/plugins/assembly.rb
|
|
@@ -1795,7 +1796,6 @@ files:
|
|
|
1795
1796
|
- lib/pwn/plugins/json_pathify.rb
|
|
1796
1797
|
- lib/pwn/plugins/log.rb
|
|
1797
1798
|
- lib/pwn/plugins/mail_agent.rb
|
|
1798
|
-
- lib/pwn/plugins/meshtastic.rb
|
|
1799
1799
|
- lib/pwn/plugins/metasploit.rb
|
|
1800
1800
|
- lib/pwn/plugins/monkey_patch.rb
|
|
1801
1801
|
- lib/pwn/plugins/msr206.rb
|
|
@@ -2094,6 +2094,7 @@ files:
|
|
|
2094
2094
|
- spec/lib/pwn/banner/radare2_spec.rb
|
|
2095
2095
|
- spec/lib/pwn/banner/white_rabbit_spec.rb
|
|
2096
2096
|
- spec/lib/pwn/banner_spec.rb
|
|
2097
|
+
- spec/lib/pwn/ffi/stdio_spec.rb
|
|
2097
2098
|
- spec/lib/pwn/ffi_spec.rb
|
|
2098
2099
|
- spec/lib/pwn/plugins/android_spec.rb
|
|
2099
2100
|
- spec/lib/pwn/plugins/assembly_spec.rb
|
|
@@ -2126,7 +2127,6 @@ files:
|
|
|
2126
2127
|
- spec/lib/pwn/plugins/json_pathify_spec.rb
|
|
2127
2128
|
- spec/lib/pwn/plugins/log_spec.rb
|
|
2128
2129
|
- spec/lib/pwn/plugins/mail_agent_spec.rb
|
|
2129
|
-
- spec/lib/pwn/plugins/meshtastic_spec.rb
|
|
2130
2130
|
- spec/lib/pwn/plugins/metasploit_spec.rb
|
|
2131
2131
|
- spec/lib/pwn/plugins/monkey_patch_spec.rb
|
|
2132
2132
|
- spec/lib/pwn/plugins/msr206_spec.rb
|
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'base64'
|
|
4
|
-
require 'geocoder'
|
|
5
|
-
require 'json'
|
|
6
|
-
require 'mqtt'
|
|
7
|
-
require 'openssl'
|
|
8
|
-
require 'securerandom'
|
|
9
|
-
|
|
10
|
-
module PWN
|
|
11
|
-
module Plugins
|
|
12
|
-
# Plugin used to interact with Meshtastic nodes
|
|
13
|
-
module Meshtastic
|
|
14
|
-
# Supported Method Parameters::
|
|
15
|
-
# mqtt_obj = PWN::Plugins::Meshtastic.connect(
|
|
16
|
-
# host: 'optional - mqtt host (default: mqtt.meshtastic.org)',
|
|
17
|
-
# port: 'optional - mqtt port (defaults: 1883)',
|
|
18
|
-
# username: 'optional - mqtt username (default: meshdev)',
|
|
19
|
-
# password: 'optional - (default: large4cats)'
|
|
20
|
-
# )
|
|
21
|
-
|
|
22
|
-
public_class_method def self.connect(opts = {})
|
|
23
|
-
# Publicly available MQTT server / credentials by default
|
|
24
|
-
host = opts[:host] ||= 'mqtt.meshtastic.org'
|
|
25
|
-
port = opts[:port] ||= 1883
|
|
26
|
-
username = opts[:username] ||= 'meshdev'
|
|
27
|
-
password = opts[:password] ||= 'large4cats'
|
|
28
|
-
|
|
29
|
-
mqtt_obj = MQTT::Client.connect(
|
|
30
|
-
host: host,
|
|
31
|
-
port: port,
|
|
32
|
-
username: username,
|
|
33
|
-
password: password
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
mqtt_obj.client_id = SecureRandom.random_bytes(8).unpack1('H*')
|
|
37
|
-
|
|
38
|
-
mqtt_obj
|
|
39
|
-
rescue StandardError => e
|
|
40
|
-
raise e
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Supported Method Parameters::
|
|
44
|
-
# PWN::Plugins::Meshtastic.subscribe(
|
|
45
|
-
# mqtt_obj: 'required - mqtt_obj returned from #connect method'
|
|
46
|
-
# region: 'optional - region (default: US)',
|
|
47
|
-
# channel: 'optional - channel name (default: LongFast)',
|
|
48
|
-
# psk: 'optional - channel pre-shared key (default: AQ==)',
|
|
49
|
-
# qos: 'optional - quality of service (default: 0)',
|
|
50
|
-
# json: 'optional - JSON output (default: false)'
|
|
51
|
-
# )
|
|
52
|
-
|
|
53
|
-
public_class_method def self.subscribe(opts = {})
|
|
54
|
-
mqtt_obj = opts[:mqtt_obj]
|
|
55
|
-
region = opts[:region] ||= 'US'
|
|
56
|
-
channel = opts[:channel] ||= 'LongFast'
|
|
57
|
-
psk = opts[:psk] ||= 'AQ=='
|
|
58
|
-
qos = opts[:qos] ||= 0
|
|
59
|
-
json = opts[:json] ||= false
|
|
60
|
-
|
|
61
|
-
# TODO: Find JSON URI for this
|
|
62
|
-
root_topic = "msh/#{region}/2/json" if json
|
|
63
|
-
# root_topic = "msh/#{region}/2/e" unless json
|
|
64
|
-
root_topic = "msh/#{region}/2/c" unless json
|
|
65
|
-
mqtt_obj.subscribe("#{root_topic}/#{channel}/#", qos)
|
|
66
|
-
|
|
67
|
-
# Decrypt the message
|
|
68
|
-
# Our AES key is 128 or 256 bits, shared as part of the 'Channel' specification.
|
|
69
|
-
|
|
70
|
-
# Actual pre-shared key for LongFast channel
|
|
71
|
-
psk = '1PG7OiApB1nwvP+rz05pAQ==' if channel == 'LongFast'
|
|
72
|
-
padded_psk = psk.ljust(psk.length + ((4 - (psk.length % 4)) % 4), '=')
|
|
73
|
-
replaced_psk = padded_psk.gsub('-', '+').gsub('_', '/')
|
|
74
|
-
psk = replaced_psk
|
|
75
|
-
dec_psk = Base64.strict_decode64(psk)
|
|
76
|
-
|
|
77
|
-
# cipher = OpenSSL::Cipher.new('AES-256-CTR')
|
|
78
|
-
cipher = OpenSSL::Cipher.new('AES-128-CTR')
|
|
79
|
-
|
|
80
|
-
if json
|
|
81
|
-
mqtt_obj.get_packet do |json_packet|
|
|
82
|
-
puts '-' * 80
|
|
83
|
-
packet = JSON.parse(json_packet.payload, symbolize_names: true)
|
|
84
|
-
puts JSON.pretty_generate(packet)
|
|
85
|
-
puts '-' * 80
|
|
86
|
-
puts "\n\n\n"
|
|
87
|
-
end
|
|
88
|
-
else
|
|
89
|
-
mqtt_obj.get_packet do |packet|
|
|
90
|
-
puts '-' * 80
|
|
91
|
-
|
|
92
|
-
payload = packet.payload.to_s
|
|
93
|
-
|
|
94
|
-
# Convert raw packet to hex-escaped bytes
|
|
95
|
-
# puts "PSK: #{psk.inspect} | Length: #{psk.length}"
|
|
96
|
-
# puts "Dec PSK: #{dec_psk.inspect} | Length: #{dec_psk.length}"
|
|
97
|
-
packet_from_backwards = payload[3..6]
|
|
98
|
-
if packet_from_backwards
|
|
99
|
-
packet_from_str = packet_from_backwards.reverse
|
|
100
|
-
packet_from_hex = packet_from_str.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join
|
|
101
|
-
packet_from = packet_from_hex.to_i(16)
|
|
102
|
-
puts "\nFrom: #{packet_from_str.inspect} >> #{packet_from_hex} >> #{packet_from}"
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
packet_to_backwards = payload[8..11]
|
|
106
|
-
if packet_to_backwards
|
|
107
|
-
packet_to_str = packet_to_backwards.reverse
|
|
108
|
-
packet_to_hex = packet_to_str.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join
|
|
109
|
-
packet_to = packet_to_hex.to_i(16)
|
|
110
|
-
puts "To: #{packet_to_str.inspect} >> #{packet_to_hex} >> #{packet_to}"
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
mystery_byte = payload[12]
|
|
114
|
-
if mystery_byte
|
|
115
|
-
mystery_hex = mystery_byte.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join
|
|
116
|
-
mystery = mystery_hex.to_i(16)
|
|
117
|
-
puts "Mystery 1: #{mystery_byte.inspect} >> #{mystery_hex} >> #{mystery}"
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
msg_len = 0
|
|
121
|
-
msg_len_byte = payload[13]
|
|
122
|
-
if msg_len_byte
|
|
123
|
-
msg_len_hex = msg_len_byte.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join
|
|
124
|
-
msg_len = msg_len_hex.to_i(16)
|
|
125
|
-
end
|
|
126
|
-
puts "Message Length: #{msg_len_byte.inspect} >> #{msg_len}"
|
|
127
|
-
|
|
128
|
-
channel_byte = payload[14]
|
|
129
|
-
if channel_byte
|
|
130
|
-
channel_hex = channel_byte.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join
|
|
131
|
-
channel = channel_hex.to_i(16)
|
|
132
|
-
puts "Channel: #{channel_byte.inspect} >> #{channel_hex} >> #{channel}"
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
mystery_byte = payload[15]
|
|
136
|
-
if mystery_byte
|
|
137
|
-
mystery_hex = mystery_byte.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join
|
|
138
|
-
mystery = mystery_hex.to_i(16)
|
|
139
|
-
puts "Mystery 2: #{mystery_byte.inspect} >> #{mystery_hex} >> #{mystery}"
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
pid_id_backwards = payload.b[-34..-31]
|
|
143
|
-
if pid_id_backwards
|
|
144
|
-
pid_str = pid_id_backwards.reverse
|
|
145
|
-
pid_hex = pid_str.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join
|
|
146
|
-
packet_id = pid_hex.to_i(16)
|
|
147
|
-
puts "ID: #{pid_str.inspect} >> #{pid_hex} >> #{packet_id}"
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
topic = packet.topic
|
|
151
|
-
puts "\nTopic: #{topic}"
|
|
152
|
-
|
|
153
|
-
if msg_len.positive?
|
|
154
|
-
begin
|
|
155
|
-
puts "Payload: #{payload.inspect}"
|
|
156
|
-
puts "Payload Length: #{payload.length}"
|
|
157
|
-
|
|
158
|
-
nonce_packet_id = [packet_id].pack('V').ljust(8, "\x00")
|
|
159
|
-
nonce_from_node = [packet_from].pack('V').ljust(8, "\x00")
|
|
160
|
-
# puts "Nonce from Node: #{nonce_from_node.inspect} | Length: #{nonce_from_node.length}"
|
|
161
|
-
nonce = "#{nonce_packet_id}#{nonce_from_node}".b
|
|
162
|
-
puts "Nonce: #{nonce.inspect} | Length: #{nonce.length}"
|
|
163
|
-
|
|
164
|
-
# Decrypt the message
|
|
165
|
-
# Key must be 32 bytes
|
|
166
|
-
# IV mustr be 16 bytes
|
|
167
|
-
cipher.decrypt
|
|
168
|
-
cipher.key = dec_psk
|
|
169
|
-
cipher.iv = nonce
|
|
170
|
-
first_byte = 16
|
|
171
|
-
last_byte = first_byte + msg_len - 1
|
|
172
|
-
encrypted_payload = payload[first_byte..last_byte]
|
|
173
|
-
puts "\nEncrypted Payload:\n#{encrypted_payload.inspect}"
|
|
174
|
-
puts "Length: #{encrypted_payload.length}" if encrypted_payload
|
|
175
|
-
|
|
176
|
-
decrypted = cipher.update(encrypted_payload) + cipher.final
|
|
177
|
-
puts "\nDecrypted Payload:\n#{decrypted.inspect}"
|
|
178
|
-
puts "Length: #{decrypted.length}" if decrypted
|
|
179
|
-
rescue StandardError => e
|
|
180
|
-
puts "Error decrypting message: #{e}"
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
raw_packet = packet.to_s.b
|
|
184
|
-
puts "\nRaw Packet: #{raw_packet.inspect}"
|
|
185
|
-
puts "Length: #{packet.to_s.length}"
|
|
186
|
-
puts '-' * 80
|
|
187
|
-
puts "\n\n\n"
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
rescue Interrupt
|
|
191
|
-
puts "\nCTRL+C detected. Exiting..."
|
|
192
|
-
rescue StandardError => e
|
|
193
|
-
raise e
|
|
194
|
-
ensure
|
|
195
|
-
mqtt_obj.disconnect if mqtt_obj
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
# Supported Method Parameters::
|
|
199
|
-
# mqtt_obj = PWN::Plugins::Meshtastic.gps_search(
|
|
200
|
-
# lat: 'required - latitude float (e.g. 37.7749)',
|
|
201
|
-
# lon: 'required - longitude float (e.g. -122.4194)',
|
|
202
|
-
# )
|
|
203
|
-
public_class_method def self.gps_search(opts = {})
|
|
204
|
-
lat = opts[:lat]
|
|
205
|
-
lon = opts[:lon]
|
|
206
|
-
|
|
207
|
-
raise 'ERROR: Latitude and Longitude are required' unless lat && lon
|
|
208
|
-
|
|
209
|
-
gps_arr = [lat.to_f, lon.to_f]
|
|
210
|
-
|
|
211
|
-
Geocoder.search(gps_arr)
|
|
212
|
-
rescue StandardError => e
|
|
213
|
-
raise e
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
# Supported Method Parameters::
|
|
217
|
-
# mqtt_obj = PWN::Plugins::Meshtastic.disconnect(
|
|
218
|
-
# mqtt_obj: 'required - mqtt_obj returned from #connect method'
|
|
219
|
-
# )
|
|
220
|
-
public_class_method def self.disconnect(opts = {})
|
|
221
|
-
mqtt_obj = opts[:mqtt_obj]
|
|
222
|
-
|
|
223
|
-
mqtt_obj.disconnect if mqtt_obj
|
|
224
|
-
nil
|
|
225
|
-
rescue StandardError => e
|
|
226
|
-
raise e
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
# Author(s):: 0day Inc. <request.pentest@0dayinc.com>
|
|
230
|
-
|
|
231
|
-
public_class_method def self.authors
|
|
232
|
-
"AUTHOR(S):
|
|
233
|
-
0day Inc. <request.pentest@0dayinc.com>
|
|
234
|
-
"
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
# Display Usage for this Module
|
|
238
|
-
|
|
239
|
-
public_class_method def self.help
|
|
240
|
-
puts "USAGE:
|
|
241
|
-
mqtt_obj = #{self}.connect(
|
|
242
|
-
host: 'optional - mqtt host (default: mqtt.meshtastic.org)',
|
|
243
|
-
port: 'optional - mqtt port (defaults: 1883)',
|
|
244
|
-
username: 'optional - mqtt username (default: meshdev)',
|
|
245
|
-
password: 'optional - (default: large4cats)'
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
#{self}.subscribe(
|
|
249
|
-
mqtt_obj: 'required - mqtt_obj object returned from #connect method',
|
|
250
|
-
region: 'optional - region (default: US)',
|
|
251
|
-
channel: 'optional - channel name (default: LongFast)',
|
|
252
|
-
psk: 'optional - channel pre-shared key (default: AQ==)',
|
|
253
|
-
qos: 'optional - quality of service (default: 0)'
|
|
254
|
-
)
|
|
255
|
-
|
|
256
|
-
mqtt_obj = #{self}.disconnect(
|
|
257
|
-
mqtt_obj: 'required - mqtt_obj object returned from #connect method'
|
|
258
|
-
)
|
|
259
|
-
|
|
260
|
-
#{self}.authors
|
|
261
|
-
"
|
|
262
|
-
end
|
|
263
|
-
end
|
|
264
|
-
end
|
|
265
|
-
end
|