Merge remote-tracking branch 'origin/main' into jorgectf/python/insecure-cookie

This commit is contained in:
jorgectf
2021-11-05 20:14:06 +01:00
27 changed files with 284 additions and 353 deletions

View File

@@ -1,6 +1,17 @@
from flask import Flask, request
from flask import Flask, request, send_from_directory, send_file
app = Flask(__name__)
@app.route("/save-uploaded-file") # $routeSetup="/save-uploaded-file"
def test_taint(): # $requestHandler
request.files['key'].save("path") # $ getAPathArgument="path"
@app.route("/path-injection") # $routeSetup="/path-injection"
def test_path(): # $requestHandler
send_from_directory("filepath","file") # $ getAPathArgument="filepath" getAPathArgument="file"
send_file("file") # $ getAPathArgument="file"
send_from_directory(directory="filepath","file") # $ getAPathArgument="filepath" getAPathArgument="file"
send_from_directory(filename="filepath","file") # $ getAPathArgument="filepath" getAPathArgument="file"
send_file(filename_or_fp="file") # $ getAPathArgument="file"

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,33 @@
import ruamel.yaml
# Unsafe:
ruamel.yaml.load(payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
ruamel.yaml.load(stream=payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
ruamel.yaml.load(payload, ruamel.yaml.Loader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
# Safe:
ruamel.yaml.load(payload, ruamel.yaml.SafeLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
ruamel.yaml.load(payload, Loader=ruamel.yaml.SafeLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
ruamel.yaml.load(payload, ruamel.yaml.BaseLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
ruamel.yaml.safe_load(payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.safe_load(..) decodeFormat=YAML
################################################################################
# load_all variants
################################################################################
# Unsafe:
ruamel.yaml.load_all(payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.load_all(..) decodeFormat=YAML decodeMayExecuteInput
# Safe:
ruamel.yaml.safe_load_all(payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.safe_load_all(..) decodeFormat=YAML
################################################################################
# C-based loaders with `libyaml`
################################################################################
# Unsafe:
ruamel.yaml.load(payload, ruamel.yaml.CLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
# Safe:
ruamel.yaml.load(payload, ruamel.yaml.CSafeLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
ruamel.yaml.load(payload, ruamel.yaml.CBaseLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML

View File

@@ -0,0 +1,63 @@
#!/usr/bin/env python3
# this file doesn't have a .py extension so the extractor doesn't pick it up, so it
# doesn't have to be annotated
# This file is just a Proof of Concept for how code execution can be triggered.
import os
import ruamel.yaml
class Exploit(object):
def __reduce__(self):
return (os.system, ('ls',))
data = Exploit()
serialized_data = ruamel.yaml.dump(data)
# All these will execute `ls`
print("!!! ruamel.yaml.load")
ruamel.yaml.load(serialized_data)
print("!!! ruamel.yaml.load kwarg")
ruamel.yaml.load(stream=serialized_data)
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.Loader")
ruamel.yaml.load(serialized_data, ruamel.yaml.Loader)
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.UnsafeLoader")
ruamel.yaml.load(serialized_data, ruamel.yaml.UnsafeLoader)
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.CLoader")
ruamel.yaml.load(serialized_data, ruamel.yaml.CLoader)
# you need to iterate through the result for it to execute... but it still works
print("!!! ruamel.yaml.load_all")
for _ in ruamel.yaml.load_all(serialized_data):
pass
# check that the safe version is actually safe
print("\n" + "-"*80)
print("safe versions")
print("-" * 80)
print("!!! ruamel.yaml.safe_load")
try:
ruamel.yaml.safe_load(serialized_data)
raise Exception("should not happen")
except ruamel.yaml.constructor.ConstructorError:
pass
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.SafeLoader")
try:
ruamel.yaml.load(serialized_data, ruamel.yaml.SafeLoader)
raise Exception("should not happen")
except ruamel.yaml.constructor.ConstructorError:
pass
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.CSafeLoader")
try:
ruamel.yaml.load(serialized_data, ruamel.yaml.CSafeLoader)
raise Exception("should not happen")
except ruamel.yaml.constructor.ConstructorError:
pass

View File

@@ -2,6 +2,7 @@ import yaml
# Unsafe:
yaml.load(payload) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
yaml.load(stream=payload) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
yaml.load(payload, yaml.Loader) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
yaml.unsafe_load(payload) # $ decodeInput=payload decodeOutput=yaml.unsafe_load(..) decodeFormat=YAML decodeMayExecuteInput
yaml.full_load(payload) # $ decodeInput=payload decodeOutput=yaml.full_load(..) decodeFormat=YAML decodeMayExecuteInput

View File

@@ -0,0 +1,58 @@
#!/usr/bin/env python3
# this file doesn't have a .py extension so the extractor doesn't pick it up, so it
# doesn't have to be annotated
# This file is just a Proof of Concept for how code execution can be triggered.
import os
import yaml
class Exploit(object):
def __reduce__(self):
return (os.system, ('ls',))
data = Exploit()
serialized_data = yaml.dump(data)
# All these will execute `ls`
print("!!! yaml.unsafe_load")
yaml.unsafe_load(serialized_data)
print("!!! yaml.unsafe_load kwarg")
yaml.unsafe_load(stream=serialized_data)
print("!!! yaml.load with Loader=yaml.UnsafeLoader")
yaml.load(serialized_data, yaml.UnsafeLoader)
# you need to iterate through the result for it to execute... but it still works
print("!!! yaml.unsafe_load_all")
for _ in yaml.unsafe_load_all(serialized_data):
pass
# check that the safe version is actually safe
print("\n" + "-"*80)
print("safe versions")
print("-" * 80)
print("!!! yaml.load")
try:
yaml.load(serialized_data)
raise Exception("should not happen")
except yaml.constructor.ConstructorError:
pass
print("!!! yaml.safe_load")
try:
yaml.safe_load(serialized_data)
raise Exception("should not happen")
except yaml.constructor.ConstructorError:
pass
print("!!! yaml.load with Loader=yaml.SafeLoader")
try:
yaml.load(serialized_data, yaml.SafeLoader)
raise Exception("should not happen")
except yaml.constructor.ConstructorError:
pass