Module: PWN::Plugins::Serial
- Defined in:
- lib/pwn/plugins/serial.rb
Overview
This plugin is used for interacting with serial devices including, but not limited to, modems (including cellphone radios), legacy equipment, arduinos, & other misc ftdi devices
Class Method Summary collapse
-
.authors ⇒ Object
- Author(s)
-
0day Inc.
-
.connect(opts = {}) ⇒ Object
- Supported Method Parameters
-
serial_obj = PWN::Plugins::Serial.connect( block_dev: ‘optional - serial block device path (defaults to /dev/ttyUSB0)’, baud: ‘optional - (defaults to 9600)’, data_bits: ‘optional - (defaults to 8)’, stop_bits: ‘optional - (defaults to 1)’, parity: ‘optional - :even|:mark|:odd|:space|:none (defaults to :none)’ ).
-
.disconnect(opts = {}) ⇒ Object
- Supported Method Parameters
-
PWN::Plugins::Serial.disconnect( serial_obj: ‘required - serial_obj returned from #connect method’ ).
-
.dump_session_data ⇒ Object
- Supported Method Parameters
-
session_data = PWN::Plugins::Serial.dump_session_data.
-
.flush_session_data ⇒ Object
- Supported Method Parameters
-
session_data = PWN::Plugins::Serial.flush_session_data.
-
.get_line_state(opts = {}) ⇒ Object
- Supported Method Parameters
-
line_state = PWN::Plugins::Serial.get_line_state( serial_obj: ‘required serial_obj returned from #connect method’ ).
-
.get_modem_params(opts = {}) ⇒ Object
- Supported Method Parameters
-
modem_params = PWN::Plugins::Serial.get_modem_params( serial_obj: ‘required - serial_obj returned from #connect method’ ).
-
.help ⇒ Object
Display Usage for this Module.
-
.request(opts = {}) ⇒ Object
- Supported Method Parameters
-
PWN::Plugins::Serial.request( serial_obj: ‘required serial_obj returned from #connect method’, payload: ‘required - array of bytes OR string to write to serial device (e.g. [0x00, 0x41, 0x90, 0x00] OR “ATDT+15555555rn”’ ).
-
.response(opts = {}) ⇒ Object
- Supported Method Parameters
-
PWN::Plugins::Serial.response( serial_obj: ‘required - serial_obj returned from #connect method’ ).
Class Method Details
.authors ⇒ Object
- Author(s)
-
0day Inc. <[email protected]>
224 225 226 227 228 |
# File 'lib/pwn/plugins/serial.rb', line 224 public_class_method def self. "AUTHOR(S): 0day Inc. <[email protected]> " end |
.connect(opts = {}) ⇒ Object
- Supported Method Parameters
-
serial_obj = PWN::Plugins::Serial.connect(
block_dev: 'optional - serial block device path (defaults to /dev/ttyUSB0)', baud: 'optional - (defaults to 9600)', data_bits: 'optional - (defaults to 8)', stop_bits: 'optional - (defaults to 1)', parity: 'optional - :even|:mark|:odd|:space|:none (defaults to :none)'
)
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/pwn/plugins/serial.rb', line 22 public_class_method def self.connect(opts = {}) block_dev = opts[:block_dev] ||= '/dev/ttyUSB0' raise "Invalid block device: #{block_dev}" unless File.exist?(block_dev) baud = opts[:baud] ||= 9_600 data_bits = opts[:data_bits] ||= 8 stop_bits = opts[:stop_bits] ||= 1 parity = opts[:parity] ||= :none case parity.to_s.to_sym when :even parity = 'E' when :odd parity = 'O' when :none parity = 'N' end raise "Invalid parity: #{opts[:parity]}" if parity.nil? mode = "#{data_bits}#{parity}#{stop_bits}" puts mode serial_conn = UART.open( block_dev, baud, mode ) serial_obj = {} serial_obj[:serial_conn] = serial_conn serial_obj[:session_thread] = init_session_thread( serial_conn: serial_conn ) serial_obj rescue StandardError => e disconnect(serial_obj: serial_obj) unless serial_obj.nil? raise e end |
.disconnect(opts = {}) ⇒ Object
- Supported Method Parameters
-
PWN::Plugins::Serial.disconnect(
serial_obj: 'required - serial_obj returned from #connect method'
)
210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/pwn/plugins/serial.rb', line 210 public_class_method def self.disconnect(opts = {}) serial_obj = opts[:serial_obj] serial_conn = serial_obj[:serial_conn] session_thread = serial_obj[:session_thread] flush_session_data session_thread.terminate serial_conn.close serial_conn = nil rescue StandardError => e raise e end |
.dump_session_data ⇒ Object
- Supported Method Parameters
-
session_data = PWN::Plugins::Serial.dump_session_data
190 191 192 193 194 |
# File 'lib/pwn/plugins/serial.rb', line 190 public_class_method def self.dump_session_data @session_data rescue StandardError => e raise e end |
.flush_session_data ⇒ Object
- Supported Method Parameters
-
session_data = PWN::Plugins::Serial.flush_session_data
199 200 201 202 203 |
# File 'lib/pwn/plugins/serial.rb', line 199 public_class_method def self.flush_session_data @session_data.clear rescue StandardError => e raise e end |
.get_line_state(opts = {}) ⇒ Object
- Supported Method Parameters
-
line_state = PWN::Plugins::Serial.get_line_state(
serial_obj: 'required serial_obj returned from #connect method'
)
96 97 98 99 100 101 102 103 104 105 |
# File 'lib/pwn/plugins/serial.rb', line 96 public_class_method def self.get_line_state(opts = {}) serial_obj = opts[:serial_obj] serial_conn = serial_obj[:serial_conn] # Should return something like: # {"rts"=>1, "dtr"=>1, "cts"=>1, "dsr"=>1, "dcd"=>0, "ri"=>0} serial_conn.lstat rescue StandardError => e disconnect(serial_obj: serial_obj) unless serial_obj.nil? raise e end |
.get_modem_params(opts = {}) ⇒ Object
- Supported Method Parameters
-
modem_params = PWN::Plugins::Serial.get_modem_params(
serial_obj: 'required - serial_obj returned from #connect method'
)
112 113 114 115 116 117 118 119 120 121 |
# File 'lib/pwn/plugins/serial.rb', line 112 public_class_method def self.get_modem_params(opts = {}) serial_obj = opts[:serial_obj] serial_conn = serial_obj[:serial_conn] # Should return something like: # {"baud"=>9600, "data_bits"=>8, "stop_bits"=>1, "parity"=>0} serial_conn.get_modem_params rescue StandardError => e disconnect(serial_obj: serial_obj) unless serial_obj.nil? raise e end |
.help ⇒ Object
Display Usage for this Module
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/pwn/plugins/serial.rb', line 232 public_class_method def self.help puts "USAGE: serial_obj = #{self}.connect( block_dev: 'optional serial block device path (defaults to /dev/ttyUSB0)', baud: 'optional (defaults to 9600)', data_bits: 'optional (defaults to 8)', stop_bits: 'optional (defaults to 1)', parity: 'optional - :even|:mark|:odd|:space|:none (defaults to :none)' ) line_state = #{self}.get_line_state( serial_obj: 'required serial_obj returned from #connect method' ) modem_params = #{self}.get_modem_params( serial_obj: 'required serial_obj returned from #connect method' ) #{self}.request( serial_obj: 'required serial_obj returned from #connect method', payload: 'required - array of bytes OR string to write to serial device (e.g. [0x00, 0x41, 0x90, 0x00] OR \"ATDT+15555555\r\n\"' ) #{self}.response( serial_obj: 'required serial_obj returned from #connect method' ) session_data_arr = #{self}.dump_session_data #{self}.flush_session_data #{self}.disconnect( serial_obj: 'required serial_obj returned from #connect method' ) #{self}.authors " end |
.request(opts = {}) ⇒ Object
- Supported Method Parameters
-
PWN::Plugins::Serial.request(
serial_obj: 'required serial_obj returned from #connect method', payload: 'required - array of bytes OR string to write to serial device (e.g. [0x00, 0x41, 0x90, 0x00] OR "ATDT+15555555\r\n"'
)
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/pwn/plugins/serial.rb', line 129 public_class_method def self.request(opts = {}) serial_obj = opts[:serial_obj] payload = opts[:payload] serial_conn = serial_obj[:serial_conn] byte_arr = nil byte_arr = payload if payload.instance_of?(Array) byte_arr = payload.chars if payload.instance_of?(String) raise "ERROR: Invalid payload type: #{payload.class}" if byte_arr.nil? byte_arr.each do |byte| serial_conn.putc(byte) end serial_conn.flush rescue StandardError => e disconnect(serial_obj: serial_obj) unless serial_obj.nil? raise e end |
.response(opts = {}) ⇒ Object
- Supported Method Parameters
-
PWN::Plugins::Serial.response(
serial_obj: 'required - serial_obj returned from #connect method'
)
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/pwn/plugins/serial.rb', line 154 public_class_method def self.response(opts = {}) serial_obj = opts[:serial_obj] raw_byte_arr = dump_session_data hex_esc_raw_resp = '' raw_byte_arr.each do |byte| # this_byte = "\s#{byte.unpack1('H*')}" this_byte = byte.unpack1('H*') # Needed when #unpack1 returns 2 bytes instead of one # e.g."ް" translates to deb0 (that's not a double quote ") # instead of de b0 # this condition is ghetto-hacker-ish. if this_byte.length == 4 byte_one = this_byte[1..2] byte_two = this_byte[-2..-1] hex_esc_raw_resp = "#{hex_esc_raw_resp}\s#{byte_one}" hex_esc_raw_resp = "#{hex_esc_raw_resp}\s#{byte_two}" else hex_esc_raw_resp = "#{hex_esc_raw_resp}\s#{this_byte}" end end # Return command response array in space-delimited hex cmd_response_arr = hex_esc_raw_resp.upcase.strip.split(/(?=FF)/) cmd_response_arr.map(&:strip) rescue StandardError => e # Flush Responses for Next Request flush_session_data raise e end |